9
7

More than 3 years have passed since last update.

Quasar v1メモ

Last updated at Posted at 2019-11-20

Quasar (v1)

vueのUIというような位置づけで紹介されているところが多いが、プロジェクト作成時に基本的なフォルダ構成も作成してくれてVueRouterやVuexが使える構造になっており、SPAやSSRを指定してビルドする機能があるのでUIというよりははじめから豊富なコンポーネントを持っているNuxtのような位置づけだと思った。

ロードマップ

ドキュメント

見やすいが、アクセスできなくなってる事が多い気がするのが辛すぎる

Vueコンポーネント

Vueディレクティブ

奇麗で豊富なので楽しい。

個人的に気になったコンポーネントとディレクティブ

プロジェクト作成方法

Quasar CLI Installation

基本的な構造

Path メモ リンク
quasar.conf.js ビルド設定等 quasar-conf-js
src/index.template.html html、head、bodyタグが記載された一番外枠のファイル(configのhtmlVariablesで変数を使用したりしている)
src/App.vue
src/boot Vueがインスタンス化される前に実行 boot-files
src/store ここにstoreを記述(Vuex) vuex-store
src/router/routes.js ここにルーティングを記述(VueRouter) routing
src/components 自作コンポーネント等(使わないでpagesのみで作るのでもOK)
src/layouts 画面用コンポーネント(pagesを読み込む用)
src/pages 画面用コンポーネント
src/assets vueファイルからの相対パス./でアクセス可能なもの App Handling Assets
src/statics ビルド時にdistのstaticsにデプロイされる App Handling Assets
src/css プロジェクト作成時に設定した形式(Pick your favorite CSS preprocessor)のcssファイルが入る(SCSSやSASS等)

プロジェクト作成後の整備(とりあえずこれを設定しておけば使えるようになりそうというもの)

historyモードに変更

quasar.conf.js
vueRouterMode: 'history',

テーマカラーを変更

src/css/quasar.variables.sass
$primary   : #027BE3
$secondary : #26A69A
$accent    : #9C27B0

$positive  : #21BA45
$negative  : #C10015
$info      : #31CCEC
$warning   : #F2C037

FontAwesomeを使えるようにする

quasar.conf.js
    // https://github.com/quasarframework/quasar/tree/dev/extras
    extras: [
      // 'ionicons-v4',
      // 'mdi-v4',
-     // 'fontawesome-v5',
+     'fontawesome-v5',
      // 'eva-icons',
      // 'themify',
      // '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
    ],
FontAwesomeで使用するアイコンのclassをそのまま設定することで使用可能
<q-icon name="fas fa-question-circle" />

axiosを設定する

src/boot/axios.js
import Vue from 'vue';
import axios from 'axios';

const axiosInstance = axios.create({
  baseURL: 'http://example.com',
  'Content-Type': 'application/json',
  Accept: 'application/json'
});

// *.vueからはthis.$axiosで呼び出せます
Vue.prototype.$axios = axiosInstance;

export { axiosInstance };
quasar.conf.js
boot: [
  'axios'
],

VueRouterにナビゲーションガードを設定してログイン判定等を行う

src/boot/auth.js
import { axiosInstance } from 'boot/axios';

export default ({ router, store, Vue }) => {
  router.beforeEach((to, from, next) => {
    to.matched.some(async (record) => {
      // https://router.vuejs.org/ja/guide/advanced/meta.html
      if (!record.meta.requiresAuth) {
        // ログイン不要
        next();
      } else {
        // ログイン必要
        let postData = new FormData();
        postData.append('name', 'value');

        await axiosInstance.post('endpoint', postData)
          .then(response => {
            next();
          })
          .catch(error => {
            if (error.response.status === 401) {
              next({ name: 'login' });
            } else {
              next({ name: 'home' });
            }
          })
          .finally(() => {
            // finally
          });
      }
    });
  });
};
quasar.conf.js
boot: [
  'axios',
  'auth'
],

lodash等のツールを使えるようにする

src/boot/lodash.js
import _ from 'lodash';

export default ({ app, router, Vue }) => {
  window._ = _;
};
quasar.conf.js
boot: [
  'axios',
  'auth',
  'lodash'
],

mixinを使う

src/mixins/api.js
import { axiosInstance } from 'boot/axios';

export default {
  methods: {
    post: (url, data) => {
      // return Promise
      return axiosInstance.post(url, data);
    }
  }
};
src/pages/XXXXXX.vue
<template>
  <q-page class="flex flex-center">
    <img @click="callMixin" alt="Quasar logo" src="~assets/quasar-logo-full.svg">
  </q-page>
</template>

<script>
import Api from '../mixins/api';

export default {
  name: 'XXXXXX',
  mixins: [Api],

  methods: {
    async callMixin () {
      let response = await this.post('endpoint', {});
    }
  }
};
</script>

Vuexを使う

exampleストアのモジュールを作る

src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';

import example from './example';

Vue.use(Vuex);

/*
 * If not building with SSR mode, you can
 * directly export the Store instantiation
 */

// *.vueからはthis.$storeで呼び出せます
// how to access state: this.$store.state.example.XXXXXX
// how to access getter: this.$store.getters.example.someGetter
// how to call mutation: this.$store.commit('example/someMutation', val)
// how to call action: this.$store.dispatch('example/someAction', val)

export default function (/* { ssrContext } */) {
  const Store = new Vuex.Store({
    modules: {
      example
    },

    // enable strict mode (adds overhead!)
    // for dev mode only
    strict: process.env.DEV
  });

  return Store;
}
src/store/example/index.js
import state from './state';
import * as getters from './getters';
import * as mutations from './mutations';
import * as actions from './actions';

export default {
  namespaced: true,
  getters,
  mutations,
  actions,
  state
};

Actions

src/store/example/actions.js
// action
// trriger: store.dispatch('someAction')
// action method is Includes asynchronous processing

export function someAction (context) {
//   context.commit('someMutation'); // call mutation
//   context.dispatch('someAction'); // call action
//   context.state.XXXXXX; // access store.state
//   context.getters.someGetter; // access store.getter
}

Getters

src/store/example/getters.js
// getter
// trriger: store.getters.someGetter
// Accessible as Computed Properties

export function someGetter (state) {
//   return state.XXXXXX + state.XXXXXX;
}

Mutations

src/store/example/mutations.js
// mutation
// trriger store.commit('methodName')
// Mutation methods must be synchronous

export function someMutation (state) {
//  state.example = 'example';
}

State

src/store/example/state.js
export default {
  example: ''
};
9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7