vuex-Getters

2019-07-06  本文已影响0人  coffee1949

有时候我们需要从 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>
上一篇下一篇

猜你喜欢

热点阅读