【问题标题】:Vue, is there a way to pass data between routes without URL params?Vue,有没有办法在没有 URL 参数的路由之间传递数据?
【发布时间】:2018-12-02 13:02:43
【问题描述】:

我正在寻找如何在两个单独的组件(不是父组件和子组件)之间秘密传递数据,而无需在我的 Vue2 应用程序中使用 URL 参数。这并不意味着我在传递秘密,而是我只是不希望用户看到它(仅出于 UI 考虑)。

我知道 Vue 有 Props 但它们是用来在父子组件之间传递数据的。 就我而言,我的 URL 会改变,但我不想通过可见参数传递数据。

有人声称使用没有 URL 参数 here 的道具,但我无法重现有效的解决方案(每次都未定义)。

我还检查了these 选项,但它们都使用我们知道可见的 URL 或查询参数。

一个丑陋的解决方案是将数据写入本地存储,然后在那里读取,但这会产生很多开销和复杂性(例如,如果我只希望这些数据被读取一次,等等)。

这个问题有更优雅的解决方案吗?

谢谢!

【问题讨论】:

  • vuex 存储会和本地存储有同样的复杂性问题。 vuex 生命周期也取决于页面刷新。如果路由器重定向到另一个视图,这不构成刷新和重置前一个视图中设置的任何内容吗?
  • JavaScript 路由器在更改路由时不应刷新页面,只需更新 url 和 state。我认为明智的做法是进行 api 调用并坚持在您的后端。它已经成为一件很正常的事情,并且没有 cookie 或会话那么尴尬(至少在大多数情况下)。
  • @ippi 谢谢。我将尝试使用 vuex 的开销。至于对后端进行 API 调用,我不确定你在这里的确切含义,但在这个用例中,对服务器进行单独的 API 调用是行不通的,它也会让脑部手术头痛:)
  • 好的!但是如果你的问题是在页面重新加载之间持久化数据,那么这不是 vuex 解决的问题(你仍然需要 localstorage 或其他一些存储来与 vuex 一起使用)。如果您的问题是让您的应用程序在路由更改时不刷新,那么这要么是网络服务器配置问题,要么是未正确设置 html5 历史模式(或未正确使用您的 url-hash)。

标签: javascript node.js vue.js vsprops


【解决方案1】:
  1. make props: true for the destination route -- 在路由器的 index.js 文件中

    {
      path: '/home',
      name: 'home',
      component: taskChooser,
      props: true,
      }
  1. 在组件中定义 props,例如 props: ['myprop'],-注意引号

  2. 将您要从源路由传递的变量复制到与您的道具同名的名称中 - 在本例中为 myprop

myprop = theVariableThatYouWantToPass

this.$router.replace({name:'home', params:{myprop}});

确保 prop 和变量的名称相同 - prop 用引号引起来。

它对我有用。

【讨论】:

  • 这不起作用,因为另一端的道具仍未定义。目前我正在使用this.myprop 访问道具,即使它是在router.replace 处定义的,它也给出了我的未定义。变量名和道具名相等。
  • 请参见第 2 点。在要接收 props 的组件中,必须定义 props。
  • 只需添加 props: ['myprop'], line above your data(){}
  • 为了完成这项工作,我不得不调整你的最后一行,使其在 JSON 的语法上完整 => this.$router.replace({name:'home', params:{ homeComponentPropertyName: currentComponentVariableName }});
  • 它适用于名称路由,但不适用于路径路由,细线。
【解决方案2】:

感谢@Mayank 为我指明了正确的方向。

这是对我有用的正确语法。

  1. 注意路由器索引中的props

    {
      path: '/componentPath',
      name: 'componentName',
      props: {
         header: true,
         content: true
      },
    }
    
  2. 在您要重定向到的组件中,将 props 定义如下:

    props: {
      myProperty: {
        type: <DATATYPE>
      },
    }
    
  3. 如下执行重定向:

    this.$router.push({
      name: 'componentName',
      params: {
        myProperty: <VARIABLE>
      }
    })
    
  4. 使用this. 约定从created 或在以后的生命周期事件中访问道具。

在这种情况下,变量名和属性名不必相同,因为它是一个简单的映射。无论如何,这种命名约定将是一个奇怪的设计选择。

【讨论】:

  • 如果您使用 vue 路由器导航到 /componentPath,这可行,但如果您只是将浏览器中的链接粘贴到您的路径,那么这些道具将不存在。
  • 要让它工作,你必须从this.$route.params而不是props获取它。不需要道具。
  • 谢谢@Rudy! this.$route.params 非常适合我!根本不需要添加道具
【解决方案3】:

我没有在 Vue 2 中测试过这个,但是在 Vue 3 中,你可以在点击链接时通过 props 传递一个字符串化的对象:

  1. props: true 添加到您的路线文件中,作为路线。

         {
             path: 'receipt',
             name: 'receipt',
             component: () => import('../pages/Receipt.vue'),
             props: true,
             beforeEnter(to, from, next) {
                 if (!to.params.receiptData) {
                     return next({
                         name: 'dashboard',
                         params: {
                             locale: from.params.locale ? from.params.locale : 'en',
                         },
                     });
                 }
    
                 return next();
             },
         },
    
  2. 包含您的字符串化对象作为router.push() 的参数。

        const receiptData = {
             transferType: 'default',
             recipient: receiver.value.name,
             referenceNumber: '#B3423424234',
             amountSent: formAmount,
             transferFee: 0,
         };
    
         router.push({
             name: 'receipt',
             params: {
                 receiptData: JSON.stringify(receiptData),
             },
         });
    
  3. 将 props 声明为组件中的实例数据。

     <script setup>
     import { computed } from 'vue';
    
     const props = defineProps({
       receiptData: {
           type: String,
           required: true,
       },
     })
     console.log('receiptData', props.receiptData);
    
     const parsedReceiptData = computed(() => JSON.parse(props.receiptData));
    
     </script>
    

我还没有测试过大小的上限,所以要小心传递一个巨大的对象,你会注意到我在路由上也显示了一个 beforeEnter 中间件,因为如果用户按 F5 来刷新页面,道具将丢失,因此在我的情况下,我将用户重定向到页面之外,因为收据仅供一次性使用。

【讨论】:

    猜你喜欢
    • 2021-11-30
    • 2015-03-30
    • 2021-12-12
    • 2015-03-31
    • 2020-06-01
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多