Фильтр данных из обьекта Vuex на Frontend
Хочу реализовать такую схему. Из Vuex мне прилетает массив persons обьектами:
[{name: 'lera', balance: 200,},{name: 'tyma', balance: 400,},{name: 'vlad', balance: 100,}]
Потом я вывожу его через v-for на страницу. Также добавляю кнопки фильтрации по полю balance
И вот в чем вопрос. Я пытаюсь реализовать фильтр через methods:
filter() {
const balanceFilter = this.$store.state.persons.filter(person => person.balance > 240)
this.$store.state.persons = balanceFilter
}
И вешаю то на кнопку. Но при нажатии ничего не происходит. Кто нибудь знает ответ на этот вопрос? Заранее спасибо!
Ответы (1 шт):
В зависимости от того допускаете ли вы изменение исходного массива данных, можно пойти разными путями:
Допустим, полагаясь на исходные данные из vuex вы создаете в компоненте фильтр и отфильтрованные данные храните в нем же, без модификации исходных данных во vuex.
const store = new Vuex.Store({
state: {
persons: [{
name: 'lera',
balance: 200,
}, {
name: 'tyma',
balance: 400,
}, {
name: 'vlad',
balance: 100,
}]
},
getters: {
getPersons: (state) => {
return state.persons
}
},
})
const {
mapGetters
} = Vuex
new Vue({
el: '#app',
store,
data: {
newPersons: []
},
computed: {
...mapGetters(['getPersons'])
},
mounted() {
this.newPersons = this.$store.state.persons
},
methods: {
filterPersons() {
const balanceFilter = this.$store.state.persons.filter(person => person.balance > 240)
this.newPersons = balanceFilter
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<div id="app">
<ul>
<li v-for="item in newPersons">{{ item.name }} ({{item.balance}})</li>
</ul>
<button @click="filterPersons">filter balance > 240</button>
</div>
В случае если вы хотите получить доступ к отфильтрованным данным глобально из других компонентов, можете провести модификацию вашего исходного массива данных. Это не всегда практично, но пример приведу, как это сделать (обращаю внимание, что проводить модификацию хранилища vuex нужно только используя мутации):
const store = new Vuex.Store({
state: {
persons: [{
name: 'lera',
balance: 200,
}, {
name: 'tyma',
balance: 400,
}, {
name: 'vlad',
balance: 100,
}]
},
getters: {
getPersons: (state) => {
return state.persons
}
},
mutations: {
setPersons: (state, data) => {
state.persons = data
}
},
})
const {
mapGetters,
mapMutations
} = Vuex
new Vue({
el: '#app',
store,
computed: {
...mapGetters(['getPersons'])
},
methods: {
...mapMutations(['setPersons']),
filterPersons() {
const balanceFilter = this.getPersons.filter(person => person.balance > 240)
this.setPersons(balanceFilter)
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<div id="app">
<ul>
<li v-for="item in getPersons">{{ item.name }} ({{item.balance}})</li>
</ul>
<button @click="filterPersons">filter balance > 240</button>
</div>
И чтобы не потерять исходные данные (перезаписать новыми данными в результате фильтрации) можете создать в vuex свойство, допустим, filteredPersons и в нее записывать текущие отфильтрованные данные, чтобы получить доступ к этим данным из любого компонента вашего приложения.
const store = new Vuex.Store({
state: {
persons: [{
name: 'lera',
balance: 200,
}, {
name: 'tyma',
balance: 400,
}, {
name: 'vlad',
balance: 100,
}],
filteredPersons: []
},
getters: {
getPersons: (state) => {
return state.persons
},
getFilteredPersons: (state) => {
return state.filteredPersons
},
},
mutations: {
setFilteredPersons: (state, data) => {
state.filteredPersons = data
}
},
})
const {
mapGetters,
mapMutations
} = Vuex
new Vue({
el: '#app',
store,
computed: {
...mapGetters(['getPersons', 'getFilteredPersons'])
},
methods: {
...mapMutations(['setFilteredPersons']),
filterPersons(balance) {
const balanceFilter = this.getPersons.filter(person => person.balance > balance)
this.setFilteredPersons(balanceFilter)
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<div id="app">
<h4>Исходные данные (Vuex)</h4>
<ul>
<li v-for="item in getPersons">{{ item.name }} ({{item.balance}})</li>
</ul>
<h4>Отфильтрованные (Vuex)</h4>
<ul>
<li v-for="item in getFilteredPersons">{{ item.name }} ({{item.balance}})</li>
</ul>
<button @click="filterPersons(199)">filter balance > 199</button>
<button @click="filterPersons(240)">filter balance > 240</button>
</div>
Это не которые из возможных вариантов и они не являются эталонными в решении вашей задачи.