如何在使用仅限运行时的 Vue 时配置 Vue 路由器



我正在尝试根据示例使用 vue-router,例如

let routes = [
{ path: '/',  component: MainComponent },
];
let router = new VueRouter({routes});
new Vue({  router  }).$mount('#app');

但我总是收到此错误:

vue.runtime.esm.js:619 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available.

我可以通过使用渲染函数来解决此问题吗? 我试过了

let routes = [];

但仍然失败了。

好的,我花了半天的时间,我终于让它工作了:vue-router + webpack + 仅运行时的 vue。

本教程是最有帮助的。 我学到了什么:

如果你使用 vue-cli,vue 版本在 webpack.base.conf 中.js

  • vue.esm.js将包含编译器
  • vue.runtime.esm.js 将不包括编译器

如果要使用运行时,则必须更改main.js不要使用这个

new Vue({
el: '#app',
router,
template: '<App/>',      //  <== This is bad
components: { App }
});

而是使用它

Vue.use(VueRouter);          // <== very important
new Vue({
router,
render(createElement) {
return createElement(App);
}
}).$mount('#app');

可以将$mountel:与运行时一起使用。两者都有效,但$mount为您提供了更大的灵活性。当然,router是以通常的方式创建的

let routes = [
{ path: '/', component: MainComponent },    
];
let router = new VueRouter({ routes }); 

如果您仍然看到错误

[Vue warn]: You are using the runtime-only build of Vue

在控制台中,请加倍确保永远不要在代码中使用任何带有字符串的模板。 即使在您的 *.vue 文件中,如果您尝试这样做

const Foo = { template: '<div>foo</div>' };

它会失败。相反,您必须使用<template>标记,否则必须使用createElement。 祝你好运!

接受的解决方案是正确的,因为你不能将字符串模板与运行时一起使用 Vue,你必须实现render函数。但是,如果要在顶层渲染组件而不是使用路由器视图,则可以获取匹配的组件并手动渲染它:

const routes = [
{ path: '/about', component: About },
{ path: '/index', component: App },
{ path: "*", component: App }
]
new Vue({
router,
render: h => {
return h(router.getMatchedComponents()[0])
},
}).$mount('#app')

基于这两个 MRE(一个有,一个没有运行时)似乎无法使用运行时。如果没有别的,如果你选择在他们的 github 或 vue 论坛上发布问题,或者另一个答案可以使用它们作为模板来证明我不正确,你可以使用这些片段。这假设你没有使用 vue-cli。使用 vue-cli,您需要选择将编译器包含在您的构建中。查看 https://cli.vuejs.org/config/#runtimecompiler 和 https://v2.vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only

失败(控制台警告 - vue 运行时)

let routes = [
{
path: "",
component: {
render(h) {
return h("div", "hello world");
}
}
}
];
let router = new VueRouter({ routes });
new Vue({ router }).$mount("#app");
<script src="https://unpkg.com/vue/dist/vue.runtime.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<router-view></router-view>
</div>

工作(无控制台警告 - 完整 vue)

let routes = [
{
path: "",
component: {
render(h) {
return h("div", "hello world");
}
}
}
];
let router = new VueRouter({ routes });
new Vue({ router }).$mount("#app");
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<router-view></router-view>
</div>

对于 Vue 3(这里使用 TypeScript),诀窍是使用h组件渲染函数作为设置函数的结果作为顶级组件,而不是默认createApp({})似乎被解释为模板。

所以我有:

const app = createApp({
setup() {
const component = computed((): Component => {
const res = router.currentRoute.value.matched
if (res.length > 0 && res[0].components)
return res[0].components.default
else
return Loading
})
return () => h(component.value)
}
})
...

vue-routerRouter在属性currentRoute.value.matched[0].components.default中公开了一个准备渲染的组件。请务必检查匹配项和要加载的组件(这也适用于使用() => import('path/to/Component.vue')导入的惰性组件)。

显然,路由器已集成到应用程序中,并且应用程序以这种方式安装,路由器是使用createRouter创建的:

...
const router = createRouter({
history: createWebHistory(),
routes: [
...
]
})
app.use(router)
app.mount('#app')

在索引注释中,不使用<router-view/>。可能是使用运行时编译器的唯一事情,请考虑将浪费空间作为文档中推荐的选项!根组件中为使其静态而付出的一点额外努力绝对是值得的。索引如下所示:

<!DOCTYPE html>
<html class="dark" data-theme="dark">
<head>
<meta charset="utf-8"/>
<title>Title</title>
<script type="module" src="/src/main.ts"></script>
</head>
<body>
<div id="app">
</div>
</body>
</html>

用 Vite 测试,允许有vue: 'vue/dist/vue.runtime.esm-bundler.js'.相当紧凑!

最新更新