我正在尝试根据示例使用 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');
可以将$mount
或el:
与运行时一起使用。两者都有效,但$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-router
的Router
在属性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'
.相当紧凑!