【问题标题】:Vue.js - Loading alternative component when dynamic variable does not existVue.js - 当动态变量不存在时加载替代组件
【发布时间】:2018-03-13 22:58:32
【问题描述】:

我已经为此苦苦挣扎了几天,并希望有一种优雅的方式来处理没有数据的动态 URL。

我有以下路线:

const router = new VueRouter({
  routes: [
    {path: '/product/:slug', component: Product},

    {path: '/404', component: PageNotFound, alias: '*'}
  ]
});

Product 组件中,我有一个产品对象,并根据slug 变量加载要显示的产品。

我遇到的问题是当 URL 是产品数据集中不存在的 slug 时。我想加载 PageNotFound 组件,而不更新 URL。

这可能吗?在整个应用程序中拥有一致的 404 页面会很好,而且我不必在产品表中重复使用 v-if 对我也有好处。

我最接近它的是:

if(!product) {
    this.$router.replace({path: '/404', query: {product: this.$route.params.slug}});
}

但是,这会更新实际的 URL,这不是很好的用户体验。

有什么线索吗?

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-router


    【解决方案1】:

    如果查询没有返回结果,您可以有条件地在 Product.vue 中呈现您的 PageNotFound 组件,然后根本不必摆弄您的路由器。

    【讨论】:

    • 谢谢,凯尔!这听起来很完美。我将如何在组件中加载组件?
    • 在您的<script> 中,您将导入组件文件,然后您就可以在模板中呈现它!更多信息在这里:laracasts.com/discuss/channels/vue/…
    • 感谢凯尔的帮助!已经发布了我最后所做的答案。
    【解决方案2】:

    感谢凯尔为我指明了正确的方向,这就是我想出的。


    因为我有点不正统并且使用服务器端组件和 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 然后自动创建一个 &lt;page-not-found&gt;&lt;/page-not-found&gt; 元素
    • 然后该元素有一个 v-if 被触发。如果没有产品,第一个容器将不存在,因此仅显示 404 组件
    • 我不是根据产品来做的,因为如果产品数据仍在通过 API 加载,你会得到一个 404 的闪现。
    • 最好将 URL 参数设置为 props (see docs),我将在某个时候这样做!

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

    希望这一切都有意义,并在未来帮助某人,并避免他们浪费大约 4 小时的试验、错误和谷歌搜索。 (是的,我有“关键字”和短语填充这个答案以帮助某人找到它......)

    【讨论】:

    • 嘿 mikestreety,还有一件事要说:我不确定你是从另一个应用程序内部使用这个库,还是它完全是 Vue.js,但我建议不要尝试模拟与 React 社区鼓励的功能组件的想法相同。他们在这里是不同的情况。考虑遵循官方的 Vue.js 风格指南——它可能会让你的生活更轻松:vuejs.org/v2/style-guide
    • 对不起,凯尔。我不太确定你的意思是什么?看来 Vue 确实有功能组件 - github.com/vuejs/vue/releases/tag/v2.0.0-alpha.5 或者这不是你的意思吗?感谢您的帮助!
    • 为了使用它,您需要在 Vue api 中建立 functional: true。就目前而言,您没有收到任何性能提升并且在语法清晰度方面有所损失。此外,产品组件中还存在计算和数据,这意味着它不是无状态的。除非您的组件是无状态的,否则它不能也不应该起作用。我强烈建议您在单个 .Vue 文件中坚持使用典型且官方推荐的 template, script, style 标签结构。 vuejs.org/v2/guide/render-function.html#Functional-Components
    • 再次感谢凯尔,我会读一读。不幸的是,我无法为这个特定项目使用命令行编译器
    猜你喜欢
    • 2016-08-31
    • 2020-12-09
    • 2020-06-29
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 2020-01-09
    • 2018-05-22
    相关资源
    最近更新 更多