【问题标题】:Preserve component state with vue-router?使用 vue-router 保留组件状态?
【发布时间】:2017-06-05 12:16:55
【问题描述】:

我有一个列表/详细信息用例,用户可以在其中双击产品列表中的项目,转到详细信息屏幕进行编辑,然后在完成后返回列表屏幕。我已经使用此处描述的动态组件技术完成了此操作:https://vuejs.org/v2/guide/components.html#Dynamic-Components。但是现在我打算在应用程序的其他地方使用 vue-router,我想重构它以使用路由。通过我的动态组件技术,我使用了保持活动来确保当用户切换回列表视图时,会出现与编辑前相同的选择。但在我看来,通过路由产品列表组件将被重新渲染,这不是我想要的。

现在,看起来可以将 router-view 包裹在 keep-alive 中,这可以解决一个问题,但会引入很多其他问题,因为我只希望该路由保持活动状态,而不是所有路由(目前我只使用一个顶级路由器视图)。 Vue 2.1 通过为路由器视图引入包含和排除参数显然已经解决了这个问题。但是我也不想这样做,因为必须在我的主页中预先声明所有应该或不应该使用保持活动的路由似乎很笨拙。在配置路由时(即在路由数组中)声明是否要保持活动状态会更整洁。那么我最好的选择是什么?

【问题讨论】:

    标签: vue.js vue-router


    【解决方案1】:

    您可以指定要保持活动的路由,例如:

    <keep-alive include="home">
      <router-view/>
    </keep-alive>
    

    在这种情况下,只有本地路由会保持活动状态

    【讨论】:

    • 这个答案似乎没有引起注意,但看起来很简单,它工作正常!
    • 注意这里使用的home指的是组件定义中给出的名称。
    【解决方案2】:

    Vue 3

    <router-view v-slot="{ Component }">
      <keep-alive>
        <component :is="Component" />
      </keep-alive>
    </router-view>
    

    完全一样,您不需要 App.vue 中的 Component 属性。即使您的组件没有指定 name 属性,您的 this 也可以工作。

    【讨论】:

    • 你是真正的 MVP
    【解决方案3】:

    我遇到了类似的问题并查看了 Vuex,但我认为它需要在我的代码中进行太多更改/添加才能添加到项目中。

    我找到了这个库https://www.npmjs.com/package/vue-save-state,它为我解决了这个问题,使 1 个组件的状态与 localStorage 保持同步,并且只花了几分钟和几行代码(全部记录在包的 Github 页面中) )。

    【讨论】:

      【解决方案4】:

      一个没有 localStorage 的解决方案:

      import {Component, Provide, Vue} from "vue-property-decorator";
      
      @Component
      export default class Counter extends Vue {
        @Provide() count = 0
      
        /**
         * HERE
         */
        beforeDestroy() {
          Object.getPrototypeOf(this).constructor.STATE = this;
        }
      
        /**
         * AND HERE
         */
        beforeMount() {
          const state = Object.getPrototypeOf(this).constructor.STATE;
          Object.entries(state || {})
              .filter(([k, v]) => /^[^$_]+$/.test(k) && typeof v !== "function")
              .forEach(([k]) => this[k] = state[k]);
        }
      }
      

      【讨论】:

        【解决方案5】:

        在我看来,您正在寻找某种state management。如果您有多个组件共享的数据,并且您想以不同的顺序呈现组件,但不想为每个组件再次加载数据。

        它的工作原理如下:

        Vue 提供了simple state management,但我会推荐使用Vuex,这是 Vue 社区中状态管理的标准。

        【讨论】:

        • 当然,我知道使用两个组件外部的存储,我可以保留列表组件的状态,然后在返回时“重构”它。但是我需要保留很多数据,而不是所有数据都是实际组件数据的一部分(例如,表格中的滚动位置)。我希望有一些巧妙的方法可以避免重新渲染它。
        • @JohnMoore 你找到解决方案了吗?我有同样的问题。
        • 我最终做的是隔离我需要在不同视图之间保留的信息,并将其作为“workingProductData”存储在 Vuex 商店中。比理想更繁琐,但它确实有效。我在另一个项目中采用的一个更简单的解决方案是将详细视图和列表视图作为同一组件的一部分,根据状态中的“editMode”属性进行切换,使用 v-if/v-else。
        • Vuex 并不总是答案,因为它增加了你可能不需要的自以为是的复杂性。如果你有一个复杂的组件状态,那么以“Vuex 方式”保持 Vuex 更新是很多突变垃圾邮件,这主要是样板......
        • Vuex 用于应用程序状态管理。但这里需要 ui 状态管理(例如过滤器或应用于列表的顺序)。这个状态应该与路由相关联,但不幸的是 vue-router 不提供这样的功能。
        猜你喜欢
        • 1970-01-01
        • 2017-05-18
        • 2016-07-05
        • 1970-01-01
        • 2018-06-12
        • 2016-03-13
        • 2023-03-06
        • 2023-03-20
        • 2019-02-28
        相关资源
        最近更新 更多