Vue 更改为数组而不更新 DOM

Vue changes to array not updating the DOM

我正在尝试更改通过 Props 传递给子组件的父组件中的数组(插入和更新数据),但是 DOM 没有被更新。

父组件:

<UsersList
  v-for="(role, i) in userRolesNames"
  :key="i"
  :users="usersPages[i].data"
/>

子组件:

<template>
<div
  v-for="user in users"
  :key="user.id"
>
  <span>{{ user.name }}</span>
  <div>
    <i
      class="bi bi-pen-fill edit-icon m-pointer"
      @click="onClickEdit(user)"
    ></i>
    <i
      class="bi bi-trash-fill delete-icon ms-2 m-pointer"
      @click="onClickDelete(user)"
    ></i>
  </div>
</div>
</template>
<script lang="ts">
// recieving the array
props: {
  users: {
    required: true,
    type: Array as PropType<usersType[]>
  }
}
</script>

每个用户基本结构如下:

{
  id: x,
  name: 'x',
  email: 'x',
  login: 'x',
  role: x
}

问题是当尝试在 usersPages[i].data 数组中插入或更新记录时,DOM 没有改变。如果我使用 Vue 开发人员工具,数据会正确更改,但 DOM 不是。

尝试在数组上使用 push 方法插入但没有成功。唯一有用的是:

const newUser = response.data;
const page = this.usersPages[newUser.role - 1];
Vue.set(page, 'data', [...page.data, newUser]);

要更新,我尝试直接更改用户属性,但像插入一样,DOM 不会更新。有效的是:

const page = this.usersPages[user.role - 1];
const oldUsers = page.data.filter(u => u.id != user.id);
Vue.set(page, 'data', [ ...oldUsers, response.data ]);

有效但看起来不对...有人可以帮忙吗?

我之前遇到过类似的问题。我相信这是 vue 中的一个错误。原因是 Vue 已经渲染了 v-for。 Vue 目前还不知道如何处理数组中的变化。作为解决方法,我所做的是将脚本中的 updateKey 变量设置为 0。然后在每次更新数组 updateKey++ 时递增此变量。我们将此密钥用于我们的组件。

在子组件上,

<template>
<span
  v-for="user in users"
  :key="user.id"
>
  <div :key="updateKey">
    <span>{{ user.name }}</span>
    <div>
      <I
        class="bi bi-pen-fill edit-icon m-pointer"
        @click="onClickEdit(user)"
      ></i>
      <I
        class="bi bi-trash-fill delete-icon ms-2 m-pointer"
        @click="onClickDelete(user)"
      ></i>
    </div>
  </div>
</span>
</template>

onClickEdit(user)onClickDelete(user)确保你有updateKey++

DOM 不会更新,因为您没有进行被动更新。要反应性地更新此值,您应该监听一些事件(例如 input),您将在子组件中发出该事件并将新的(!)值传递给您的 属性。但更好的方法是通过 v-model.

绑定你的组件

P.S。 - 所以你可以看到 devtools 的变化,因为这不是 Vue 生命周期的一部分,它就像一个观察实际数据的解析器,但没有上下文。

我决定创建一个示例来向@peperoneen 展示我是如何做到的,因为我相信这种方法是正确的。但在示例本身中,它有效,而在我的项目中,它没有,唯一的区别是列表最初填充的方式。

为了加载用户,我向 API 请求返回分页数据,我通常使用“=”运算符分配这些数据。但是,我决定逐步进行分配,在用户部分,我使用了 'push' 方法。这样,使用 push 和 filter 的列表操作正常工作,更新 DOM 而无需使用 Vue.set

我认为问题出在生成列表的方式上。我想我并没有被动地这样做...