Vuex getter filteredUsers 未在 dom 中重新激活,但在控制台中重新激活

Vuex getter filteredUsers not reactiv in dom but in console

这里有一个奇怪的问题。可能是因为我不太了解吸气剂是如何工作的。

我尝试更新我从 jsonplaceholder 获取的用户列表。 当我在输入字段中搜索用户时,应该会触发列表更新。

用于可视化的快速 gif:

这是我的组件:

<template>
  <v-app>
    <div class="mt-2 ml-2">
      <v-btn
        color="info"
        x-small
        @click="fetchUsers()"
      >
        Reset All
      </v-btn>
    </div>
    <add-user />
    <v-text-field
      v-model="search"
      class="mt-5 px-3"
      label="Search"
      required
      dense
      style="width: 300px"
      @input="filteredUsers(search)"
    />
    <ul
      class="mt-1 px-3"
      style="list-style: none"
    >
      <li
        v-for="(user, userIndex) in users"
        :key="user.id"
      >
        <ul
          class="pl-0"
          style="list-style: none"
        >
          <li
            v-for="(value, key, index) in user"
            :key="index"
          >
            <b>{{ key }}:</b> {{ value }}
          </li>
          <v-btn
            x-small
            color="error"
            class="my-2"
            @click="deleteUser(userIndex)"
          >
            Delete
          </v-btn>
        </ul>
        <hr>
      </li>
    </ul>
  </v-app>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';
import AddUser from '@/components/AddUser';
export default {
  name: 'App',
  components: {
    AddUser,
  },
  data: () => ({
    search: '',
  }),
  computed: {
    ...mapGetters(['userWithId', 'users', 'filteredUsers']),
  },
  created() {
    this.fetchUsers();
  },
  methods: {
    ...mapActions(['deleteUser', 'fetchUsers']),
  },
};
</script>

这是我的商店:

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    users: [],
  },
  getters: {
    users: (state) => {
      return state.users
    },
    userWithId: (state) => (id) => {
      return state.users.filter((user) => user.id === id)
    },
    filteredUsers: (state, getters) => (search) => {
      // CONSOLE
      console.log(
        getters.users.filter((user) =>
          user.name.toLowerCase().includes(search.toLowerCase())
        )
      )
      // SHOULD DOM UPDATE
      return getters.users.filter((user) =>
        user.name.toLowerCase().includes(search.toLowerCase())
      )
    },
  },
  mutations: {
    loadUsers(state, payload) {
      state.users = payload
    },
    deleteUser(state, id) {
      state.users.splice(id, 1)
    },
    addUser(state, payload) {
      state.users.push(payload)
    },
    deleteAllExceptOne(state, id) {
      return state.users.filter((user) => user.id === id)
    },
  },
  actions: {
    fetchUsers(context) {
      axios
        .get('https://jsonplaceholder.typicode.com/users')
        .then((res) => {
          const users = res.data
          users.forEach((user) => {
            delete user.address
            delete user.company
            delete user.phone
            delete user.website
          })
          context.commit('loadUsers', users)
        })
        .catch((err) => {
          console.log(err)
        })
    },
    deleteUser(context, userId) {
      axios
        .delete(`https://jsonplaceholder.typicode.com/users/${userId}`)
        .then(() => {
          context.commit('deleteUser', userId)
        })
        .catch((err) => {
          console.log(err)
        })
    },
    addUser(context, user) {
      axios
        .post('https://jsonplaceholder.typicode.com/users')
        .then((res) => {
          user.id = res.data.id
          context.commit('addUser', user)
        })
        .catch((err) => {
          console.log(err)
        })
    },
  },
  modules: {},
})

如果我没理解错的话,你想在搜索输入下方显示过滤后的用户列表,对吧?

似乎错误是您在 users 而不是 filteredUsers 上迭代来创建列表。

也许这对你有用:

<template>
  <v-app>
    ...
    <v-text-field
      v-model="search"
      class="mt-5 px-3"
      label="Search"
      required
      dense
      style="width: 300px"
    />
    <ul
      class="mt-1 px-3"
      style="list-style: none"
    >
      <li
        v-for="(user, userIndex) in filteredUsers(search)"
        :key="user.id"
      >
     ...
  </v-app>
</template>

另一个建议是在您的组件中制作 filteredUsers 一个计算 属性 并将其从您的商店中删除。它看起来像这样:

<template>
  <v-app>
    ...
    <v-text-field
      v-model="search"
      class="mt-5 px-3"
      label="Search"
      required
      dense
      style="width: 300px"
    />
    <ul
      class="mt-1 px-3"
      style="list-style: none"
    >
      <li
        v-for="(user, userIndex) in filteredUsers"
        :key="user.id"
      >
     ...
  </v-app>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';
import AddUser from '@/components/AddUser';
export default {
  name: 'App',
  components: {
    AddUser,
  },
  data: () => ({
    search: '',
  }),
  computed: {
    ...mapGetters(['userWithId', 'users']),
    filteredUsers () {
      return this.users.filter((user) =>
        user.name.toLowerCase().includes(this.search.toLowerCase())
      )
    }
  },
  created() {
    this.fetchUsers();
  },
  methods: {
    ...mapActions(['deleteUser', 'fetchUsers']),
  },
};
</script>