繁体   English   中英

如何改变基于Vue“prop”计算的数组?

[英]How to mutate the array which has been computed based on Vue "prop"?

来自 Vue 文档:

prop 作为需要转换的原始值传入。 在这种情况下,最好使用 prop 的值来定义计算属性。

资源

如果这个“道具”是对象数组怎么办? 我试图根据文档将其转换为计算数组。 但是那怎么变异呢?

在下面的示例中,组件接受项目Array<{ ID: string, lettering: string; }> Array<{ ID: string, lettering: string; }> 组件为每个项目呈现按钮。

  1. 当我们点击按钮时,它必须改变颜色。
  2. 如果我们再次单击相同的按钮,它必须返回到初始 state。

在此处输入图像描述

小提琴

<template>
  <div>
    <button  
      v-for="(item, index) in selectableItems"
      :key="`BUTTON-${item.ID}`"
      :class="{ selected: item.selected }"
       @click="() => {onButtonClicked(item, index) }"
    > {{ item.lettering }}
    </button>
  </div>  
</template>

我从items计算selectableItems 除了item的属性外, selectableItems还具有selected属性。

export default {
  name: "HelloWorld",
  props: {
    items: Array
  },
  computed: {
    selectableItems: function () {
      const selectableItems = [];
      this.items.forEach((item) => {
        selectableItems.push({
          ID: item.ID,
          lettering: item.lettering,
          selected: false
        });
      });
      return selectableItems;
    }
  },
  methods: {
    onButtonClicked: function(item, index) {
      if (item.selected) {
        this.selectableItems[index].selected = false;
      } else {
        this.selectableItems[index].selected = true;
      }
      console.log(this.selectableItems);
    }
  }
};

目前,Vue 不会重新渲染按钮。

我知道 getter 的 mutate 使用不当。 但是我应该如何改变数组呢?

禁止解决方案

传递{ ID: string, lettering: string; selected: boolean; } { ID: string, lettering: string; selected: boolean; } { ID: string, lettering: string; selected: boolean; }通过props而不是{ ID: string, lettering: string; } { ID: string, lettering: string; }是不允许的。 { ID: string, lettering: string; } { ID: string, lettering: string; }是纯model,肯定不知道UI。 selected: boolean; 仅适用于 UI。

这是 jsfiddle https://jsfiddle.net/hgvajn5t/中的一个简单示例

由于我的时间不够,我跳过了创建两个组件并实际上将数据作为道具进行。

关键是在数据中定义您选择的按钮

data () {
    return {
      selectedItems: []
    }
},

第二部分是存储哪些项目被选中,哪些没有

onButtonClicked: function(item){
  let index = this.selectedItems.indexOf(item.ID)
  if (index > -1) {
    this.selectedItems.splice(index, 1)
  } else {
    this.selectedItems.push(item.ID)
  }
}

onButtonClicked 将项目作为输入接收并检查它是否存在于您的 selectedItems 中 - 如果存在,它将被删除,否则将被添加

最后一部分是更改您的绑定以设置选定的 class

:class="{ selected: selectedItems.indexOf(item.ID) > -1 }"

再次在这里 - 只需检查它是否是 selectItems 的一部分

然后,您可以删除您的计算属性并简单地使用道具循环遍历元素。

重要提示:这仅在您的项目 ID 值是唯一的情况下才有效。

关于这个的一些一般想法:当你刚接触 vue 时,这个概念可能有点难以理解,因为对于简单的 select 状态来说,它似乎非常复杂。 这对于我提供的解决方案可能是正确的——但总体而言,这在很大程度上取决于您如何构建您的 UI。 这一切的主要原因是你不应该直接操纵道具。 使用计算道具来增强它们是好的 - 操纵计算道具同样糟糕。 If you need the select state outside your current component you will need to think about using events to emit the click on a button to the parent (where the data comes from) and change the select state directly there. 然后它将直接通过 props 传递。 这是更“自然”的方式,因为您可以操纵单一事实来源,而不是在另一个屏幕中保存有关项目的附加信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM