Vuex State

Vuex 使用单一状态树

一个对象就包含了全部的应用层级状态

作为一个“唯一数据源 ”而存在

每个应用将仅仅包含一个 store 实例

单状态树和模块化并不冲突

如何将状态和状态变更事件分布到各个子模块中?

在 Vue 组件中获得 Vuex 状态

从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态:

store.state.count 组件中 this.$store.state.count;
// 创建一个 Counter 组件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count //组件中 this.$store.state.count;
    }
  }
}

每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。

在模块化的构建系统中,在每个需要使用 state 的组件中需要频繁地导入,并且在测试组件时需要模拟状态

Vuex 通过 store 选项 (调用 Vue.use(Vuex)) 将状态从根组件“注入”到每一个子组件中。

const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
//当下面的store 实例注入到根组件下的所有子组件中后,子组件通过 this.$store 访问到
      return this.$store.state.count
    }
  }
}

const app = new Vue({
  el: '#app',
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

mapState 辅助函数

使用 mapState 辅助函数,可以帮助我们生成计算属性。

当一个组件需要获取多个状态的时候,可以将这些状态使用mapState声明为计算属性。

index.js:

import Vue from 'vue';
import 'es6-promise/auto'
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        count: 0,
        countPlus: 1,
        countLength: 1,
    },
    mutations: {
        increment(state) {
            state.count++;
            state.countPlus = state.count + 1;
            state.countLength = state.count.toString().length;
        },
        decrement(state) {
            state.count--;
            state.countPlus = state.count + 1;
            state.countLength = state.count.toString().length;
        },
    },
});
export default store;

StoreComponent.vue:

<template>
    <div>
        <button @click="increment"> {{count}}</button>
        <button @click="decrement"> {{count}}</button>
        <span> Plus one: {{ countPlus }}</span>
        <span> Length:   {{ countLength}}</span>
    </div>
</template>

<script>
    import {mapState} from 'vuex';

    export default {
        name: "StoreComponent",

        // computed: {
        //     count() {
        //         return this.$store.state.count;
        //     },
        //
        // },
        computed: mapState({
            count: state => state.count,

            countPlus: 'countPlus',

            countLength(state) {
                return state.countLength;
            },

        }),
        // computed: mapState({
        //     // count: state => state.count,
        //     // count: 'count',
        // }),
        // computed: mapState([
        //     'count',
        //     'countPlus',
        //     'countLength',
        // ]),


        methods: {
            increment() {
                this.$store.commit('increment');
            },
            decrement() {
                this.$store.commit('decrement');
            },
        }
    }
</script>

<style scoped>

</style>

除了:

computed: mapState({
    count: state => state.count,

    countPlus: 'countPlus',

    countLength(state) {
        return state.countLength;
    },

}),

也可以使用:

computed: mapState([
    'count',
    'countPlus',
    'countLength',
]),

对象展开运算符

mapState 函数返回的是一个对象

像这样:

//这样的我们怎么添加其他本地计算属性呢?

computed: mapState({
    count: state => state.count,

    countPlus: 'countPlus',

    countLength(state) {
        return state.countLength;
    },

}),

方法:使用对象展开运算符

即:

computed: {
  localComputed () { /* ... */ },
  // 使用对象展开运算符将此对象混入到外部对象中
  ...mapState({//三个点必须要
    // ...
  })
}
computed: {
    countPlusLength() {
        return this.countPlus.toString().length;
    },
    ...mapState({
        count: state => state.count,

        countPlus: 'countPlus',

        countLength(state) {
            return state.countLength;
        },

    })
},

注意:

使用 Vuex 并不意味着你需要将所有的状态放入 Vuex。

虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。

如果有些状态严格属于单个组件,最好还是作为组件的局部状态。

你应该根据你的应用开发需要进行权衡和确定。

原文地址:https://www.cnblogs.com/dzkjz/p/12761055.html