Вывести отфильтрованый список с помощью vuex
Есть такой небольшой проект: codesandbox
Список из постов и select фильтр.
Home.vue:
<b-form-select v-model="selected" :options="options"></b-form-select>
<ul v-for="post in getPostsFilter" :key="post.id">
<li>
{{ post.id }}
{{ post.completed }}
<b-form-checkbox v-model="post.completed">
I accept the terms and use
</b-form-checkbox>
{{ post.title }}
</li>
</ul>
import { mapActions, mapGetters } from "vuex";
export default {
name: "Home",
components: {
DefaultLayout,
},
data() {
return {
selected: this.$store.state.selected,
options: [
{
value: "all",
text: "All",
},
{
value: "completed",
text: "Completed",
},
{
value: "not_completed",
text: "Not completed",
},
],
};
},
computed: {
...mapGetters(["getPostsFilter"]),
},
methods: {
...mapActions(["fetchPosts"]),
},
mounted() {
this.fetchPosts();
},
};
</script>
store.js:
export default new Vuex.Store({
state: {
posts: [],
selected: "all"
},
getters: {
getPosts(state) {
return state.posts;
},
getPostsFilter(state) {
if (state.selected === "all") {
return state.posts;
}
if (state.selected === "completed") {
return state.posts.filter((p) => (p = p.completed));
}
if (state.selected === "not_completed") {
return state.posts.filter((p) => (p = !p.completed));
}
}
},
mutations: {
setPosts(state, payload) {
state.posts = payload;
}
},
actions: {
async fetchPosts({ commit, dispatch }) {
axios
.get(" https://jsonplaceholder.typicode.com/todos/?_limit=3")
.then((response) => {
this.commit("setPosts", response.data);
})
.catch((err) => {
console.log(err);
});
}
}
});
Вопрос: Как отображать отфильтрованый список при выборе в select completed\not_completed\all ?
Ответы (1 шт):
Автор решения: MoloF
→ Ссылка
Поправил ваш код.
Без объяснений сразу готовый рабочий вариант: codesandbox
Store.js.
Добавил в мутации и actions метод который изменяет status в объекте filter
export default new Vuex.Store({
state: {
posts: [],
filter: {
status: "all"
}
},
getters: {
getPosts(state) {
return state.posts;
},
getPostsFilter(state) {
const { posts, filter } = state;
if (filter.status === "all") return posts;
if (filter.status === "completed")
return posts.filter((post) => !!post.completed);
if (filter.status === "not_completed")
return posts.filter((post) => !post.completed);
}
},
mutations: {
setPosts(state, payload) {
state.posts = payload;
},
setFilterStatus(state, status) {
state.filter.status = status;
}
},
actions: {
async fetchPosts({ commit }) {
try {
const { data } = await axios.get(
" https://jsonplaceholder.typicode.com/todos/?_limit=10"
);
commit("setPosts", data);
} catch (e) {
console.error(e);
}
},
setFilterStatus({ commit }, status) {
commit("setFilterStatus", status);
}
}
});
Home.vue. Добавил в mapActions метод изменяющий статус, добавил watch который при изменении будет стучать на добавленный action.
export default {
name: "Home",
components: {
DefaultLayout,
},
data() {
return {
selected: this.$store.state.selected,
options: [
{
value: "all",
text: "All",
},
{
value: "completed",
text: "Completed",
},
{
value: "not_completed",
text: "Not completed",
},
],
};
},
computed: {
...mapGetters(["getPostsFilter"]),
},
methods: {
...mapActions(["fetchPosts", 'setFilterStatus']),
},
mounted() {
this.fetchPosts();
},
watch: {
selected(value) {
this.setFilterStatus(value);
}
}
};