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.json
のcompilerOptions
に以下の設定を追加します。
{
"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で作ったフロントエンドアプリのバンドルサイズを削減する