根据 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
启动项目,就正常实现了 路由
功能。