vue.js 在v-for中创建的v-select中管理v-model价值

qyzbxkaa  于 2023-11-21  发布在  Vue.js
关注(0)|答案(2)|浏览(170)

我有一个由v-for创建的成员表,一些用户可以根据他们的角色管理其他成员。我实现了一些检查,以防止一些角色干预,但检查的完整列表是在后端完成的。
管理是用v-select完成的,我希望能够恢复v-select选择,因为用户没有被授权执行此操作。
这是我一开始做的:

<template>
  <tr v-for="member in members" :key="member.username">
    <td>{{ member.username }}</td>
    <td>
      <v-select
        density="compact"
        hide-details="true"
        v-model="member.role"
        :items="dialog_roles"
        :item-props="itemProps"
        @update:modelValue="changeRole(member)"
      ></v-select>
    </td>
</template>

<script>
  export default {
    data: () => ({
      members: [
        {
          username: 'John',
          role: {
            role: 'owner',
            description: 'full access to the project, can delete it and can manage members'
          },
        },
        {
          username: 'Jane',
          role: {
            role: 'manager',
            description: 'full access to the project, and can manage members'
          },
        },
        {
          username: 'Joe',
          role: {
            role: 'collaborator',
            description: 'can view the project but not modify any content'
          },
        },
      ],
      dialog_roles: [
              {
                "role": "owner",
                "description": "full access to the project, can delete it and can manage members"
              },
              {
                "role": "manager",
                "description": "full access to the project, and can manage members"
              },
              {
                "role": "contributor",
                "description": "full access to the project, but cannot delete it"
              },
              {
                "role": "collaborator",
                "description": "can view the project but not modify any content"
              }
            ]
    }),
    methods: {
        itemProps(item) {
          return {
            title: item.role,
            subtitle: item.description,
          };
        },
        changeRole(member) {
          //make API call to change the role
          //if it was unauthorized, change back the role in the v-select
        },
    }
  }
</script>

字符串
为了能够在更新v-select时获得旧值和新值,我将v-model="member.role"移动到一个简单的:value=member.role.role,然后给予@update:modelValue="changeRole(member, $event)",其中member存储初始值,$event存储更新后的值。
现在我有了它,如果API调用有效,我如何应用这个更改,如果无效,我如何恢复它?

zvokhttg

zvokhttg1#

要在API调用有效时应用更改,并在无效时恢复更改,您可以更新Vue组件中的changeRole方法。

<template>
  <tr v-for="member in members" :key="member.username">
    <td>{{ member.username }}</td>
    <td>
      <v-select
        density="compact"
        hide-details="true"
        :value="member.role.role"  <!-- Use :value to bind the role.role value -->
        :items="dialog_roles"
        :item-props="itemProps"
        @update:modelValue="changeRole(member, $event)"
      ></v-select>
    </td>
  </tr>
</template>

<script>
export default {
  data: () => ({
    // Your data here
  }),
  methods: {
    // ...

    async changeRole(member, newRole) {
      const oldRole = member.role.role; // Store the old role
      member.role.role = newRole; // Update the local data immediately

      // Make an API call to change the role
      try {
        // Example: If your API call returns an error, you can handle it here
        // if (response.error) {
        //   member.role.role = oldRole; // Revert the role
        //   console.error('API call failed. Reverted role.');
        // }
      } catch (error) {
        // Handle API call errors here
        console.error('API call failed. Reverted role.');
        member.role.role = oldRole; // Revert the role
      }
    },
  },
};
</script>

字符串

monwx1rj

monwx1rj2#

首先,你还需要在for循环中传递索引。重要的是以后能够更新成员值。

<tr v-for="(member, index) in members" :key="member.username"

字符串
然后,您需要将索引传递给更改角色函数

changeRole(member, index)


现在,在这个函数中,你必须缓存最近更改的值。

// globally defined
let cachedValues = {
    member: null,
    index: null
};

changeRole(member, index) {
    cachedValues.member = member;
    cachedValues.index = index

    try {
      // make your api call
      // if unauthorized, throw error
    } catch {
      // change back values by taking them from cachedValues
    }
}


如果您已经想缓存更改之前的值,则可以在状态上保存成员数组的整个副本,该副本仅在提交成功后才更改。
示例实现:

<script>
  export default {
    data: () => ({
      autoChange: false,
      members: [
        {
          username: 'John',
          role: {
            role: 'owner',
            description: 'full access to the project, can delete it and can manage members'
          },
        },
        {
          username: 'Jane',$
          role: {
            role: 'manager',
            description: 'full access to the project, and can manage members'
          },
        },
        {
          username: 'Joe',
          role: {
            role: 'collaborator',
            description: 'can view the project but not modify any content'
          },
        },
      ],
      membersCache: [
        {
          username: 'John',
          role: {
            role: 'owner',
            description: 'full access to the project, can delete it and can manage members'
          },
        },
        {
          username: 'Jane',$
          role: {
            role: 'manager',
            description: 'full access to the project, and can manage members'
          },
        },
        {
          username: 'Joe',
          role: {
            role: 'collaborator',
            description: 'can view the project but not modify any content'
          },
        },
      ],
    }),
    methods: {
        itemProps(item) {
          return {
            title: item.role,
            subtitle: item.description,
          };
        },
        changeRole(member, index) {
            if (this.autoChange) return;
            try {
              // make your api call
              // if unauthorized, throw error
              // if authorized also adjust cached array and use $set to force reactivity
              this.$set(this.membersCache, index, member)
            } catch {
              // change back values by taking them from cachedValues
              const cachedMember = this.membersCache[index];
              this.autoChange = true;
              this.$set(this.members, index, cachedMember);
              const timeoutMs = 500;
              setTimeout(() => {
                this.autoChange = false;
              }, timeoutMs);
            }
        }
    }
  }
</script>

相关问题