根據 vue3 官方文件 路由,寫了如下一個簡單的頁面來模擬路由的實現。
為了減少 *.vue
檔案的個數,在這個但頁面中,使用 defineComponent
透過 object 定義元件。
<script setup>
import { ref, computed, defineComponent } from 'vue'
const Home = defineComponent({
template: `<h1>Home</h1>`
})
const About = defineComponent({
template: `<h1>About</h1>`
})
const NotFound = defineComponent({
template: `<h1>404</h1>`
})
const routes = {
'/': Home,
'/about': About
}
const currentPath = ref(window.location.hash)
window.addEventListener('hashchange', () => {
currentPath.value = window.location.hash
})
const currentView = computed(() => {
return routes[currentPath.value.slice(1) || '/'] || NotFound
})
</script>
<template>
<div>
<ul class="list-none flex justify-start space-x-5">
<li><a href="#/">Home</a></li>
<li><a href="#/about">About</a></li>
<li><a href="#/non-existent-path">Broken Link</a></li>
</ul>
<component :is="currentView" />
</div>
</template>
<style scoped>
li a {
color: cornflowerblue;
}
h1 {
font-size: 2em;
font-weight: bold;
}
</style>
但是執行時,<ul>
元素正常渲染了,<component :is="currentView" />
動態元件卻沒有正常渲染;瀏覽器 console 報出如下 warning:
[Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".
at <Anonymous>
at <SimpleRouterView onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > >
at <KeepAlive>
at <RouterView>
at <App>
於是根據提示,在專案根目錄下的 vite.config.js 中,新增 alias 內容 vue: 'vue/dist/vue.esm-bundler.js'
如下:
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueDevTools from 'vite-plugin-vue-devtools'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), VueDevTools()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
vue: 'vue/dist/vue.esm-bundler.js'
}
}
})
再次 pnpm run dev
啟動專案,就正常實現了 路由
功能。