LoginSignup
380
394

More than 1 year has passed since last update.

Vue3 便利帳(随時更新)

Last updated at Posted at 2019-09-25

Vue開発してて、これは便利だなって裏技がたくさんあるんですが、すぐ忘れてしまい毎回ググらないで済むよう、自分用のメモのつもりでまとめておきます。他にもこんなんあるで!ってのあればぜひ教えてくださいね。
(ps. Vue3 x CompositionAPI x TypeScript に移行したので、内容を書き換え中。)

環境構築、基本設定

Pug の Code Folding を有効にする (VSCode)

デフォルトの設定では、.vueファイル上でPugのインデントBlockをFoldできず不便。
setting.jsonに以下を追加するとFoldできるようになります。

setting.json
{
    "[vue]": {
        "editor.foldingStrategy": "indentation"
    }
}

ローカル開発中、ホットリロード時にコンソールをクリア

コンソールがエラーだらけになってると、ちゃんとコンパイル通ったかよくわからなくなりますよね。そんな時はこちら。変更を保存してホットリロードされる度にコンソールが綺麗になります。

main.ts
if (module.hot) {
  module.hot.accept()
  module.hot.addStatusHandler(status => {
    if (status === 'prepare') console.clear()
  })
}

ローカル開発中、ターミナルの表示をシンプルにする

yarn serve でターミナルに表示される情報をシンプルにすると、エラーを把握しやすくなるかも。

vue.config.js
module.exports = {
  devServer: {
    progress: false
  }
}

グローバルなfiltersは外部ファイルにまとめておく

Vue3からはFilterが非推奨になったようです。でも、頻繁に使うものについては、まとめて定義ファイルを作っておくと便利ですよね。

filters.ts
export default {
  toPercentage (n: number): string { return (Math.round(n * 10000) / 100).toFixed(2) },
  toLocaleString (val: number, decimal = 0): string {
    const pow = Math.pow(10, decimal)
    const rounded = Math.round(val * pow) / pow
    return rounded.toFixed(decimal).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')
  }
}

グローバルで使えるようにする:

main.ts
import filters from '@/filters'
const app = createApp(App)

// register global filters
app.config.globalProperties.$filters = filters

app.mount('#app')

使い方:

hoge.vue
<template lang="pug">
section
  p Balance ${{ $filters.toLocaleString(balance, 2) }}
  //- 出力結果: Balance $1,234,567.89
</template>

setup()の中で使いたい場合はやや面倒。

hoge.vue
// getCurrentInstance をインポート
import { defineComponent, getCurrentInstance } from "vue"

export default defineComponent({
  name: "App",
  props: ["balance"],
  setup() {
    const app = getCurrentInstance(); // instanceを取得
    const $filters = app.appContext.config.globalProperties.$filters; // filtersを取得
    const balanceStr: string = $filters.toLocaleString(balance, 2); // filterを使う
    return { balanceStr }
  }
})

SCSSの変数やmixinをvueファイル内でグローバルに使えるようにする

vue.config.js
module.exports = {
  productionSourceMap: false,
  css: {
    loaderOptions: {
      scss: {
        additionalData: `
          @import "~@/assets/scss/base/_variables.scss";
          @import "~@/assets/scss/base/_media_queries.scss";
        `
      }
    }
  }
}

2022/5/4更新:"prependData"はsass-loader 8+から使えなくなりました。代わりに"additionalData"を使いましょう。)

コンパイルされるファイル名からハッシュを取り除く

vue.config.js
module.exports = {
  filenameHashing: false,
}

CodeSplitting やめてほしい時

vue.config.js
module.exports = {
  configureWebpack: {
    optimization: {
      splitChunks: false
    }
  }
}

Composition API Syntax

Lifecycle hooks

beforeCreate  -> use setup() { ... }
created       -> use setup() { ... }
beforeMount   -> onBeforeMount(() => { ... })
mounted       -> onMounted(() => { ... })
beforeUpdate  -> onBeforeUpdate(() => { ... })
updated       -> onUpdated(() => { ... })
beforeDestroy -> onBeforeUnmount(() => { ... })
destroyed     -> onUnmounted(() => { ... })
errorCaptured -> onErrorCaptured(() => { ... })

Props の Type Annotation

PropTypeをインポートして使いましょう。やや面倒ですね。

hoge.vue
import { defineComponent, PropType } from "vue";

interface Hoge {
  name: string;
  type: 'foo' | 'faa' | 'hoge';
  age: number;
}

export default defineComponent({
  name: "SectionInvestments",
  props: {
    hogeData: {
      type: Object as PropType<Hoge>,
      required: true
    }
  }
});

Scoped CSS のセレクタ

hoge.vue
<style lang="scss" scoped>
// deep selectors
.a ::v-deep(.b) { ... }

// slot
::v-slotted(.b) { ... }

// global
::v-global(.b) { ... }
</style>

以下のシンタックスも議論されていましたが、今のところうまく動かない模様。
vue3.0.0で試しましたが、global扱いになってしまいます。

hoge.vue
<style lang="scss" deep>
// deep styles
</style>

<style lang="scss" slotted>
// slotted styles
</style>

$nextTick は async/await を使ってこう書く

hoge.vue
// nextTick をインポート
import { defineComponent, ref, onMounted, nextTick } from "vue"

export default defineComponent({
  name: "App",
  setup() {
    onMounted(async () => {
      await nextTick()  // サブコンポーネントのマウントを待つ
      console.log('すべてのサブコンポーネントのマウント完了!')
    })
  }
})

$refs へのアクセスはこうする

Hoge.vue
<template lang="pug">
#hoge(ref="hoge")
  h1 Hello World!
</template>

import { defineComponent, ref } from "vue"

export default defineComponent({
  name: "Hoge",
  setup() {
    const hoge = ref(null);
    console.log(hoge.value); // ← これで#hogeにアクセスできる。
    return { hoge };
  }
})

Plugin 関連

重たいコンポーネントはLazyLoadしよう。

// 普通にコンポーネントを読み込む場合
import Hoge from '@/Hoge.vue'

// LazyLoadで呼ばれた時に読み込む場合
const Foo = () => import('@/Foo.vue')

その他にも、ロジックをjsファイルに切り出した場合も、WebpackでLazyLoadすると初期ロードを軽くできます。

import(/* webpackChunkName: "Hoge" */ '@/Hoge.js').then(module => {
  const Hoge = module.default
  Hoge.doSomething()
})

FontAwesomeを使う

参考: Font awesome を Vue.js で使ってみよう

vue-cli
$ yarn add @fortawesome/fontawesome-svg-core
$ yarn add @fortawesome/free-solid-svg-icons
$ yarn add @fortawesome/vue-fontawesome
@/plugins/fontawesome.js
import Vue from 'vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

library.add(fas)
Vue.component('font-awesome-icon', FontAwesomeIcon)
main.js
import '@/plugins/fontawesome'

アイコンの使い方:

hoge.vue
<font-awesome-icon icon="file-download" />

便利ツール

準備中

380
394
6

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
380
394