我几天来一直在努力解决这个问题,希望能够以优雅的方式处理没有数据的动态网址。
我有以下路线:
const router = new VueRouter({
routes: [
{path: '/product/:slug', component: Product},
{path: '/404', component: PageNotFound, alias: '*'}
]
});
在Product
组件中,我有一个产品对象,并根据slug
变量加载要显示的产品。
我遇到的问题是当URL是产品数据集中不存在的slug时。我想加载PageNotFound
组件,而不更新网址。
这可能吗?在整个应用程序中拥有一致的404页面会很不错,对我来说也不错,不必在产品表中重复v-if
。
我最接近的是:
if(!product) {
this.$router.replace({path: '/404', query: {product: this.$route.params.slug}});
}
但是,这会更新实际的URL,这不是很好的用户体验。
任何线索?
答案 0 :(得分:3)
如果查询没有返回任何结果,您可以有条件地在Product.vue
中呈现您的PageNotFound组件,然后根本不必摆弄您的路由器。
答案 1 :(得分:1)
感谢凯尔指出我正确的方向,这就是我想出来的。
因为我有点不正统并使用服务器端组件和JavaScript,我已经找到了我的页面未找到的组件 - 看起来像这样:
const PageNotFound = {
name: 'PageNotFound',
template: `<div>
<h1>404 Page Not Found</h1>
<p>Head back to the <router-link to="/">home page</router-link> and start again.</p>
</div>`
};
我确保在我的产品组件之前的HTML中加载了PageNotFound.js
文件,因此我能够执行以下操作:
const ProductPage = {
name: 'ProductPage',
template: `<div>
<div v-if="product"><h1>{{ product.title }}</h1></div>
<page-not-found v-if="notFound"></page-not-found>
</div>`,
components: {
PageNotFound
},
data() {
return {
notFound: false
}
},
computed: {
product() {
let product;
if(Object.keys(this.$store.state.products).length) {
product = this.$store.state.products[this.$route.params.slug];
if(!product) {
this.notFound = true;
}
}
return product;
}
}
};
上面要注意的事项:
PageNotFound: PageNotFound
的ES6 - 然后Vue会自动生成<page-not-found></page-not-found>
元素props
(see docs)是一种更好的做法,我将在某些时候进行此操作!总而言之,这允许您在整个SPA(单页面应用程序)中显示一致的404页面,同时保持具有动态路由的URL。它允许您在不更新URL的情况下加载另一个组件或显示另一个组件,并且还允许您为动态路由设置通配符404。
希望一切都有意义,并在将来帮助某人,并避免浪费~4小时的试用,错误和谷歌搜索。 (是的,我有&#34;关键字&#34;并且短语填写了这个答案,以帮助有人找到它...)