vue3 动态编译组件失败:Component provided template option but runtime compilation is not supported in this build of Vue

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

官方解释

link

  • In-browser template compilation:
    • vue.runtime.esm-bundler.js (default) is runtime only, and requires all templates to be pre-compiled. This is the default entry for bundlers (via module field in package.json) because when using a bundler templates are typically pre-compiled (e.g. in *.vue files).
    • vue.esm-bundler.js: includes the runtime compiler. Use this if you are using a bundler but still want runtime template compilation (e.g. in-DOM templates or templates via inline JavaScript strings). You will need to configure your bundler to alias vue to this file.
posted on 2024-03-23 21:50  HorseShoe2016  阅读(552)  评论(0编辑  收藏  举报