Vue 3のbeta版がリリースされて、あわせて周辺ツールがalphaからbetaへ作業中とのことだったのでvue-router動くかなと思ってやってみた。
以下素振りりぽじとり
プロジェクトのセットアップ
必要なものをyarn addする。
yarn add vue@next vue-router@next
あと開発用にいつもの。lint周りはお好みなので省略
yarn add -D webpack webpack-cli webpack-dev-server ts-loader vue-loader clean-webpack-plugin html-webpack-plugin typescript
webpackの設定書く
webpack.config.js
/* eslint-disable @typescript-eslint/no-var-requires */ const { resolve } = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const { VueLoaderPlugin } = require('vue-loader') const webpack = require('webpack') const outputPath = resolve(__dirname, 'dist') /** @type {import('webpack').ConfigurationFactory} */ const config = (env = {}) => ({ mode: env.prod ? 'production' : 'development', devtool: env.prod ? 'source-map' : 'inline-source-map', devServer: { contentBase: outputPath, historyApiFallback: true, hot: true, stats: 'minimal', }, output: { path: outputPath, publicPath: '/', filename: 'bundle.js', }, entry: [resolve(__dirname, 'src/main.ts')], module: { rules: [ { test: /\.ts$/, use: 'ts-loader', }, { test: /\.vue$/, use: 'vue-loader', }, ], }, resolve: { alias: { vue: '@vue/runtime-dom', '~': resolve('src'), }, extensions: ['.ts', 'd.ts', '.tsx', '.js', '.vue'], }, plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template: resolve(__dirname, 'src/index.html'), }), new CleanWebpackPlugin(), ], }) module.exports = config
適当にエイリアスの設定とかもしておく。
"scripts": { "dev": "webpack-dev-server --mode=development", }
これでsrc/main.tsをエントリポイントとしてサーバーが立ち上がるようになるはず。
composition api + vue-router
viewsにindex.htmlを適当に用意。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Poketto</title> </head> <body> <div id="root"></div> </body> </html>
エントリポイントを定義する。従来とは若干apiが変わっているため注意。
createAppに<router-view />
が定義されているメインのコンポーネントを渡し、rootにマウントする。やっていることは今までのVueと同じ。
main.ts
import { createApp } from 'vue' import App from '~/App.vue' import { route } from '~/router' const app = createApp(App) app.use(route) app.mount('#root')
現時点でApp.vueもrouterもないので定義していく。
App.vue
<script> export default { name: 'App', } </script> <template> <div> <router-view /> </div> </template>
ページコンポーネントを定義する。
今回はカレントパスとなるindex.vueとサブページsub.vueを作る。なんか表示したかったので適当にcomputedを利用したreadonlyなデータを吐く関数も用意した。(useAppConfig)
vue-routerは既存のthis.$route
からのアクセスではなくなり、useRouter
というnamed exportされている関数を用いることでjavascript側からhistoryの操作をすることができる。
router-link
は今まで通りに使えるが、特に型が効いたりはしない。
views/useAppConfig
import { computed } from 'vue' export const useAppConfig = computed(() => { return { name: 'poketto', version: '0.0.1', mode: process.env.NODE_ENV, } })
views/index.vue
<script> import { useAppConfig } from '~/views/useAppConfig' import { useRouter } from 'vue-router' export default { name: 'Index', setup() { const router = useRouter() const toSub = () => router.push({ name: 'sub' }) return { useAppConfig, toSub } }, } </script> <template> <div> <p>{{ useAppConfig.name }}</p> <p>{{ useAppConfig.version }}</p> <p>{{ useAppConfig.mode }}</p> <router-link :to="{ name: 'sub' }"> to sub link </router-link> <div> <button @click="toSub"> to sub button </button> </div> </div> </template>
views/sub.vue
<script> import { useRouter } from 'vue-router' export default { name: 'Index', setup() { const router = useRouter() const toHome = () => router.push({ path: '/' }) return { toHome, } }, } </script> <template> <div> <p>Sub Page</p> <router-link :to="{ path: '/' }"> home </router-link> <div> <button @click="toHome"> to sub button </button> </div> </div> </template>
routerの定義。
useRouter
と同様に、新しくrouter作成用の関数などがnamed exportされるようになっているため、これらを使う。
router.ts
import { createRouter, createWebHistory } from 'vue-router' import Index from '~/views/index.vue' import Sub from '~/views/sub.vue' export const routerHistory = createWebHistory() export const route = createRouter({ history: routerHistory, routes: [ { path: '/home', redirect: '/', }, { path: '/', name: 'index', component: Index, }, { path: '/sub', name: 'sub', component: Sub, }, ], })
ここまでできたらyarn dev
で動作確認。
うごく
おわり
vue-routerはまだalphaなので大きくapiが変わる可能性もあるが、現時点ではちゃんと動作する。
別でフルtsxで書いてみたけどvue-routerはなんか動かなかった。あまり追えてない。