SMARTCAMP Engineer Blog

スマートキャンプ株式会社(SMARTCAMP Co., Ltd.)のエンジニアブログです。業務で取り入れた新しい技術や試行錯誤を知見として共有していきます。

Vue.js 3 のベータ版がリリースされたので予習してみる

こんにちは!スマートキャンプでエンジニアをしている中川です。

いきなりですが、つい先日待望の Vue.js 3.0.0 beta がリリースされました!

ステータスは beta なのでいま2系からアップグレードすることに抵抗はありつつも、待望の新バージョンなので内容が気になる・試してみたい方も多いのではないでしょうか。(かくいう私自身がそうです)

そこで今回の記事ではVue.jsの今後のロードマップを紹介して、何がいつリリースされるのか・どう移行するのか等をまとめた上で、気になったVue 3系の変更点をいくつかピックアップしていきます。

記事の後半には実際にVue 3系をサンプルプロジェクトで導入してみているので、ご興味がある方はご覧ください。

今後のスケジュール(ロードマップ)を見てみる

まずはロードマップですが、こちらにGithub Projectsとして公開されています。

Roadmap · GitHub

列を時系列としてクオーター単位で区切られており、執筆時点(2020/04/29)では2020 Q1の最中に位置しています。

進行具合としては3.0 Beta by end of Q1とされていた3.0 Betaがすでにリリースされているので、概ねスケジュール通りかやや早いくらいで進行していると言えそうです。

また、RCリリースは2020 Q2の中ごろということで、だいたい7月ごろにリリースされるようなスケジュール感で認識していれば良さそうです。

他にも、左端のFAQの列には実際ユーザーから多く寄せられたであろう質問とその回答が記載されています。 回答の中から特に気になったポイントを以下に羅列しました。

  • 既存のVue 2系ユーザーに対してはマイグレーションガイドやマイグレーションツールをCLIで提供(該当コードを自動でアップグレード・手動でアップグレードが必要なものもスキャン)する。
  • 2系に関してはこの後(Vue 3のRCリリースとどちらが前後するかは不明)、2.7がリリースされる予定
    • 互換性のある3系の機能が2系にも実装される
    • 2.7は2系最後のマイナーリリースとなり、以後18ヶ月間LTSになる
  • VuexはVue 3に対応するためのバージョン4をリリースする。
    • バージョン4は以前のバージョンと全く同じAPIを持ち、Vue 3に移行したユーザーがVuexもスムーズに移行出来るようにするためのもの
    • すでにバージョン5としてVue 3で搭載されるreactivity APIなどを活用したVuex自体の新しいデザインも行っているが、初期段階でありリリースは2020 Q3以降になる見込み

最後のVuexに関してはすでにbeta版が先日リリースされており、この記事の後半でも導入してみています。

変更点を見てみる

次に、実際にVue 3系になることでどういった変更があったのかを見ていきます。

以下のリンクからRFC経由で3系に取り込まれたものの一覧が見れます。

Pull Requests · vuejs/rfcs · GitHub

特にbreaking changeタグのついたPRは今後Vue 3系にアップデートする上で対応が必要なものも含まれる可能性があるものなので、ここからいくつかピックアップしてみます。

Scoped Style Changes

Scoped Style Changes by yyx990803 · Pull Request #119 · vuejs/rfcs · GitHub

従来のVueでは、SFCのstyleタグにscopedを指定しているとき、基本的には該当のコンポーネントにのみCSSが適用されていますが、新たに::v-deep, ::v-slotted, ::v-globalを追加するPRになっています。

::v-deepに関してはこれまで/deep/>>>といったシンタックスで同様のことが出来ていましたが、削除されたCSS自体のシンタックスと混同してユーザーが混乱するといった事情から3系からdeprecatedとなるようです。

話が逸れますが、個人的にはRFCのなかで触れられてる以下の一文が気になりました。

We are also aware that many users want to be able to use component props or state in the CSS of single-file components. We do have plans to support that but it will be in a separate RFC.

データによって変動する可能性のある高さや幅を持つコンポーネントのスタイリングを見通し良く簡潔に実装することはこれまで難しかったので、ここが解決されるとかなり嬉しいですね...!

Remove data object declaration

Remove data object declaration by CyberAP · Pull Request #111 · vuejs/rfcs · GitHub

読んで字の如しですが、ルートコンポーネントのdataプロパティの値にオブジェクトを渡すことが出来なくなります。

これまでルートコンポーネントのdataプロパティの値には関数もしくはオブジェクトを渡すことが出来ましたが、2通りの宣言が出来てしまうことや、オブジェクトを渡したときのみすべてのインスタンス間で状態を共有出来ることが混乱を招くのが削除される意図のようです。

数年前から存在するUIのためのサンプルプロジェクトなどはオブジェクトを渡しているパターンがあったりするので、今後参考にする場合は気をつける必要がありそうです。

Remove filters

Remove filters by yyx990803 · Pull Request #97 · vuejs/rfcs · GitHub

これまでコンポーネントのtemplateタグでは{{ msg | format }}のような形で値をフォーマットすることが出来ましたが、この構文が{{ format(msg) }}のように変わります。

変更の意図としては、|というシンタックスがJavaScript自体の演算子と衝突することにより式の解析を複雑にしていることが挙げられています。

その他

気になったPRの紹介は以上ですが、他にもワクワクするような変更が多くあるので、一度上記のPR一覧から変更点を眺めてみるとよさそうです!

また、Vue 3ではComposition APIといった大きな変更も予定されています。 Composition APIは以前ハンズオン記事を書いたのでよろしければ併せてご覧ください。

tech.smartcamp.co.jp

実際に試してみる

最後に、実際にVue 3のbeta版を手元で試してみます。

導入方法としては、Vue CLIのプラグインとしてVue 3のベータ版を試すためのものが公式から提供されているためそちらを使用していきます。

github.com

まずはVue CLIでサンプルプロジェクトを作成します。

$ vue create try-out-vue-3

いくつかの質問に答えていきます。今回は以下のように選択しました。 Linterなどは好みですが、TypeScriptとVuexは選択しておくようにしましょう。

f:id:mkt0225:20200429195327p:plain

プロジェクトが作成されたことを確認したら上述したプラグインを入れます。

$ cd try-out-vue-3
$ vue add vue-next

これだけでセットアップは完了です!この手軽さは素晴らしいですね。 念の為、バージョンを確認するためにpackage.jsonを見てみます。

"vue": "^3.0.0-beta.1",
"vue-router": "^4.0.0-alpha.5",
"vuex": "^4.0.0-alpha.1"

よさそうですね。 試しに$ yarn serveしてみるとコケてしまうので、表示されたエラーに従っていくつかのファイルを修正していきます。

src/main.ts

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";

const app = createApp(App);

app.use(router);
app.use(store);
app.mount("#app");

src/store/index.ts

import { createStore } from 'vuex'

export default createStore({
  state: {},
  mutations: {},
  actions: {},
  modules: {}
});

src/router/index.ts

import { RouteRecordRaw, createRouter, createWebHistory } from "vue-router";
import Home from "../views/Home.vue";

const routes: Array<RouteRecordRaw> = [
  {
    path: "/",
    name: "Home",
    component: Home
  },
  {
    path: "/about",
    name: "About",
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () =>
      import(/* webpackChunkName: "about" */ "../views/About.vue")
  }
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
});

export default router;

上記の変更を行った後、再度$ yarn serveしたところ無事立ち上がりました。

f:id:mkt0225:20200429195435p:plain

コンソール上のエラーも表示されていないのでよさそうですね。

以上で導入は完了です!

まとめ

駆け足で紹介してきましたが、いかがだったでしょうか。

正式リリースまでは少し日がありますが、今から次バージョンに目を向けておき、スムーズな移行をしていきたいですね!

今回の記事は以上になります、それでは!

www.wantedly.com