Vue.js - 当动态变量不存在时加载替代组件
Vue.js - Loading alternative component when dynamic variable does not exist
几天来我一直在努力解决这个问题,希望有一种优雅的方式来处理没有数据的动态 URLs。
我有以下路线:
const router = new VueRouter({
routes: [
{path: '/product/:slug', component: Product},
{path: '/404', component: PageNotFound, alias: '*'}
]
});
在 Product
组件中,我有一个产品对象,根据 slug
变量,加载要显示的产品。
我遇到的问题是 URL 是产品数据集中不存在的 slug。我想加载 PageNotFound
组件,而不更新 URL.
这可能吗?在整个应用程序中拥有一致的 404 页面会很好,而且对我来说也有好处,不必在产品 table.
中重复使用 v-if
我最接近的是:
if(!product) {
this.$router.replace({path: '/404', query: {product: this.$route.params.slug}});
}
然而,这更新了实际的 URL 这不是很好的用户体验。
有什么线索吗?
如果查询 returns 没有结果,您可以在 Product.vue
中有条件地呈现您的 PageNotFound 组件,然后根本不必 fiddle 使用您的路由器。
感谢 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.js
文件在我的产品组件之前加载到 HTML 中,因此我能够执行以下操作:
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: PageNotFound
的 ES6 - Vue 然后自动创建一个 <page-not-found></page-not-found>
元素
- 然后该元素有一个被触发的 v-if。由于第一个容器没有产品就不存在,所以只显示404组件
- 我不会根据产品执行此操作,因为如果产品数据仍在通过 API.
加载,您会看到 404 的闪光灯
- 更好的做法是将 URL 参数设置为
props
(see docs),我将在某个时候这样做!
总而言之,这允许您在整个 SPA(单页应用程序)中显示一致的 404 页面,同时使用动态路由维护 URLs。它允许您在不更新 URL 的情况下加载另一个组件或显示另一个组件,还可以让您拥有动态路由的通配符 404。
希望一切都有意义,并在未来帮助某人,避免他们浪费 ~4 小时的试验、错误和谷歌搜索。 (是的,我有 "keyword" 和短语填充这个答案以帮助别人找到它...)
几天来我一直在努力解决这个问题,希望有一种优雅的方式来处理没有数据的动态 URLs。
我有以下路线:
const router = new VueRouter({
routes: [
{path: '/product/:slug', component: Product},
{path: '/404', component: PageNotFound, alias: '*'}
]
});
在 Product
组件中,我有一个产品对象,根据 slug
变量,加载要显示的产品。
我遇到的问题是 URL 是产品数据集中不存在的 slug。我想加载 PageNotFound
组件,而不更新 URL.
这可能吗?在整个应用程序中拥有一致的 404 页面会很好,而且对我来说也有好处,不必在产品 table.
中重复使用v-if
我最接近的是:
if(!product) {
this.$router.replace({path: '/404', query: {product: this.$route.params.slug}});
}
然而,这更新了实际的 URL 这不是很好的用户体验。
有什么线索吗?
如果查询 returns 没有结果,您可以在 Product.vue
中有条件地呈现您的 PageNotFound 组件,然后根本不必 fiddle 使用您的路由器。
感谢 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.js
文件在我的产品组件之前加载到 HTML 中,因此我能够执行以下操作:
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: PageNotFound
的 ES6 - Vue 然后自动创建一个<page-not-found></page-not-found>
元素 - 然后该元素有一个被触发的 v-if。由于第一个容器没有产品就不存在,所以只显示404组件
- 我不会根据产品执行此操作,因为如果产品数据仍在通过 API. 加载,您会看到 404 的闪光灯
- 更好的做法是将 URL 参数设置为
props
(see docs),我将在某个时候这样做!
总而言之,这允许您在整个 SPA(单页应用程序)中显示一致的 404 页面,同时使用动态路由维护 URLs。它允许您在不更新 URL 的情况下加载另一个组件或显示另一个组件,还可以让您拥有动态路由的通配符 404。
希望一切都有意义,并在未来帮助某人,避免他们浪费 ~4 小时的试验、错误和谷歌搜索。 (是的,我有 "keyword" 和短语填充这个答案以帮助别人找到它...)