Javascript Vue.js-在动态变量不存在时加载替代组件
我已经为此挣扎了几天,希望有一种优雅的方式来处理没有数据的动态URL 我有以下路线:Javascript Vue.js-在动态变量不存在时加载替代组件,javascript,vue.js,vuejs2,vue-router,Javascript,Vue.js,Vuejs2,Vue Router,我已经为此挣扎了几天,希望有一种优雅的方式来处理没有数据的动态URL 我有以下路线: const router = new VueRouter({ routes: [ {path: '/product/:slug', component: Product}, {path: '/404', component: PageNotFound, alias: '*'} ] }); 在Product组件中,我有一个products对象,并根据slug变量加载要显示的产品 我遇到
const router = new VueRouter({
routes: [
{path: '/product/:slug', component: Product},
{path: '/404', component: PageNotFound, alias: '*'}
]
});
在Product组件中,我有一个products对象,并根据slug变量加载要显示的产品
我遇到的问题是,URL是产品数据集中不存在的slug。我想加载PageNotFound组件,而不更新URL
这可能吗?在整个应用程序中有一个一致的404页面将是很好的,而且对于我来说,不必在产品表中重复使用v-if也是很好的
我最接近它的是:
if(!product) {
this.$router.replace({path: '/404', query: {product: this.$route.params.slug}});
}
但是,这会更新实际的URL,这不是很好的UX
有什么线索吗?如果查询没有返回结果,您可以有条件地在Product.vue中呈现PageNotFound组件,然后根本不必摆弄路由器。感谢Kyle为我指出了正确的方向,这就是我想到的 因为我有点不正统,使用服务器端组件和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>`
};
在上述内容中需要注意的事项:
数据是异步加载的,因此需要检查产品是否存在
PageNotFound组件加载到-这是PageNotFound的ES6:PageNotFound-Vue然后自动生成一个元素
然后,该元素有一个v-if,它会被触发。由于如果没有产品,第一个容器将不存在,因此只显示404组件
我并不是根据产品来做的,因为若产品数据仍然通过API加载,你们会看到404的闪光。
将URL参数作为道具是更好的做法,我将在某个时候这样做!
总之,这允许您在SPA单页应用程序中显示一致的404页面,同时使用动态路由维护URL。它允许您在不更新URL的情况下加载另一个组件或显示另一个组件,还允许您使用用于动态路由的通配符404
希望这一切都是有意义的,能在将来帮助别人,避免他们浪费4个小时的尝试、错误和谷歌搜索。是的,我有关键字和短语填充这个答案来帮助别人找到它…谢谢,凯尔!听起来很完美。如何在组件中加载组件?在您的组件中,您将导入组件文件,然后您将能够在模板中呈现它!更多关于这个:谢谢你的帮助,凯尔!我已经发布了我最后所做的回答。嘿,mikestreety,还有一件事要说:我不确定您是从另一个应用程序内部使用这个库,还是完全是Vue.js,但我建议不要尝试模仿React社区所鼓励的功能组件的想法。这里的情况不同。考虑下面的官方Vu.JS风格指南未来-它可能会使你的生活更轻松:对不起,Kyle。我不太明白你的意思?Vue似乎有功能组件——或者这不是你的意思?谢谢你的帮助!要利用这一点,您需要在Vue api中建立以下功能:true。就目前而言,您没有得到任何性能提升,也没有失去语法清晰性。此外,您还可以在产品组件中显示计算结果和数据,这意味着它不是无状态的。除非组件是无状态的,否则它不能也不应该正常工作。我强烈建议您坚持在单个.Vue文件中使用典型的和官方推荐的模板、脚本和样式标记结构。再次谢谢你,凯尔,我来看看。不幸的是,我不能在这个特定的项目中使用命令行编译器
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;
}
}
};