【问题标题】:Select all chekboxes by $emit doesn't re-renders view - Vuejs通过 $emit 选择所有复选框不会重新渲染视图 - Vuejs
【发布时间】:2019-03-27 17:44:49
【问题描述】:

案例 - 需要在更改标题复选框时选择/取消选择所有复选框。

问题 - 我可以发出和接收事件。可以看到我修改后的数据数组。但我猜一些反应在 Vue 中不起作用。

我已经在 CodeSandbox - https://88nz9z64j0.codesandbox.io/ 上列出了非常小的示例。

代码 -

https://codesandbox.io/s/88nz9z64j0

注意 - 这与 Array 突变有关。因为我可以选择单个复选框,并且在全部选中后可以看到我的标题复选框标记为选中。然而,反向并不是通过相同的机制发生的。好奇怪!

必须向Array(100).fill(length) 学习作为反应数据,否则我在做一些愚蠢的事情。

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    问题在于Array.fill 正在就地修改数组。 Vuecan't detect changes to an array when you directly modify its elements。您需要先使用split创建一个新数组,修改新创建的数组,然后重新分配。

    this.checkSelections = this.checkSelections.splice(0).fill(allSelected);
    

    CodeSandbox

    【讨论】:

    • 也许使用Vue.set函数更好,不需要总是创建新数组,使用vue.set你可以在现有数组中以反应方式修改元素,减少开销,当然对于大型数组...请参阅我在 vue.set 上的回答
    • @Ben 我注意到Vue.sethit and miss 的事情。创建新的数组/对象似乎可以保证所有情况下的反应性。但无论如何,如果Vue.set 在某种情况下有效,您绝对可以使用它。
    • 确实如此,但也许只看Vue网站的官方信息:vuejs.org/v2/guide/reactivity.html,在vuejs.org/v2/guide/list.html#Caveats上确实有关于这两种方法的话题,在这种情况下,我认为我们没有修改数组的长度,所以注意1:vue.set的解决方案,当数组长度变化时需要拼接解决方案
    • 感谢您将我带到那里的文档。您和关于突变的解释似乎是合理的。然而,作为一般实践,我总是创建新的副本,因为我来自 React 背景。所以当它不工作时,我试过这个` const newArr = Array(this.data.length).fill(allSelected); this.checkSelections = newArr; ` 还是不行。
    • @kushalvm 在我看来它确实有效。 See this sandbox.
    【解决方案2】:

    在 table/index.vue 上的挂载函数上,您可以在更改数组后使用 this.$forceUpdate(),因为 vue 看不到更改。

    mounted() {
      this.$root.$on("selectAll", ({ allSelected }) => {
        console.log("selectAll index.vue", allSelected);
        this.checkSelections = this.checkSelections.fill(allSelected);
        console.log("selectAll", this.checkSelections);
        this.$forceUpdate(); 
      });
    }
    

    您可以在the documentation查看更多详情

    Working example

    【讨论】:

      【解决方案3】:

      你应该查看这篇关于 vue 反应性的文章和它的陷阱https://medium.com/js-dojo/reactivity-in-vue-js-and-its-pitfalls-de07a29c9407,以及某些关于数组的部分。

      对于数组,你最好使用 Vue.set

      见分叉:https://codesandbox.io/s/m7xqk9qn0j

       for(var i = 0; i <= this.checkSelections.length; i++)
       {
            Vue.set(this.checkSelections, i , allSelected);
       }
      

      详细信息也可以在vue官网找到: https://vuejs.org/v2/guide/list.html#Caveats (在这种情况下,数组的长度不会改变,所以要注意1)

      【讨论】:

      • 选择所有复选框时,不会在您的 fork 中选中标题复选框。加上每次迭代都重新赋值,会不会比一次性重新赋值整个数组效率低?
      猜你喜欢
      • 1970-01-01
      • 2019-02-18
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      相关资源
      最近更新 更多