删除数据中的元素不会刷新 VueJS 中的键

Remove element in data doesn't refresh keys in VueJS

我正在尝试制作一个提供输入和颜色选择器的项目列表。它应该始终在列表末尾有一个空元素。

元素由存储在 data 中的对象填充。

一切正常,我做了一个简单的方法过滤空值的对象,然后添加一个新的。

但是,当用户在不是最后一个的元素上设置空值时:

这是我在父 Vue 上所做的:

addEmptyElement() {
  // now find any empty values
  this.values = this.values.filter((v) => v.length);
  // and append an empty one
  this.values.push("");
},

并且这些值用于绑定 Item 组件,如下所示:

<Item
  v-for="(v, i) in values"
  :key="i"
  v-bind:text="v"
  @valueChanged="onItemChanged"
/>

“valueChanged”事件由 Item 发出并提供列表中的位置和更改的值。

我创建了一个更简单的示例,您可以在此处查看:

https://codesandbox.io/s/vue-component-order-problem-rc4o1?file=/src/App.vue

给出一些精确度:

也许我做错了,执行不好,所以请告诉我我做错了什么:)

谢谢!

我觉得你看到的和documentation

中的这段比较有关系

When Vue is updating a list of elements rendered with v-for, by default it uses an "in-place patch" strategy. If the order of the data items has changed, instead of moving the DOM elements to match the order of the items, Vue will patch each element in-place and make sure it reflects what should be rendered at that particular index.

This default mode is efficient, but only suitable when your list render output does not rely on child component state or temporary DOM state (e.g. form input values).

这就是为什么在 v-for 中使用简单的 index 作为 key 是棘手的。最好不要依赖索引并维护自己的唯一性 id 即使它需要更多工作...

this.$.vnode.key 的用法也有异味...它没有记录在案 API 所以你绝对应该避免它,只需通过道具明确地传递 id

working exaple

...其他想法

就在我发布我的答案之后,我又意识到一件事......所以只是为了完整:

这可以很容易地与 v-for index 作为键一起使用。它对您不起作用的原因在于您的 <Item> 组件。您将 text 道具传递给 Item 组件。您使用 prop 的值 一次性初始化 valuedata 中使用 value 作为 v-model input.

重新呈现列表时会发生什么? Vue 为列表中的每个项目更新 text 属性,但是更新 对用作 v-model 的内部组件的 value 没有影响(所以它对 <input> 元素中显示的值没有影响)!!

解决方法是重写Item组件:

<template>
  <div>
    <input type="text" v-model="model" />
  </div>
</template>
<script>
export default {
  props: ["modelValue"],
  computed: {
    model: {
      get() {
        return this.modelValue;
      },
      set(evt) {
        this.$emit("update:modelValue", evt);
      },
    },
  },
};
</script>

...并更改 App.vue:

<Item
    v-for="(v, i) in values"
    :key="i"
    :modelValue="v"
    @update:modelValue="onItemChanged(i, $event)"
  />

正常工作 其余代码不变 - 2nd example