# Quasar

Cree sin esfuerzo interfaces de usuario Vue 3 de alto rendimiento y calidad en un tiempo récord.

# Características

  • Vue JS 3
  • Soporte para navegadores de escritorio y móviles (¡incluido iOS Safari!) Listo para usar
  • SPA, SSR, PWA, aplicación móvil, aplicación de escritorio y extensión del navegador
  • CLI propia
  • Personalizable (CSS) y ampliable (JS)
  • Si solo desea crear un sitio web, Quasar solo creará el código necesario para un sitio web, sin nada más. Lo mismo ocurre con los otros modos de construcción.

Puedes construir:

  • SPA (aplicación de una sola página)
  • SSR (aplicación renderizada del lado del servidor) (+ adquisición de cliente PWA opcional)
  • PWA (aplicación web progresiva)
  • BEX (extensión del navegador)
  • Aplicaciones móviles (Android, iOS,…) a través de Cordova o Capacitor
  • Aplicaciones de escritorio multiplataforma (usando Electron)

# Quasar CLI

$ yarn global add @quasar/cli
# or
$ npm install -g @quasar/cli

Primer proyecto

quasar create <folder_name> --branch next

WARNING

Actualmente npm tiene un error de compilación, por lo tanto se recomienda utilizar la configuración de yarn al momento de crear un nuevo proyecto.

Error compilación UI

quasar dev

# Layout

# Router

const routes = [
  {
    path: "/",
    component: () => import("layouts/MainLayout.vue"),
    children: [
      { path: "", component: () => import("pages/Index.vue") },
      { path: "/about", component: () => import("pages/About.vue") },
    ],
  },
  {
    path: "/:catchAll(.*)*",
    component: () => import("pages/Error404.vue"),
  },
];

export default routes;

# q-page

De forma predeterminada, su componente QPage tendrá una propiedad min-height CSS configurada para garantizar que el contenido llene la pantalla en todo momento, incluso cuando el contenido tenga solo unas pocas líneas.

<template>
  <q-page padding>
    <h1>About</h1>
  </q-page>
</template>

# Style

<template>
  <q-page padding>
    <h1 class="text-primary">About</h1>
    <h2 class="bg-secondary text-white">Lorem, ipsum dolor.</h2>
    <h3 class="text-deep-orange-6">Lorem, ipsum dolor.</h3>
  </q-page>
</template>
<div class="q-mt-xl bg-warning q-pa-xl">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis deleniti
    iusto eos sed repellat placeat modi eligendi eveniet quasi fuga aspernatur
    est atque facere, ducimus reiciendis debitis dolores libero minima!
  </p>
</div>
<p class="shadow-1">
  Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae ut commodi
  repellendus provident? Deleniti vel dolor neque soluta ratione quo. Eaque,
  aspernatur incidunt nihil officia cum quo ducimus et provident!
</p>

# Flex Grid

<template>
  <q-page padding>
    <div class="row">
      <p class="col-12">
        Lorem ipsum dolor sit amet consectetur, adipisicing elit. Reprehenderit
        hic tempora voluptas corrupti cumque dolorem maiores cupiditate non
        explicabo, saepe pariatur quae dicta adipisci a, officiis odit placeat
        vitae recusandae.
      </p>
    </div>
    <div class="row">
      <p class="col-12 col-sm-6">
        Lorem ipsum dolor, sit amet consectetur adipisicing elit. Tempore,
        ducimus sunt totam beatae inventore excepturi fugiat obcaecati ratione,
        deserunt, commodi nesciunt minus tenetur iure quasi ut! Iste hic rem
        non.
      </p>
      <p class="col-12 col-sm-6">
        Lorem ipsum dolor, sit amet consectetur adipisicing elit. Tempore,
        ducimus sunt totam beatae inventore excepturi fugiat obcaecati ratione,
        deserunt, commodi nesciunt minus tenetur iure quasi ut! Iste hic rem
        non.
      </p>
    </div>
    <div class="row">
      <p class="col">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati
        cumque quas expedita minus ullam tempora aut reiciendis tenetur aperiam,
        vero eligendi beatae. Non, quia! Ipsam provident velit deleniti amet
        laborum.
      </p>
      <p class="col">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati
        cumque quas expedita minus ullam tempora aut reiciendis tenetur aperiam,
        vero eligendi beatae. Non, quia! Ipsam provident velit deleniti amet
        laborum.
      </p>
      <p class="col">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati
        cumque quas expedita minus ullam tempora aut reiciendis tenetur aperiam,
        vero eligendi beatae. Non, quia! Ipsam provident velit deleniti amet
        laborum.
      </p>
    </div>
    <div class="row">
      <p class="col bg-warning">Lorem, ipsum dolor.</p>
      <p>Lorem, ipsum dolor.</p>
    </div>

    <div class="row items-center bg-dark text-white" style="height: 300px">
      <div class="col bg-positive">One of three cols</div>
      <div class="col bg-positive">One of three cols</div>
      <div class="col bg-positive">One of three cols</div>
    </div>
  </q-page>
</template>

# Gutter

<div class="row q-col-gutter-md">
  <p class="col-12 col-sm-4">
    Lorem ipsum dolor, sit amet consectetur adipisicing elit. Tempore, ducimus
    sunt totam beatae inventore excepturi fugiat obcaecati ratione, deserunt,
    commodi nesciunt minus tenetur iure quasi ut! Iste hic rem non.
  </p>
  <p class="col-12 col-sm-4">
    Lorem ipsum dolor, sit amet consectetur adipisicing elit. Tempore, ducimus
    sunt totam beatae inventore excepturi fugiat obcaecati ratione, deserunt,
    commodi nesciunt minus tenetur iure quasi ut! Iste hic rem non.
  </p>
  <p class="col-12 col-sm-4">
    Lorem ipsum dolor, sit amet consectetur adipisicing elit. Tempore, ducimus
    sunt totam beatae inventore excepturi fugiat obcaecati ratione, deserunt,
    commodi nesciunt minus tenetur iure quasi ut! Iste hic rem non.
  </p>
</div>
<div class="q-gutter-x-md">
  <q-btn color="primary">Uno</q-btn>
  <q-btn color="primary">Dos</q-btn>
  <q-btn color="primary">Tres</q-btn>
</div>

# Header Picture

<template>
  <q-layout view="lHh Lpr lff">
    <q-header elevated class="bg-cyan-9">
      <q-toolbar>
        <q-toolbar-title>Header</q-toolbar-title>
        <q-btn flat @click="drawer = !drawer" round dense icon="menu" />
      </q-toolbar>
    </q-header>

    <q-drawer v-model="drawer" show-if-above :width="200" :breakpoint="400">
      <q-scroll-area
        style="height: calc(100% - 150px); margin-top: 150px; border-right: 1px solid #ddd"
      >
        <q-list padding>
          <q-item clickable v-ripple to="/" exact active-class="my-menu-link">
            <q-item-section avatar>
              <q-icon name="inbox" />
            </q-item-section>

            <q-item-section> Inicio </q-item-section>
          </q-item>

          <q-item clickable v-ripple to="/about" active-class="my-menu-link">
            <q-item-section avatar>
              <q-icon name="star" />
            </q-item-section>

            <q-item-section> About </q-item-section>
          </q-item>
        </q-list>
      </q-scroll-area>

      <q-img
        class="absolute-top"
        src="https://cdn.quasar.dev/img/material.png"
        style="height: 150px"
      >
        <div class="absolute-bottom bg-transparent">
          <q-avatar size="56px" class="q-mb-sm">
            <img src="https://cdn.quasar.dev/img/boy-avatar.png" />
          </q-avatar>
          <div class="text-weight-bold">Razvan Stoenescu</div>
          <div>@rstoenescu</div>
        </div>
      </q-img>
    </q-drawer>

    <q-page-container>
      <router-view></router-view>
    </q-page-container>
  </q-layout>
</template>

<script>
import { ref } from "vue";
export default {
  setup() {
    const drawer = ref(false);
    return { drawer };
  },
};
</script>

<style lang="scss">
.my-menu-link {
  color: white;
  background: $cyan-9;
}
</style>

# Form + Validate + Table

<template>
  <q-page padding>
    <h1 class="text-h2">Lista de compras</h1>
    <q-form
      class="row q-col-gutter-md"
      @reset="onReset"
      @submit.prevent="onSubmit"
      ref="myForm"
    >
      <q-input
        label="Producto"
        class="col-12 col-sm-6"
        v-model.trim="producto"
        lazy-rules
        :rules="[(val) => (val && val.length > 0) || 'Campo vacío']"
      />
      <q-select
        label="Prioridad"
        class="col-12 col-sm-6"
        :options="opciones"
        v-model="seleccion"
        lazy-rules
        :rules="[(val) => (val && val.length > 0) || 'Campo vacío']"
      />
      <q-toggle
        label="Aceptar los las condiciones super bknes"
        v-model="condiciones"
        class="col-12"
      />
      <div class="col-12">
        <q-btn label="submit" type="submit" color="primary" />
        <q-btn
          label="reset"
          type="reset"
          color="primary"
          flat
          class="q-ml-sm"
        />
      </div>
    </q-form>
    <!-- <pre>{{productos}}</pre> -->

    <lista-productos :productos="productos" class="q-mt-xl" />
  </q-page>
</template>

<script>
import { useQuasar } from "quasar";
import ListaProductos from "src/components/ListaProductos.vue";
import { ref } from "vue";
export default {
  components: { ListaProductos },
  setup() {
    const $q = useQuasar();
    const myForm = ref(null);

    const productos = ref([]);

    const producto = ref(null);
    const seleccion = ref(null);
    const opciones = ["Máxima", "Moderada", "Mínima"];
    const condiciones = ref(false);

    const onSubmit = () => {
      if (condiciones.value === false) {
        $q.notify({
          color: "red-5",
          textColor: "white",
          icon: "warning",
          message: "You need to accept the license and terms first",
        });
      } else {
        $q.notify({
          color: "green-4",
          textColor: "white",
          icon: "cloud_done",
          message: "Submitted",
        });

        myForm.value.resetValidation();
        productos.value = [
          ...productos.value,
          {
            producto: producto.value,
            prioridad: seleccion.value,
          },
        ];
        onReset();
      }
    };

    const onReset = () => {
      producto.value = null;
      seleccion.value = null;
      condiciones.value = false;
    };

    return {
      producto,
      seleccion,
      opciones,
      condiciones,
      onSubmit,
      onReset,
      myForm,
      productos,
    };
  },
};
</script>

components/ListaProductos.vue

<template>
  <q-table
    title="Productos"
    :columns="columns"
    :rows="productos"
    no-data-label="Sin productos para mostrar"
  />
  <!-- <pre>{{productos}}</pre> -->
</template>

<script>
const columns = [
  {
    name: "producto",
    align: "left",
    label: "Producto",
    field: "producto",
    sortable: true,
  },
  { name: "prioridad", label: "Prioridad", field: "prioridad", sortable: true },
];

const row = [
  {
    producto: "fsad",
    prioridad: "Máxima",
  },
];
export default {
  props: {
    productos: Array,
  },
  setup() {
    return {
      columns,
      row,
    };
  },
};
</script>

# Icons

quasar.conf.js

extras: [
  // 'ionicons-v4',
  // 'mdi-v5',
  // 'fontawesome-v5',
  // 'eva-icons',
  'themify',
  // 'line-awesome',
  // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!

  'roboto-font', // optional, you are not bound to it
  'material-icons', // optional, you are not bound to it
],
<template>
  <q-page padding>
    <div class="text-center">
      <q-icon name="trending_up" class="text-primary" size="200px" />
      <q-icon name="ti-joomla" class="text-accent" size="200px" />
    </div>
  </q-page>
</template>
<q-btn color="secondary" icon-right="ti-twitter" label="On Right" />

# SEO

TIP

Aproveche al máximo esta función usándola con Quasar CLI , especialmente para las compilaciones SSR (Server-Side Rendering) .

También tiene sentido usarlo para SPA (aplicaciones de una sola página). Aunque la metainformación en este caso se agregará en tiempo de ejecución y no la proporcionará directamente el servidor web (como en las compilaciones SSR).

quasar.conf.js

plugins: ["Meta"];

vistas.vue

import { useMeta } from "quasar";

const metaData = {
  title: "Inicio web Quasar",
  meta: {
    description: {
      name: "description",
      content: "Descripción de página de inicio",
    },
  },
};

export default {
  setup() {
    useMeta(metaData);
  },
};

# History

quasar.conf.js

build: {
  vueRouterMode: "history";
}

# SPA

quasar build

# Redirects (history)

Crear archivo _redirects en carpeta public:

/* /index.html  200

Subir a netlify! 🥳