【问题标题】:Not able to uncheck/check chekboxes on uncheck/check of header checkbox after individual checkboxes are interacted with - Vuejs与单个复选框交互后,无法在取消选中/选中标题复选框时取消选中/选中复选框 - Vuejs
【发布时间】:2018-10-24 06:27:36
【问题描述】:

情况 1 - 我检查了我的个人复选框,我的标题复选框被选中。这是方法 1,效果很好。

相同的代码

index.vue

<VCheckbox
 checked={this.checkSelections[idx]}
    nativeOnChange={e => {

    this.$set(this.checkSelections, idx, e.target.checked);
    let allSelected = true;
    for (let i = 0; i < this.checkSelections.length; i++) {
        allSelected = this.checkSelections[i];
        if (!allSelected) break;
    }
    this.$root.$emit("checkmarkHead", { allSelected });
    }}
/>

Head.vue

  mounted() {
    this.$nextTick(() => {
        this.$root.$on("checkmarkHead", ({ allSelected }) => {
        console.log("checkmarkHead", allSelected);
         this.allSelected = allSelected;
      });
    }

  },

情况 2 -

我检查了我的标题复选框,并且我的所有复选框都被选中了。反之亦然。所以与此对应的方法2也可以正常工作。

相同的代码 -

Head.vue

  <HeadItem>
    <VCheckbox
        checked={this.allSelected}
        nativeOnChange={e => {
        this.allSelected = e.target.checked;
        this.$root.$emit("selectAll", {
            allSelected: this.allSelected
        });
        }}
    />
</HeadItem>

index.vue

mounted() {
   this.$nextTick(() => {
        this.$root.$on("selectAll", ({ allSelected }) => {
        this.checkSelections = Array(this.sortedData.length).fill(allSelected);
     });
   });
 }

问题 - 当我在情况 1 之后执行情况 2 时,相同的方法无法按预期工作。视图未更新。同样,在情况 2 之后执行情况 1 也不起作用。

这里是链接

代码链接 - https://codesandbox.io/s/vmwy3v4203

在处理了所有突变警告等之后,我现在一无所知。

【问题讨论】:

  • 有人可以提到问题否决的问题吗?
  • 我认为这是您在上面的所有重复文本 :)
  • 我注意到,有人在 Codesandbox 的 head.vue 中更改了挂载函数中的行。很奇怪!因此,我所讨论的用例可能无法正常工作。在共享沙盒之前,我应该阅读更多关于编辑权限的信息。
  • 如果有人可以投票就好了。现在我确实冻结了这个问题。
  • @HusamIbrahim 什么重复的部分。我交叉检查了任何错误,但仍然无法弄清楚?除非您打算将双关语链接到上一个问题。

标签: javascript vue.js vuejs2


【解决方案1】:

我欠你一个道歉。这确实是另一个反应性问题,可以通过提供 key attribute 来解决。..

key 特殊属性主要用作 Vue 的提示 虚拟 DOM 算法在区分新列表时识别 VNode 对旧列表的节点。没有键,Vue 使用一种算法 最小化元素移动并尝试修补/重用 尽可能在原地使用相同的类型。使用键,它将重新排序 基于键的顺序变化的元素,以及带有键的元素 不再存在的将始终被删除/销毁。

您可以为元素分配唯一的key 值,如果更改将强制 Vue 重新渲染该元素。在您的情况下,您可以将键分配给您的 VCheckbox 元素等于它们的 checked 值,强制 Vue 在它们被选中/取消选中时重新渲染它们。例如..

<HeadItem>
  <VCheckbox
    key={this.allSelected}
    checked={this.allSelected}
    nativeOnChange={e => {
      this.$emit('change', !this.allSelected)
    }}
  />
</HeadItem>

我冒昧地将您的 allSelected 属性重写为计算属性,并删除了您在根实例上设置的事件侦听器。我认为这样更干净..

【讨论】:

  • 您确实为 allSelected 使用了计算的 getter/setter。标题复选框根据作为道具传递给 Head.vue 的计算值呈现。现在,当 head 复选框触发更改事件时,您已经使用了 $emit,但没有通过明确说 this.$root.$on('change', ...) 而是通过 onChange 函数作为 head.vue 组件的道具来捕获它。 Vuejs 如何在内部处理这个问题?我的意思是在 React 中,在这种情况下调用 this.props.onChange() 是明确的。
  • 第二,你使用了computed。 allSelected 的 Getter 将针对复选框的每个更改事件被触发。现在,如果我们只有两个显式的 getAllSelected 和 setAllSelected 方法,methods{} 会有什么不同?在这种情况下,计算会提供什么好处?
  • @kushalvm 对于某些观点,您可以参考this issue。但基本上当子组件使用$emit 时,父组件(在您的情况下为table 组件)可以使用v-ononChangeonInputonClick 等)在子实例上设置侦听器你使用 JSX)。调用$emit 时传递的任何其他参数都将传递给侦听器的回调函数。
  • 在您的实现中,您基本上将根实例用作事件总线,这在 Vue 中不是惯用的。它适用于您的简单情况,但问题是如果表组件被破坏,除非您专门调用 this.$root.$off('change'),否则不会删除事件侦听器。将此与 Vue automatically takes care of cleanup for you. 的另一种情况进行对比
  • 如果你有other components using a 'change' event on the root instance,你的实现也会导致问题。这使您的组件在同一棵树中无法重用,并迫使您考虑如何命名事件,以免引起冲突。将此与everything is nice and localized 的情况进行对比。
猜你喜欢
  • 2017-04-14
  • 2020-06-18
  • 1970-01-01
  • 2021-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多