Categories
Quasar

Developing Vue Apps with the Quasar Library — Editor Tokens and Expansion Items

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Add Our Own Editor Features

We can add our own features to the Quasar WYSIWYG editor.

To add our own dropdown that lets us add preset text, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-editor
          v-model="editor"
          ref="editor"
          toolbar-text-color="white"
          toolbar-toggle-color="yellow-8"
          toolbar-bg="primary"
          :toolbar="[
        ['token'],
        ['bold', 'italic', 'underline'],
        [{
          label: $q.lang.editor.formatting,
          icon: $q.iconSet.editor.formatting,
          list: 'no-icons',
          options: ['p', 'h3', 'h4', 'h5', 'h6', 'code']
        }]
      ]"
        >
          <template v-slot:token>
            <q-btn-dropdown
              dense
              no-caps
              ref="token"
              no-wrap
              unelevated
              color="white"
              text-color="primary"
              label="Token"
              size="sm"
            >
              <q-list dense>
                <q-item tag="label" clickable @click="add('email')">
                  <q-item-section side>
                    <q-icon name="mail" />
                  </q-item-section>
                  <q-item-section>Email</q-item-section>
                </q-item>
                <q-item tag="label" clickable @click="add('title')">
                  <q-item-section side>
                    <q-icon name="title" />
                  </q-item-section>
                  <q-item-section>Title</q-item-section>
                </q-item>
              </q-list>
            </q-btn-dropdown>
          </template>
        </q-editor>
        <q-card flat bordered>
          <q-card-section>
            <pre style="white-space: pre-line;">{{ editor }}</pre>
          </q-card-section>
        </q-card>
        <q-card flat bordered>
          <q-card-section v-html="editor"></q-card-section>
        </q-card>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          editor: ""
        },
        methods: {
          add(name) {
            const edit = this.$refs.editor;
            this.$refs.token.hide();
            edit.caret.restore();
            edit.runCmd(
              "insertHTML",
              `&nbsp;<div class="editor_token row inline items-center" contenteditable="false">&nbsp;<span>${name}</span>&nbsp;<i class="q-icon material-icons cursor-pointer" onclick="this.parentNode.parentNode.removeChild(this.parentNode)">close</i></div>&nbsp;`
            );
            edit.focus();
          }
        }
      });
    </script>
  </body>
</html>

We populate the token slot with a dropdown.

Then dropdown options run the add method.

The method calls runCmd to add our own HTML into the editor box.

It’ll also be added to the editor reactive property that we bound to the editor.

The insertHTML command inserts HTML into our editor.

Expansion Item

The q-expansion-item component lets us display more items when we click on it.

To use it, we write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-expansion-item
          v-model="expanded"
          icon="perm_identity"
          label="Settings"
          caption="James"
        >
          <q-card>
            <q-card-section>
              Lorem ipsum dolor sit amet
            </q-card-section>
          </q-card>
        </q-expansion-item>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          expanded: false
        }
      });
    </script>
  </body>
</html>

We add the q-expansion-item component with the v-model directive to bind to its open state.

icon has the name of the icon displayed on the left,.

label has the label displayed on the top.

caption is displayed below the label and it’s smaller than it.

When we click on it, the text in the q-card will be toggled on and off.

Conclusion

We can add extra editor features to the Quasar WYSIWYG editor.

Also, we can add a component to toggle more content into our Vue app with the q-expansion-item component.

Categories
Quasar

Developing Vue Apps with the Quasar Library — WYSIWYG Editor Options

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

WYSIWYG Editor Features

The WYSIWYG editor that comes with Quasar comes with many features.

We can add them all by writing:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-editor
          v-model="editor"
          :dense="$q.screen.lt.md"
          :toolbar="[
            [
              {
                label: $q.lang.editor.align,
                icon: $q.iconSet.editor.align,
                fixedLabel: true,
                list: 'only-icons',
                options: ['left', 'center', 'right', 'justify']
              },
              {
                label: $q.lang.editor.align,
                icon: $q.iconSet.editor.align,
                fixedLabel: true,
                options: ['left', 'center', 'right', 'justify']
              }
            ],
            ['bold', 'italic', 'strike', 'underline', 'subscript', 'superscript'],
            ['token', 'hr', 'link', 'custom_btn'],
            ['print', 'fullscreen'],
            [
              {
                label: $q.lang.editor.formatting,
                icon: $q.iconSet.editor.formatting,
                list: 'no-icons',
                options: [
                  'p',
                  'h1',
                  'h2',
                  'h3',
                  'h4',
                  'h5',
                  'h6',
                  'code'
                ]
              },
              {
                label: $q.lang.editor.fontSize,
                icon: $q.iconSet.editor.fontSize,
                fixedLabel: true,
                fixedIcon: true,
                list: 'no-icons',
                options: [
                  'size-1',
                  'size-2',
                  'size-3',
                  'size-4',
                  'size-5',
                  'size-6',
                  'size-7'
                ]
              },
              {
                label: $q.lang.editor.defaultFont,
                icon: $q.iconSet.editor.font,
                fixedIcon: true,
                list: 'no-icons',
                options: [
                  'default_font',
                  'arial',
                  'arial_black',
                  'comic_sans',
                  'courier_new',
                  'impact',
                  'lucida_grande',
                  'times_new_roman',
                  'verdana'
                ]
              },
              'removeFormat'
            ],
            ['quote', 'unordered', 'ordered', 'outdent', 'indent'],

            ['undo', 'redo'],
            ['viewsource']
          ]"
          :fonts="{
            arial: 'Arial',
            arial_black: 'Arial Black',
            comic_sans: 'Comic Sans MS',
            courier_new: 'Courier New',
            impact: 'Impact',
            lucida_grande: 'Lucida Grande',
            times_new_roman: 'Times New Roman',
            verdana: 'Verdana'
          }"
        ></q-editor>
        <q-card flat bordered>
          <q-card-section>
            <pre style="white-space: pre-line;">{{ editor }}</pre>
          </q-card-section>
        </q-card>
        <q-card flat bordered>
          <q-card-section v-html="editor"></q-card-section>
        </q-card>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          editor: ""
        },
        methods: {
          saveWork() {
            console.log("saved");
          }
        }
      });
    </script>
  </body>
</html>

We put all the features in the toolbar prop to add them.

The styles of the editor can be changed.

For instance, we can change the toolbar and editor colors by writing:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-editor
          v-model="editor"
          flat
          content-class="bg-amber-3"
          toolbar-text-color="white"
          toolbar-toggle-color="yellow-2"
          toolbar-bg="primary"
          :toolbar="[
            ['bold', 'italic', 'underline'],
            [{
              label: $q.lang.editor.formatting,
              icon: $q.iconSet.editor.formatting,
              list: 'no-icons',
              options: ['p', 'h3', 'h4', 'h5', 'h6', 'code']
            }]
          ]"
        ></q-editor>
        <q-card flat bordered>
          <q-card-section>
            <pre style="white-space: pre-line;">{{ editor }}</pre>
          </q-card-section>
        </q-card>
        <q-card flat bordered>
          <q-card-section v-html="editor"></q-card-section>
        </q-card>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          editor: ""
        },
        methods: {
          saveWork() {
            console.log("saved");
          }
        }
      });
    </script>
  </body>
</html>

content-class changes the editor color.

toolbar-text-color changes the toolbar’s text color.

toolbar-toggle-color changes the color when we toggle any buttons.

toolbar-bg is the background color of the toolbar.

Conclusion

We can add many features to Quasar’s editor component and style it our way.

Categories
Quasar

Developing Vue Apps with the Quasar Library — WYSIWYG Editor

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

WYSIWYG Editor

Quasar comes with a WYSIWYG editor component.

To use it, we write the following:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-editor v-model="editor" min-height="5rem"></q-editor>
        <q-card flat bordered>
          <q-card-section>
            <pre style="white-space: pre-line;">{{ editor }}</pre>
          </q-card-section>
        </q-card>
        <q-card flat bordered>
          <q-card-section v-html="editor"></q-card-section>
        </q-card>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          editor: ""
        }
      });
    </script>
  </body>
</html>

We have the editor reactive property which is bound to the q-editor ‘s input value with v-model .

Then when we type something into the editor box and change the styles, they’ll be reflected below the editor.

editor is an HTML string with the styles, so we can use the v-html directive to display the styled content.

We can change how the buttons are displayed.

For instance, we can change the label of the bold button by writing:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-editor
          v-model="editor"
          min-height="5rem"
          :definitions="{
            bold: {label: 'Bold', icon: null, tip: 'My bold tooltip'}
          }"
        ></q-editor>
        <q-card flat bordered>
          <q-card-section>
            <pre style="white-space: pre-line;">{{ editor }}</pre>
          </q-card-section>
        </q-card>
        <q-card flat bordered>
          <q-card-section v-html="editor"></q-card-section>
        </q-card>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          editor: ""
        }
      });
    </script>
  </body>
</html>

We add the definitions prop to change the bold button with the object.

label is displayed in the button.

title is displayed when we hover over the button.

Also, we can add our own button that runs a method when we click it by writing:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-editor
          v-model="editor"
          min-height="5rem"
          :definitions="{
            save: {
              tip: 'Save your work',
              icon: 'save',
              label: 'Save',
              handler: saveWork
            },
          }"
          :toolbar="[
            ['bold', 'italic', 'strike', 'underline'],
            ['upload', 'save']
          ]"
        ></q-editor>
        <q-card flat bordered>
          <q-card-section>
            <pre style="white-space: pre-line;">{{ editor }}</pre>
          </q-card-section>
        </q-card>
        <q-card flat bordered>
          <q-card-section v-html="editor"></q-card-section>
        </q-card>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          editor: ""
        },
        methods: {
          saveWork() {
            console.log("saved");
          }
        }
      });
    </script>
  </body>
</html>

We add the save button in the defintitions object.

handler is set to the saveWork method so that it runs when we click it.

Then to add it to the toolbar, we put it in the toolbar prop.

Conclusion

Quasar comes with a WYSIWYG editor that we can add to our Vue app easily.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Dialog Box

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Dialogs

We can add dialog boxes into our Vue app with the Quasar library.

For instance, we can add a simple one by writing:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-btn label="Show Alert" color="primary" @click="alert = true" />
        <q-dialog v-model="alert">
          <q-card>
            <q-card-section>
              <div class="text-h6">Alert</div>
            </q-card-section>
            <q-card-section class="q-pt-none">
              Lorem ipsum
            </q-card-section>
            <q-card-actions align="right">
              <q-btn flat label="OK" color="primary" v-close-popup />
            </q-card-actions>
          </q-card>
        </q-dialog>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          alert: false
        }
      });
    </script>
  </body>
</html>

We add the q-btn component to add a button to open the dialog box.

The q-dialog component is controlled by the alert state, which is bound with v-model .

When alert is true , the dialog is displayed.

Inside the dialog, we have q-card to hold the content.

q-card-section divides the card into sections.

The v-close-popup prop makes the dialog close when we click the button.

We can add a close button to close the dialog when it’s clicked:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-btn label="Show Alert" color="primary" @click="alert = true" />
        <q-dialog v-model="alert">
          <q-card>
            <q-card-section class="row items-center q-pb-none">
              <div class="text-h6">Close icon</div>
              <q-space></q-space>
              <q-btn icon="close" flat round dense v-close-popup></q-btn>
            </q-card-section>

            <q-card-section>
              Lorem ipsum
            </q-card-section>
          </q-card>
        </q-dialog>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          alert: false
        }
      });
    </script>
  </body>
</html>

We just set the icon prop of q-btn to close to add a close icon.

q-space separates the title from the close button by pushing them to the left and right side respectively.

Also, we can position the dialog with the position prop:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-btn label="Show Alert" color="primary" @click="alert = true" />
        <q-dialog v-model="alert" position="right">
          <q-card>
            <q-card-section class="row items-center q-pb-none">
              <div class="text-h6">Close icon</div>
              <q-space></q-space>
              <q-btn icon="close" flat round dense v-close-popup></q-btn>
            </q-card-section>

            <q-card-section>
              Lorem ipsum
            </q-card-section>
          </q-card>
        </q-dialog>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          alert: false
        }
      });
    </script>
  </body>
</html>

Conclusion

We can add a simple dialog box into a Vue app with Quasar’s q-dialog component.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Color Picker

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Color Picker

Quasar comes with a color picker input component.

To use it, we write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-color v-model="hex"> </q-color>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          hex: ""
        }
      });
    </script>
  </body>
</html>

We add the q-color component to add a color picker.

We can also use it with the q-input component.

For instance, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-input filled v-model="color">
          <template v-slot:append>
            <q-icon name="colorize" class="cursor-pointer">
              <q-popup-proxy transition-show="scale" transition-hide="scale">
                <q-color v-model="color" />
              </q-popup-proxy>
            </q-icon>
          </template>
        </q-input>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          color: ""
        }
      });
    </script>
  </body>
</html>

to add the append slot.

We put the color picker in the q-popup-proxy , which is inside the q-icon so that when we click on the icon, we can see the color picker displayed.

We use v-model to bind both to the color reactive property.

So when we pick a color from the color picker, we see the same value displayed in the input.

Also, we can add a validation rule to the q-input to validate the color picker value:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-input filled v-model="color" :rules="[required]" hint="Pick a color">
          <template v-slot:append>
            <q-icon name="colorize" class="cursor-pointer">
              <q-popup-proxy transition-show="scale" transition-hide="scale">
                <q-color v-model="color" />
              </q-popup-proxy>
            </q-icon>
          </template>
        </q-input>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          color: ""
        },
        methods: {
          required(val) {
            return val || "Required";
          }
        }
      });
    </script>
  </body>
</html>

We defined the required method and then pass that into the rules prop to apply the rule.

Also, we can remove the header and footer with the no-header and no-footer props respectively:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-color v-model="color1" no-header></q-color>
        <q-color v-model="color2" no-footer></q-color>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          color1: "",
          color2: ""
        }
      });
    </script>
  </body>
</html>

Conclusion

Quasar provides a color picker component that we can add into our Vue app.