有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数:
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性
)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
Getter 接受 state 作为其第一个参数:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
通过属性访问
Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值:
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
Getter 也可以接受其他 getter 作为第二个参数:
getters: {
// ...
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
store.getters.doneTodosCount // -> 1
我们可以很容易地在任何组件中使用
它:
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
注意,getter 在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的。
getters
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuex</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script type="text/javascript" src="https://unpkg.com/vuex@3.1.1/dist/vuex.js"></script>
</head>
<body>
<div id="app">
{{msg}}
{{word}}
<home/>
</div>
<!-- home组件template模板 -->
<script type="text/x-template" id='home'>
<div>
<table border='1'>
<tr>
<td>id</td>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
<td>语文</td>
<td>数学</td>
<td>英语</td>
<td>总分</td>
</tr>
<tr v-for='item in students'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>{{item.sex}}</td>
<td>{{item.chinese}}</td>
<td>{{item.math}}</td>
<td>{{item.english}}</td>
<td>{{item.sum}}</td>
</tr>
</table>
</div>
</script>
<script type="text/javascript">
// 第一步实例化一个store
// 第二步在根组件上挂载store,详见87行
// 第三步在组件或者子组件中使用this.$store.state.students
var store = new Vuex.Store({
state: {
students: [
{
id: 1,
name: '张三',
age: 18,
sex: 'man',
chinese: 80,
math: 94,
english: 99
},
{
id: 2,
name: '李四',
age: 18,
sex: 'man',
chinese: 80,
math: 94,
english: 99
}
]
},
getters: {
// getters里面的方法接收一个state参数,指向state,可直接调用state中的数据
students(state){
// 先拿到state的数据students
var students = state.students
// 再针对students处理,最后返回处理后的students数据
state.students.map(item=>{
item.sum = item.chinese + item.math + item.english
})
return students
}
}
})
// home组件
var home = {
template: '#home',
data(){
return {
}
},
computed: {
students(){
return this.$store.getters.students
}
}
}
// 根组件
var app = new Vue({
data: {
msg: 'hello'
},
computed: {
word(){
return this.msg + ', world'
}
},
// 子组件
components: {
home
},
store
}).$mount('#app')
</script>
</body>
</html>
网友评论