2020年6月追記:記事の内容がだいぶ古くなっていたので、最新の情報に見直しました。

Vue+TypeScriptで作ったフロントエンドアプリの見た目をよくしたかったので、Vuetifyを導入しました。
Quick Startにいっぱい書いてあって、どれをどうやればいいかが結構分かりにくかったので、導入手順を記載しておきます。

インストール

こちら にしたがって導入をします。

VuetifyのUI Componentを利用する箇所で毎回moduleをimportしなくても、自動的にimportしてくれる vuetify-loader を利用するケースについて記載しています。

依存ライブラリを追加します。

npm install --save vuetify
npm install --save-dev sass sass-loader fibers deepmerge -D
npm install --save-dev vuetify-loader
npm install --save @mdi/font -D # Material Design Iconsを使う場合

webpack.config.jsの設定

rulesにsass-loader、pluginsにVuetifyLoaderPluginの設定を追加します。

const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')

module.exports = {
  rules: [
    {
      test: /\.s(c|a)ss$/,
      use: [
        'vue-style-loader',
        'css-loader',
        {
          loader: 'sass-loader',
          // Requires sass-loader@^7.0.0
          options: {
            implementation: require('sass'),
            fiber: require('fibers'),
            indentedSyntax: true // optional
          },
          // Requires sass-loader@^8.0.0
          options: {
            implementation: require('sass'),
            sassOptions: {
              fiber: require('fibers'),
              indentedSyntax: true // optional
            },
          },
        },
      ],
    },
  ],
  plugins: [
    new VuetifyLoaderPlugin(),
  ]
}

vuetifyの組み込み

plugins/vuetify.tsを作成して、以下のように記載します。

import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import '@mdi/font/css/materialdesignicons.css' // mdi-iconを使う場合、バンドルに含めるためにimport必要

Vue.use(Vuetify)

export default new Vuetify({
  icons: {
    iconfont: 'mdi', // mdi-iconを使う場合
  },
})

このままだと、Could not find a declaration file for module 'vuetify/lib'. と怒られるので、tsconfig.jsoncompilerOptionsに以下の設定を追加します。

{
  "compilerOptions": {
+    "types": [
+      "vuetify"
+    ],
  }
}

app.tsで先ほど作成したplugins/vuetify.tsを読み込みます。

import Vue, { CreateElement } from 'vue'
import vuetify from '../plugins/vuetify'
import { VNode } from 'vue/types/umd'

new Vue({
  vuetify,
  render: (h: CreateElement): VNode => h(App),
}).$mount('#app')

vuetifyを適用する範囲を指定

これが一番大事だと思うのですが、vuetifyを適用する範囲を<v-app>で囲む必要があります。
App.vueの一番トップレベルをで囲むことにしました。

<template>
  <v-app>
    <Hoge />
    <Fuga />
  </v-app>
</template>

これで、App.vue配下でvuetifyが使えるようになりました。

UIコンポーネントを利用

あとは、こちらを参考にして、UIコンポーネントを使っていけば大丈夫です。importせずとも使えます。

例えば、テキストエリアに被せるようにSAVEボタンを表示するケースであれば、を使って以下のように書けば動きました。

<template>
  <v-card>
    <v-btn small fab color="info" absolute top right @click=handleSaveButtion>save</v-btn>
    <v-card-text>
      <v-textarea label="自由にメモを記載してください。" v-model=memo rows=15 ></v-textarea>
    </v-card-text>
  </v-card>
</template>

こんな感じでまあまあいい感じの見た目になったかな。。

[参考] CDNを利用してバンドルサイズを削減

CDNを利用してバンドルサイズを削減することを考えることもあると思います。別記事を書いてまして、そちらでvuetifyをCDNから読み込むように変更していますので、興味があれば参照してください。
Vue+Firebaseで作ったフロントエンドアプリのバンドルサイズを削減する