Vue.js - 当动态变量不存在时加载替代组件

时间:2017-10-02 19:58:42

标签: javascript vue.js vuejs2 vue-router

我几天来一直在努力解决这个问题,希望能够以优雅的方式处理没有数据的动态网址。

我有以下路线:

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,这不是很好的用户体验。

任何线索?

2 个答案:

答案 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: PageNotFound的ES6 - 然后Vue会自动生成<page-not-found></page-not-found>元素
  • 那个元素然后有一个v-if被触发。如果没有产品,第一个容器将不存在,只显示404组件
  • 我不是根据产品来做的,因为如果产品数据仍然通过API加载,您将获得404的闪光。
  • 将URL参数设置为propssee docs)是一种更好的做法,我将在某些时候进行此操作!

总而言之,这允许您在整个SPA(单页面应用程序)中显示一致的404页面,同时保持具有动态路由的URL。它允许您在不更新URL的情况下加载另一个组件或显示另一个组件,并且还允许您为动态路由设置通配符404。

希望一切都有意义,并在将来帮助某人,并避免浪费~4小时的试用,错误和谷歌搜索。 (是的,我有&#34;关键字&#34;并且短语填写了这个答案,以帮助有人找到它...)