问题描述
我们正在构建一个基于 Vue 和 Nuxt 的庞大网站,其中包含超过 25 种不同的页面类型,这些页面类型无法与 Vue Router 开箱即用的标准/:id 或/overview/:slug 逻辑匹配.
由于 slug-matching 不是一种选择,我们正在考虑以下解决方案:
- 用户访问页面/this-is-a-topic-page"
- 服务器调用返回 pageType 的 API
topicPage
topicPage
与 nuxt 页面相关WpTopicPage
- 我们在 Vue Router 的通配符实例中将
WpTopicPage
设置为我们的组件
代码如下:
导出函数 createRouter() {返回新路由器({模式:'历史',路线:[//1. 用户访问页面/this-is-a-topic-page"{name: '通配符',小路: '*',组件: *,//这应该是动态的beforeEnter: (to, from, next) =>{//2. 服务器调用返回pageType`topicPage`的APIthis.$axios.get(`/call-to-the-api?slug=${to.params.slug}`).then((res) => {//3.`topicPage`与nuxt页面`WpTopicPage`相关if(res.data.pageType === 'topicPage') {//4. 设置 `WpTopicPage` 作为我们的页面组件返回 WpTopicPage;}})},},],});}
以上显然行不通.有没有办法在 beforeEnter 函数中动态设置路由内的 component
?
这是可能的.我创建了一个
正如您在控制台日志中看到的那样 - 每次发生变化时,我们都会加载和安装随机组件.
We are building an enormous website based on Vue and Nuxt with over 25 different page types that cannot be matched with standard /:id or /overview/:slug logic that comes out of the box with Vue Router.
As slug-matching isn't an option, we are thinking about the following solution:
- User visits page "/this-is-a-topic-page"
- Server calls API that returns the pageType
topicPage
topicPage
relates to the nuxt pageWpTopicPage
- We set
WpTopicPage
as our component within our wildcard instance of Vue Router
This looks like the following in code:
export function createRouter() {
return new Router({
mode: 'history',
routes: [
// 1. User visits page "/this-is-a-topic-page"
{
name: 'wildcard',
path: '*',
component: *, // this should be dynamic
beforeEnter: (to, from, next) => {
// 2. Server calls API that returns the pageType `topicPage`
this.$axios.get(`/call-to-the-api?slug=${to.params.slug}`)
.then((res) => {
// 3. `topicPage` relates to the nuxt page `WpTopicPage`
if(res.data.pageType === 'topicPage') {
// 4. Set `WpTopicPage` as our Page component
return WpTopicPage;
}
})
},
},
],
});
}
The above obviously doesn't work. Is there a way to set the component
within a route dynamically in the beforeEnter function?
It's possible to do. I have created a codepen for you to test:
Here it is:
Vue.use(VueRouter);
let A = {
mounted() {
console.log('Mouted component A');
},
};
let B = {
mounted() {
console.log('Mouted component B');
},
};
let C = {
mounted() {
console.log('Mouted component C');
},
};
const router = new VueRouter({
mode: "hash",
routes: [
{
path: '*',
beforeEnter(to, from, next) {
let components = {
default: [A, B, C][Math.floor(Math.random() * 100) % 3],
};
to.matched[0].components = components;
next();
}
},
]
});
app = new Vue({
router,
el: '#app',
components: { A, B, C }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.2/vue-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<router-link :to="'/' + Math.random()">anything</router-link>
<router-view></router-view>
</div>
This is the output:
As you can see in the console logs - each time something changes we get random component loaded and mounted.
这篇关于全动态vue-router的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!