2020/04/17 に Vue 3.0.0-beta.1 がリリースされました!
お試し用の環境を作って Vue Composition API や Proxy によるリアクティブといった待望の機能を試してみましょう。
We just released Vue 3.0.0-beta.1! Here's an overview from @youyuxi on the status of 3.0 core and official tools & libraries: https://t.co/7TP5ZMtjK4
— Vue.js (@vuejs) April 16, 2020
動作環境
- macOS Catalina
- Node.js 12.16.2
- npm 6.14.4
- Vue CLI v4.3.1
- Chrome 81
Vue CLI のインストール
npm i -g @vue/cli
Vue CLI をグローバルインストールしたくない方は、以下の手順の vue
コマンド部分を npx @vue/cli
に読み替えていただいても大丈夫です。
環境構築
プロジェクトの作成
vue-3-beta-trial
というプロジェクト名で環境を構築していきます:
vue create vue-3-beta-trial
設定は以下のようにしました:
Vue CLI v4.3.1
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, Linter
? Use class-style component syntax? No
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? No
? Pick a linter / formatter config: Basic
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
プラグインの導入
プロジェクトディレクトリが出来上がったら、vue-cli-plugin-vue-next を導入します:
cd vue-3-beta-trial
vue add vue-next
ファイルの修正
vue-cli-plugin-vue-next を導入した直後に npm run serve
でビルドしようとしてもエラーが出てしまうので、 *.d.ts
ファイルと *.vue
ファイルを修正します:
-
src/shims-tsx.d.ts
の内容をすべてコメントアウトする -
src/App.vue
,src/components/HelloWorld.vue
の内容を以下のように修正:
<script lang="ts">
-import Vue from 'vue';
+import { defineComponent } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
-export default Vue.extend({
+export default defineComponent({
name: 'App',
components: {
HelloWorld
以上で npm run serve
でビルドができるようになりました
ファイルの差分をみてみる
vue create
コマンドで作成したプロジェクトは自動で git の初期コミットが済んだ状態のため、 git status
で vue add vue-next
コマンド以降に差分が出たファイルを確認できます:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .eslintrc.js
modified: package-lock.json
modified: package.json
modified: src/App.vue
modified: src/components/HelloWorld.vue
modified: src/main.ts
modified: src/shims-tsx.d.ts
package.json
の差分
@@ -8,7 +8,7 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
- "vue": "^2.6.11"
+ "vue": "^3.0.0-beta.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.26.0",
@@ -16,10 +16,11 @@
"@vue/cli-plugin-eslint": "~4.3.0",
"@vue/cli-plugin-typescript": "~4.3.0",
"@vue/cli-service": "~4.3.0",
+ "@vue/compiler-sfc": "^3.0.0-beta.1",
"@vue/eslint-config-typescript": "^5.0.2",
"eslint": "^6.7.2",
- "eslint-plugin-vue": "^6.2.2",
+ "eslint-plugin-vue": "^7.0.0-alpha.0",
"typescript": "~3.8.3",
- "vue-template-compiler": "^2.6.11"
+ "vue-cli-plugin-vue-next": "~0.1.2"
}
}
src/main.ts
の差分
@@ -1,8 +1,4 @@
-import Vue from 'vue'
+import { createApp } from 'vue';
import App from './App.vue'
-Vue.config.productionTip = false
-
-new Vue({
- render: h => h(App),
-}).$mount('#app')
+createApp(App).mount('#app')
vuejs/rfcs の 0009-global-api-change.md に書いてある通り、 Vue 2系 におけるプラグイン導入(Vue.use()
)によるグローバル汚染問題の解消のためこのような書き方に変更となったようです。
お試し編
Vue Composition API を試してみる
https://composition-api.vuejs.org/ にあった Basic example をコピーしてビルドしてみました:
<template>
<button @click="increment">
Count is: {{ state.count }}, double is: {{ state.double }}
</button>
</template>
<script>
import { reactive, computed } from 'vue'
export default {
setup() {
const state = reactive({
count: 0,
double: computed(() => state.count * 2)
})
function increment() {
state.count++
}
return {
state,
increment
}
}
}
</script>
シンプルなカウンターが動作しました。
(なお、上記のコードであれば Vue 2.6.11 に @vue/composition-api (Vue 2 向けのプラグイン)を導入して試すことができます)
Proxy な reactive を試してみる
Vue 3.0 では Proxy ベースのリアクティブ実装となる1ため、従来のリアクティブ実装2では実現できなかった配列のインデックスと一緒にアイテムを直接セットする場合についても変更を検知可能になるようです。
<template>
<button @click="increment1">
counts[0] is: {{ state.counts[0] }}
</button>
<button @click="increment2">
counts[1] is: {{ state.counts[1] }}
</button>
</template>
<script>
import { reactive } from 'vue'
export default {
setup() {
const state = reactive({
counts: [100, 200],
})
function increment1() {
state.counts[0]++
}
function increment2() {
state.counts[1]++
}
return {
state,
increment1,
increment2,
}
}
}
</script>
Vue 2系では変更の検知ができなかった state.counts[0]++
といった操作でも、画面上に値が反映されました。
また、 <button>
要素が <template>
直下に2個並んでいることから、ルート要素は必ず1個という掟についてもなくなっていることが分かります。