Vuetify 2.2の新機能 Presets

2020/01/02 にリリースされた Vuetify 2.2 から追加された**Presets機能**がなかなかに素敵だったので、記事にしてみました。

[Vuetify v2.2.0 Releas](https://github.com/vuetifyjs/vuetify/releases/tag/v2.2.0)

## Presets機能とは
Googleが策定するデザインガイドライン [Material Design]() の中で作成された、[Material studies](https://material.io/design/material-studies/about-our-material-studies.html) をpresetのスタイルとして用意してくれる機能です。

公式ドキュメント：[Vuetify Customization/Presets](https://vuetifyjs.com/ja/customization/presets)

下記はリリースページに掲載されているPresets機能のサンプルです。
<img width="300px" alt="basil" src="https://user-images.githubusercontent.com/9064066/71647028-2387e500-2cb6-11ea-8863-75c5e2effb9a.png">
<img width="300px" alt="owl" src="https://user-images.githubusercontent.com/9064066/71648675-ed099480-2ccc-11ea-97e6-78ee87477cca.png">
<img width="300px" alt="shrine" src="https://user-images.githubusercontent.com/9064066/71650749-c56ef800-2cdd-11ea-9ba6-1cd7a275e8b5.png">

## Material studiesとは
[Material studies](https://material.io/design/material-studies/about-our-material-studies.html) は[レシピアプリ](https://material.io/design/material-studies/basil.html#)、[ファイナンスアプリ](https://material.io/design/material-studies/rally.html#)、[教育アプリ](https://material.io/design/material-studies/owl.html#)などより具体的なアプリケーションのデザイン例と共に、そのデザインの**理論的根拠**や**コンポーネント選択**について詳細に説明した、Material Designを学ぶ上で非常に有用なコンテンツとなっております。

<img width="300px" alt="basil_studies" src="https://storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1579302979877%2Fassets%2F12WcnQceK_XdiYVO_0IOeeKzGpwelBSZT%2Fcasestudies-basil-main.png">
<img width="300px" alt="rally_studies" src="https://storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1579302979877%2Fassets%2F1MvqIqiMU-07zdfL5gFNeKeg1DrzFHOtj%2Fcasestudies-rally-main.png">
<img width="300px" alt="owl_studies" src="https://storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1579302979877%2Fassets%2F1MbmV841MQ_gu7nNWpdP-JHzNYNwb3jMl%2Fcasestudies-owl-main.png">

## 要するに
**Material studies のアプリのデザインを Vuetify でサクッと試せる機能**

## 使い方
Preset は Vue CLI の plugin として実装されているので、Vue CLIを利用して追加します。
利用方法は [vuetifyjs/vue-cli-plugins](https://github.com/vuetifyjs/vue-cli-plugins) リポジトリにまとめられていますので、そちらも参照してください。

### Vue CLIのインストール
インストール済みの方はスキップしてください。

```console
$ npm install -g @vue/cli
# OR
$ yarn global add @vue/cli
```

参考：[Vue CLI Getting Started](https://cli.vuejs.org/#getting-started)

### Preset Rallyを試す

```console
# プロジェクト作成
$ vue create my-app
$ cd my-app

# vuetifyをプロジェクトに追加
$ vue add vuetify

# 任意のpresetを追加
# 今回はrallyを選択
$ vue add vuetify-preset-rally

# 起動して確認
$ yarn serve
```

起動すると、下記のような感じでスタイルが適用されているのがわかります。
色やフォントが変化しています。
いくつかコンポーネントのスタイルも変更されているようですが、それらは自分でコンポーネントを追加しないと分からないようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214526/83bb251f-8574-4bc1-848f-58544081d378.png)

### 何が起こったのか？
`vue add vuetify-preset-rally` によって発生した差分は下記の通りです。

```console
$ git status
	modified:   package.json
	modified:   public/index.html
	modified:   src/plugins/vuetify.js
	modified:   yarn.lock
```

`public/index.html` の diff は下記の通りで、fontが追加されています。

```diff:public/index.html
diff --git a/public/index.html b/public/index.html
index 2545523..ae2a70f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -8,6 +8,7 @@
     <title>my-app</title>
     <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Condensed:300,400,500,700:100,300,400,500,700,900|Eczar:400:100,300,400,500,700,900&display=swap">
   </head>
   <body>
     <noscript>
```

`src/plugins/vuetify.js` に関しては、モジュールをimportし、vuetifyへ渡す実装が追加されていました。

```diff:src/plugins/vuetify.js
diff --git a/src/plugins/vuetify.js b/src/plugins/vuetify.js
index ec46adb..c14a53a 100644
--- a/src/plugins/vuetify.js
+++ b/src/plugins/vuetify.js
@@ -1,7 +1,9 @@
 import Vue from 'vue';
 import Vuetify from 'vuetify/lib';
+import { preset } from 'vue-cli-plugin-vuetify-preset-rally/preset'

 Vue.use(Vuetify);

 export default new Vuetify({
+  preset,
 });
```

ここで利用されている `vue-cli-plugin-vuetify-preset-rally` の実装は下記にあります。
https://github.com/vuetifyjs/vue-cli-plugins/tree/master/packages/vue-cli-plugin-vuetify-preset-rally

`preset` ディレクトリの中の実装を見ると、`index.js` によるthemeのカラーの設定や、 `scss` と `sass` によるスタイルのoverrideが実装されています。
これらにより、Material studies のスタイルが Vuetify に適用される仕組みになっています。

overrideしているstyleの数はそんなに多くありませんが、Releaseページでも、
>features are not supportable at this time. 

と書かれているので、今後に期待です。

## 課題
**Nuxt.jsからだとどうPresetsを追加すべきかが悩ましい**
個人的にVuetifyを使う場合、セットでNuxt.jsを利用する場合が多いです。

Nuxt.jsは公式推奨の手順だと `yarn create nuxt-app` コマンドによる初期化手順であり、Vue CLIを利用していません。
そのため、`vue add` によるpluginの追加に対応していないので、Presetsをどう追加するのかが悩ましいです。

2020/02/05 追記
指定する機能は入っているようですが、いまいちうまく動作しないようです。
https://github.com/nuxt-community/vuetify-module/pull/247

指定は下記のように `nuxt.config.js` 中で行うと思うのですが、エラーになります。
```js:nuxt.config.js
  vuetify: {
    preset: 'vue-cli-plugin-vuetify-preset-rally/preset'
  },
```

## まとめ
サクッとアプリを作った際に配色で悩むことがよくあるので、このような簡単に利用できるpresetがあるのは個人的に嬉しいです。
また、 Vue CLI以外でのインストール方法に関しては今後に期待です。