Prologue
Vue3 のプロジェクトの立ち上げ方と Vue2 -> Vue3 の移行が現状どのようになっているのか確認するために検証を行いました。
Vue3や使用している CLI 等は今後変更があると思いますので、自身で設定する場合には都度公式を確認することをお勧めします。
環境
- macOS: v10.15.6
- node.js: v12.18.2
- terminal: iTerm
- エディタ: VS Code
- パッケージマネージャ:
yarn
install
vueCLI v4.5.0 で Vue3 のプロジェクトを選択できるようになりました。
参考:
- https://github.com/vuejs/vue-cli/releases/tag/v4.5.0
- https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md
- https://v3.vuejs.org/guide/
今回 バージョンが Vue CLI v4.4.6
だったため、 yarn global add @vue/cli
を実行し、バージョンを上げます。
参考: https://github.com/vuejs/vue-cli/releases
以下のコマンドを実行してバージョンの確認の確認をし、問題なければOKです。
vue -V
@vue/cli 4.5.4
プロジェクトの作成 : Default Vue 3 Preview を選択
vue create vue3-next
コマンドを実行します。今回プロジェクトは vue3-next
としています。
Vue CLI v4.5.4
? Please pick a preset:
Default ([Vue 2] babel, eslint)
❯ Default (Vue 3 Preview) ([Vue 3] babel, eslint)
Manually select features
デフォルトで Vue3 が選択できるようになっています。感動。
package.json
を確認します。
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0-0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0-0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0-0"
},
yarn.lock
も確認してみます。
vue@^3.0.0-0:
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-rc.10.tgz#31298a757b4fad6ee8973d0fa27c4fde8574bd01"
integrity sha512-nRsyIQtOWLDMBb5dsPwg/WdIqznCMVWN6O6wJSzhseKC768wHlZKcJ7SPHhWPid9wi3Ykhtl9vtgvxTK/qICkw==
dependencies:
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/runtime-dom" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
vue3.0.0-rc.10
がインストールされていて、 yarn serve
を実行し問題なく表示されて入ればOKです。
プロジェクトの作成 : Manually select features を選択
manually select
を選択します。
Vue CLI v4.5.4
? Please pick a preset:
Default ([Vue 2] babel, eslint)
Default (Vue 3 Preview) ([Vue 3] babel, eslint)
❯ Manually select features
次に Vue のバージョンの選択肢が表示されるため、3.x を選択します。
? Choose a version of Vue.js that you want to start the project with
2.x
❯ 3.x (Preview)
以下はこれまで通り、自分が使うモジュール等を選択していきます。
vue create vue3-next-manually
Vue CLI v4.5.4
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, Rou
ter, Vuex, Linter
? Choose a version of Vue.js that you want to start the project with 3.x (Previe
w)
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfi
lls, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback
in production) Yes
? Pick a linter / formatter config: Prettier
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated confi
g files
? Save this as a preset for future projects? No
manually select
だと従来通り TS も選択できるため、TS を使用したい方はこちらを選択すると設定周りも楽になります。(Default (Vue 3 Preview)
だと手動で入れる必要があります。)
package.json
を確認します。
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0-0",
"vue-class-component": "^8.0.0-0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0-0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^7.0.0-0",
"prettier": "^1.19.1",
"typescript": "~3.9.3"
}
次に yarn.lock
も確認してみます。
vue@^3.0.0-0:
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-rc.10.tgz#31298a757b4fad6ee8973d0fa27c4fde8574bd01"
integrity sha512-nRsyIQtOWLDMBb5dsPwg/WdIqznCMVWN6O6wJSzhseKC768wHlZKcJ7SPHhWPid9wi3Ykhtl9vtgvxTK/qICkw==
dependencies:
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/runtime-dom" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
以上、2種類の操作を試しましたが、Vue3 のバージョンに違いがないことを確認しました。こちらも yarn serve
を実行して画面が表示されればOKです。
プロジェクトの作成 : Manually select features を選択, class-style component を使わない
ここでは CompositionAPI を使いたい場合、 class-style component
を選択しないと違いがあるのかを検証しています。
プロジェクトの作成
vue create vue3-next-manually-no-class
Vue CLI v4.5.4
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, Rou
ter, Vuex, Linter
? Choose a version of Vue.js that you want to start the project with 3.x (Previe
w)
? Use class-style component syntax? No
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfi
lls, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback
in production) Yes
? Pick a linter / formatter config: Prettier
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated confi
g files
? Save this as a preset for future projects? No
package.json
を確認します。
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0-0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0-0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^7.0.0-0",
"prettier": "^1.19.1",
"typescript": "~3.9.3"
}
yarn.lock
も確認してみます。
vue@^3.0.0-0:
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-rc.10.tgz#31298a757b4fad6ee8973d0fa27c4fde8574bd01"
integrity sha512-nRsyIQtOWLDMBb5dsPwg/WdIqznCMVWN6O6wJSzhseKC768wHlZKcJ7SPHhWPid9wi3Ykhtl9vtgvxTK/qICkw==
dependencies:
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/runtime-dom" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
// 略
vuex@^4.0.0-0:
version "4.0.0-beta.4"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.0.0-beta.4.tgz#7b319ead2ef30432b7eaa4e37258ea3c5e44f698"
integrity sha512-/+4E1dokq5cwbl4mohOqOj8h0vOLOWmLSqlqTf++bfmN9/JKWtwYfsBrzlK0sYrNfuYcpQeX0BVxQHoHXDfYZQ==
// 略
vue-router@^4.0.0-0:
version "4.0.0-beta.9"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.0-beta.9.tgz#8552c38c9b015527e74c9c6cb4c54868219d601e"
integrity sha512-k8AGMm3LCTqnsEuF37AD4kcZVMwtnFEzdjACgmIII/xbLnTj3+o5XyH/zREBZutgv5q2hzlLltMVglqDQYMd/A==
"vue-class-component": "^8.0.0-0"
がないだけとなります。この辺りも従来通りという感じです。
CompositionAPI が使えるか確認
Vue2 までは plugin の CompositionAPI
を import して使う必要がありましたが、Vue3 ではその必要が無くなったということで、実際書いてみます。
src/components/HelloWorld.vue
を以下のように変更
- before
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "HelloWorld",
props: {
msg: String
}
});
</script>
- after
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "HelloWorld",
props: {
msg: {
type: String
}
},
setup(props) {
const message = `${props.msg}. + Vue3`;
return { message };
}
});
</script>
before
の時点で vue
から defineComponent
が import されているため使えることは当たり前なのですが、念のため setup
等も追記してみました。
追加したテキスト等が表示されていればOKです。
既存のプロジェクトをVue3 に変更
ここからが一番使うのではないでしょうか。
まずはVue2 でプロジェクトを作成します。今回プロジェクト名は vue3-next-cli-plugin
としました。
TS, Vuex, vue-router も一緒にインストールしていきます。
vue create vue3-next-cli-plugin
Vue CLI v4.5.4
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, Rou
ter, Vuex, Linter
? Choose a version of Vue.js that you want to start the project with 2.x
? Use class-style component syntax? No
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfi
lls, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback
in production) Yes
? Pick a linter / formatter config: Prettier
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated confi
g files
? Save this as a preset for future projects? No
package.json
の中身を確認します。
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^6.2.2",
"prettier": "^1.19.1",
"typescript": "~3.9.3",
"vue-template-compiler": "^2.6.11"
}
yarn.lock
の中身も確認します。
vue@^2.6.11:
version "2.6.12"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123"
integrity sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg==
//
vuex@^3.4.0:
version "3.5.1"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.5.1.tgz#f1b8dcea649bc25254cf4f4358081dbf5da18b3d"
integrity sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw==
//
vue-router@^3.2.0:
version "3.4.3"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.4.3.tgz#fa93768616ee338aa174f160ac965167fa572ffa"
integrity sha512-BADg1mjGWX18Dpmy6bOGzGNnk7B/ZA0RxuA6qedY/YJwirMfKXIDzcccmHbQI0A6k5PzMdMloc0ElHfyOoX35A==
HelloWorld.vue
は以下の通り。
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
name: "HelloWorld",
props: {
msg: String
}
});
</script>
以上は、以下から行う比較のために参考として置いておきます。
vue add vue-next
で Vue3 を入れる
参考: https://github.com/vuejs/vue-cli-plugin-vue-next
コマンドを実行します。
vue add vue-next
📦 Installing vue-cli-plugin-vue-next...
yarn add v1.22.4
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Saved lockfile.
success Saved 2 new dependencies.
info Direct dependencies
└─ vue-cli-plugin-vue-next@0.1.3
info All dependencies
├─ vue-cli-plugin-vue-next@0.1.3
└─ vue-loader@16.0.0-beta.5
✨ Done in 4.19s.
✔ Successfully installed plugin: vue-cli-plugin-vue-next
🚀 Invoking generator for vue-cli-plugin-vue-next...
📦 Installing additional dependencies...
yarn install v1.22.4
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Saved lockfile.
✨ Done in 7.65s.
⚓ Running completion hooks...
✔ Successfully invoked generator for plugin: vue-cli-plugin-vue-next
vue-next Installed vuex 4.0.
vue-next Documentation available at https://github.com/vuejs/vuex/tree/4.0
vue-next Installed vue-router 4.0.
vue-next Documentation available at https://github.com/vuejs/vue-router-next
インストールが完了しました。次に package.json
の中身を確認してみます。
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0-beta.1",
"vue-router": "^4.0.0-alpha.6",
"vuex": "^4.0.0-alpha.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0-beta.1",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^7.0.0-alpha.0",
"prettier": "^1.19.1",
"typescript": "~3.9.3",
"vue-cli-plugin-vue-next": "~0.1.3"
}
yarn.lock の中身も確認します。
vue@^3.0.0-beta.1:
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-rc.10.tgz#31298a757b4fad6ee8973d0fa27c4fde8574bd01"
integrity sha512-nRsyIQtOWLDMBb5dsPwg/WdIqznCMVWN6O6wJSzhseKC768wHlZKcJ7SPHhWPid9wi3Ykhtl9vtgvxTK/qICkw==
dependencies:
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/runtime-dom" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
// 略
vuex@^4.0.0-alpha.1:
version "4.0.0-beta.4"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.0.0-beta.4.tgz#7b319ead2ef30432b7eaa4e37258ea3c5e44f698"
integrity sha512-/+4E1dokq5cwbl4mohOqOj8h0vOLOWmLSqlqTf++bfmN9/JKWtwYfsBrzlK0sYrNfuYcpQeX0BVxQHoHXDfYZQ==
// 略
vue-router@^4.0.0-alpha.6:
version "4.0.0-beta.9"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.0-beta.9.tgz#8552c38c9b015527e74c9c6cb4c54868219d601e"
integrity sha512-k8AGMm3LCTqnsEuF37AD4kcZVMwtnFEzdjACgmIII/xbLnTj3+o5XyH/zREBZutgv5q2hzlLltMVglqDQYMd/A==
package.json
では vue: ^3.0.0-beta.1
となっていましたが、yarn.lock
で最新版が落とされていることを確認しました。vue-router
, vuex
も同様です。
Error の解消
このままで yarn serve
を実行すると、エラーが出ます。
ERROR Failed to compile with 6 errors 22:57:58
Module Error (from ./node_modules/vue-loader/lib/index.js):
[vue-loader] vue-template-compiler must be installed as a peer dependency, or a compatible compiler implementation must be passed via options.
// 略
Module build failed (from ./node_modules/vue-loader/lib/index.js):
TypeError: Cannot read property 'parseComponent' of undefined
at parse (/Users/mi**/work/vue3-next-cli-plugin/node_modules/@vue/component-compiler-utils/dist/parse.js:15:23)
at Object.module.exports (/Users/mi**/work/vue3-next-cli-plugin/node_modules/vue-loader/lib/index.js:67:22)
// 略
You may use special comments to disable some warnings.
Use // eslint-disable-next-line to ignore the next line.
Use /* eslint-disable */ to ignore all warnings in a file.
ERROR in src/main.ts:6:11
TS2345: Argument of type 'typeof import("/Users/mi**/work/vue3-next-cli-plugin/node_modules/vue/dist/vue")' is not assignable to parameter of type 'Component'.
Type 'typeof import("/Users/mi**/work/vue3-next-cli-plugin/node_modules/vue/dist/vue")' is not assignable to type 'ComponentOptionsWithObjectProps<any, any, any, any, any, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, Readonly<{ [x: string]: any; }> | Readonly<...>>'.
Type 'typeof import("/Users/mi**/work/vue3-next-cli-plugin/node_modules/vue/dist/vue")' is not assignable to type 'ComponentOptionsBase<Readonly<{ [x: string]: any; }> | Readonly<{ [x: string]: any; } & { [x: number]: any; }>, any, any, any, any, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string>'.
Types of property 'watch' are incompatible.
Type '{ <T extends readonly (object | Ref<unknown> | ComputedRef<unknown> | (() => unknown))[], Immediate extends boolean = false>(sources: T, cb: WatchCallback<MapSources<T>, MapOldSources<T, Immediate>>, options?: WatchOptions<...> | undefined): WatchStopHandle; <T, Immediate extends boolean = false>(source: WatchSource...' is not assignable to type 'Record<string, ComponentWatchOptionItem>'.
Index signature is missing in type '{ <T extends readonly (object | Ref<unknown> | ComputedRef<unknown> | (() => unknown))[], Immediate extends boolean = false>(sources: T, cb: WatchCallback<MapSources<T>, MapOldSources<T, Immediate>>, options?: WatchOptions<...> | undefined): WatchStopHandle; <T, Immediate extends boolean = false>(source: WatchSource...'.
4 | import store from "./store";
5 |
> 6 | createApp(App)
| ^^^
7 | .use(router)
8 | .use(store)
9 | .mount("#app");
ERROR in src/router/index.ts:1:10
TS2305: Module '"../../node_modules/vue-router/dist/vue-router"' has no exported member 'RouteConfig'.
> 1 | import { RouteConfig, createRouter, createWebHistory } from "vue-router";
| ^^^^^^^^^^^
2 | import Home from "../views/Home.vue";
3 |
4 | const routes: Array<RouteConfig> = [
ERROR in src/store/index.ts:3:21
TS2339: Property 'createStore' does not exist on type '{ Store: typeof Store; mapState: Mapper<Computed> & MapperWithNamespace<Computed> & MapperForState & MapperForStateWithNamespace; ... 4 more ...; createLogger: <S>(option?: LoggerOption<...> | undefined) => Plugin<...>; }'.
1 | import Vuex from "vuex";
2 |
> 3 | export default Vuex.createStore({
| ^^^^^^^^^^^
4 | state: {},
5 | mutations: {},
6 | actions: {},
ERROR in src/views/Home.vue:12:20
TS2339: Property 'extend' does not exist on type 'typeof import("/Users/mi**/work/vue3-next-cli-plugin/node_modules/vue/dist/vue")'.
10 | import HelloWorld from "@/components/HelloWorld.vue"; // @ is an alias to /src
11 |
> 12 | export default Vue.extend({
| ^^^^^^
13 | name: "Home",
14 | components: {
15 | HelloWorld
一つずつ修正していきます。
src/**.vue 内を CompositionAPI に則した形で書く
component 内が Vue.extend
のままなので、修正します。こちらは問題なく終了。
createApp について
こちらは Vue3 での変更点となります。
変更点: GlobalAPI の再設計によって、createApp
が作成され、それによりアプリインスタンスのみにスコープされるようになりました。
自動で書き換えられていますが、型に関する変更を手動で行う必要があります。
shims-vue.d.ts
の変更
参考: https://github.com/vuejs/vue-next-webpack-preview/issues/5
調べると以下の方がより型に沿っているそうなのですが、今回はとりあえず上記 Issue で議論された内容で修正します。
参考: https://dev.to/lmillucci/building-a-vue-3-component-with-typescript-4pge
shims-vue.d.ts
を修正します。
- before
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
- after
declare module "*.vue" {
import { ComponentOptions } from "vue";
const component: ComponentOptions
export default component;
}
compile エラーは無くなりました。
vue-loader
こちらはエラー内容から依存関係がうまくいっていないような気がしたため、そこに推測を立て、yarn.lock
を確認しながら以下の方法で検証しました。
検証:
-
"vue-cli-plugin-vue-next": "~0.1.3"
を削除してインストールすると動く
- before:
yarn.lock
"vue-loader-v16@npm:vue-loader@^16.0.0-beta.3", vue-loader@^16.0.0-alpha.3:
name vue-loader-v16
version "16.0.0-beta.5"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.0.0-beta.5.tgz#04edc889492b03a445e7ac66e9226a70175ca8a0"
integrity sha512-ciWfzNefqWlmzKznCWY9hl+fPP4KlQ0A9MtHbJ/8DpyY+dAM8gDrjufIdxwTgC4szE4EZC3A6ip/BbrqM84GqA==
dependencies:
"@types/mini-css-extract-plugin" "^0.9.1"
chalk "^3.0.0"
hash-sum "^2.0.0"
loader-utils "^1.2.3"
merge-source-map "^1.1.0"
source-map "^0.6.1"
- after:
yarn.lock
"vue-loader-v16@npm:vue-loader@^16.0.0-beta.3", vue-loader@^16.0.0-alpha.3:
version "16.0.0-beta.5"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.0.0-beta.5.tgz#04edc889492b03a445e7ac66e9226a70175ca8a0"
integrity sha512-ciWfzNefqWlmzKznCWY9hl+fPP4KlQ0A9MtHbJ/8DpyY+dAM8gDrjufIdxwTgC4szE4EZC3A6ip/BbrqM84GqA==
dependencies:
"@types/mini-css-extract-plugin" "^0.9.1"
chalk "^3.0.0"
hash-sum "^2.0.0"
loader-utils "^1.2.3"
merge-source-map "^1.1.0"
source-map "^0.6.1"
2. 別にもう一つプロジェクトを立ち上げて yarn.lock
を削除、インストールして検証した結果、問題なく動いたためやはりうまく依存関係が解決できなかっただけかなと思います。
こちらに関して何かありましたらご意見ください。
vue-router
参考: https://github.com/vuejs/vue-router-next
RouteConfig
は RouteRecordRaw
に rename されるとあるので修正します。
src/router/index.ts
import { RouteRecordRaw, createRouter, createWebHistory } from "vue-router";
// 略
const routes: Array<RouteRecordRaw> = [
// 略
breaking changes の確認
-
mode: history
がhistory
に変更されます。こちらは以下の通りインストール時点で変換されていました。
src/router/index.ts
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
});
- 全ての route を示す
/*
はカスタム正規表現/:catchAll(.*)
を用いて宣言するようになるとのことなので、以下のように修正して確認します。
const routes: Array<RouteRecordRaw> = [
{
path: "/:catchAll(.*)",
name: "Home",
component: Home
},
];
BASE_URL/asdf
等 asdf
部分を良きように変えても Home
component が表示されればOKです。
params の取り扱いについて
params が global な root を通す必要が無くなったため、どのように取得できるのか確認します。
-
/src/router/index.ts
に以下のように追記
const routes: Array<RouteRecordRaw> = [
{
path: "/:catchAll(.*)",
name: "Home",
component: Home
},
{
path: '/account/:id', component: Account // 追記
},
{
path: "/about",
name: "About",
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue")
}
];
-
src/components/Account.vue
を作成
template 内では従来通りに取得できます。
<template>
{{ $route.params.id }}
</template>
setup 内では以下のようにして取得することができました。
<script lang="ts">
import { defineComponent } from 'vue';
import { useRouter } from 'vue-router';
import router from '@/router'
export default defineComponent ({
name: 'Account',
setup(props, context){
const { currentRoute } = router
console.log(currentRoute.value.params.id)
}
})
</script>
ただ、こちらは検証不十分のため、ベストプラクティスかわからず...
近い内にもう少し掘り下げたいと思います。
Vuex
参考: https://github.com/vuejs/vuex/tree/4.0#vuex-4
breaking changes として、 Vuex のインストールプロセスが変更になり、 createStore
関数を使用することになった、とのことなので修正します。
src/store/index.ts
import { createStore } from "vuex";
export default createStore({
state: {},
mutations: {},
actions: {},
modules: {}
});
ここまでで compile エラーで出ていた箇所の修正は完了ですが、TS で使用する場合には独自にモジュール拡張を宣言する必要があるとのことなので、ドキュメント通りに修正しました。
- vuex-shim.d.ts
import { ComponentCustomProperties } from "vue";
import { Store } from "vuex";
declare module "@vue/runtime-core" {
interface State {
}
interface ComponentCustomProperties {
$store: Store<State>;
}
}
今回の breaking changes で、 Vue component 内でのグローバルな型付の削除が行われたため、完全に型付された構造を作ることができるようになりました。
debug をとって確かめるために、以下のように追加していきます。
vuex-shim.d.ts
import { ComponentCustomProperties } from "vue";
import { Store } from "vuex";
declare module "@vue/runtime-core" {
interface State {
count: number;
}
interface ComponentCustomProperties {
$store: Store<State>;
}
}
src/store/index.ts
import { createStore } from "vuex";
export default createStore({
state: {
count: 1
},
mutations: {},
actions: {},
modules: {}
});
src/components/index.ts
<script lang="ts">
import { defineComponent, SetupContext } from "vue";
import { useStore } from 'vuex';
export default defineComponent({
name: "HelloWorld",
props: {
msg: String
},
setup() {
const store = useStore()
console.log(store.state.count) // 1 が表示される
}
});
</script>
参考: https://blog.logrocket.com/whats-new-in-vuex-4/
以上となります。
Epilogue
今回は Vue3 を実装する上でどこから手をつければいいのか把握する、を目標に実際に手を動かして検証してみました。次回は vuejs/rfcs を触りつつもう少し広げて作ってみようと思います。
また実際触ってみて global にする必要がなくなった、という点を忘れてしまいどこに格納されている or どこから取得すればいいのか、と迷いましたが、スコープが小さくなったという点に気をつけ、Document を確認すれば特に困ることはあまりないのかな、と感じました。
ただ、Vue2 から Vue3 へ段階的に上げることができるのか、Vuex や vue-router の切替等、大きなプロジェクトの運用、進め方は やはり考慮しないといけないのか、と思います。
勉強途中のため、何かありましたらご連絡ください。
変更点:
20/09/13: タイトル分かりにくいので修正しました