Vue 3のbeta版がリリースされて、あわせて周辺ツールがalphaからbetaへ作業中とのことだったのでvue-router動くかなと思ってやってみた。
github.com
github.com
以下素振りりぽじとり
github.com
プロジェクトのセットアップ
必要なものを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
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')
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$/,
exclude: /node_modules|vue\/src/,
use: [
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
transpileOnly: true,
},
},
],
},
{
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
適当にエイリアスの設定とかもしておく。
package.jsonに開発鯖起動用のスクリプト書く。
"scripts": {
"dev": "webpack-dev-server --mode=development",
}
これでsrc/main.tsをエントリポイントとしてサーバーが立ち上がるようになるはず。
composition api + vue-router
viewsにindex.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 lang="ts">
import { defineComponent } from 'vue'
import { useAppConfig } from '~/views/useAppConfig'
import { useRouter } from 'vue-router'
export default defineComponent({
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 lang="ts">
import { defineComponent } from 'vue'
import { useRouter } from 'vue-router'
export default defineComponent({
name: 'Sub',
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はなんか動かなかった。あまり追えてない。
github.com