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>
这里有一个奇怪的问题。可能是因为我不太了解吸气剂是如何工作的。
我尝试更新我从 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>