⑧ vuex

1 了解 Vuex

  • Vuex 是一个专门为 Vue.js 应用程序开发的 全局状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规则保证状态以一种可预测的方式发生变化

为什么要使用 Vuex

  • vuex 的出现就是为了解决多组件间的数据通讯

  • 通过定义和隔离状态管理中的各种概念并通过强制规则 维持视图和状态间的独立性

2. 使用

2.1 步骤

  1. 创建一个 store[一个应用中运行一个store]

  2. 创建 state 数据交由 store 来管理

  3. 将创建好的 store 注入到 Vue 根实例里

  4. 在组件中使用 state 中的数据

    在任意组件中都可利用 this.$store.state.xxx 获取状态数据

    // 创建store
    const store = new Vuex.Store({
        // 创建state
        state:{
            products:[
                {name: '鼠标', price: 20},
                {name: '键盘', price: 40},
                {name: '耳机', price: 60},
                {name: '显示屏', price: 80}
            ]
        }
    }

    let app = new Vue({
        el:'#app',
        template:`<myapp/>`,
        components:{ myapp },

        // 注入store到vue实例
        store
    });

    //在myapp组件中使用store
    this.$store.state.products

2.2 Vuex的核心概念

2.2.1 state(理解为组件中的 data

state 就是 Vuex 中的公共的状态, 用于保存所有组件的公共数据

vuex 和单纯的全局对象有以下两点不同:
  1. vuex 的状态存储是响应式的

  2. 不能直接改变 store 中的状态

  • 组件获取 state this.$store.state.xxx

  • 组件修改 state this.$store.commit(mutation)

    state: {
        products: [
            { id:1, name: '鼠标', price: 20 },
            { id:2, name: '键盘', price: 40 },
            { id:3, name: '耳机', price: 60 },
            { id:4, name: '显示屏', price: 80 }
        ],
        city: '广州'
    },

2.2.2 getters(理解为组件中的 computed

类似于vue中的计算属性,getter的返回值会根据其依赖被缓存起来,且只有当它的依赖发生改变了才会被重新计算

  • 组件获取getter this.$store.getters.xxx
    getters: {
        saleProducts(state) {
            return state.products.map(item => {
                return {
                    price: item.price / 2,
                    name: item.name
                }
            });
        }
    },

2.2.3 mutations(理解为组件中的 methods

是存放处理数据的方法的集合,负责更改 state 中的数据

  • mutations 内的函数的参数

    • state

    • payload 触发函数时传入的参数

  • 调用方式:this.$store.commit(type, payload)

    mutations: {
        change(state, payload) {
            state.products = state.products.map(item => {
                return { ...item, ...payload };
            });
        }
    }

    // 调用
    this.$store.commit('change', { price: 88 })

2.2.4 actions (类似于 mutations,负责做异步操作)

actions 用来操作 mutationsmutations 用来操作 state

actions 中可以包含异步操作, mutations 中绝对不允许出现异步

  • actions 内的函数的参数

    • context:与 store 实例具有相同属性和方法的对象

    • payload 触发函数时传入的参数

  • 调用方式: this.$store.dispatch(type,payload)

    //添加actions
    actions:{ 
        minusPriceAsync(context, payload) {
            setTimeout(_ => {
                context.commit('change', payload); //context提交
            }, 2000)
        }
    }

    //调用
    this.$store.dispatch('minusPriceAsync', { price: 100 })

2.3 store 模块化

  • 由于使用单一状态 state(即所有状态会集中到 state 这个对象),当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

  • 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 statemutationactiongetter 等,这样好管理又容易维护

    import Vue from 'vue';
    import Vux from 'vuex';

    // 引入其他store模块
    import home from './home.js';
    import top250 from './top250.js';

    export default new Vuex.Store({
        modules: {
            home,
            top250
        }
    });

2.4 映射 Vuex

使用 mapState, mapGetters, mapMutations, mapActionsstate, getters, mutations, actions 映射到组件中使用,主要用于简化操作

    // 模块化开发中直接引入mapState使用
    import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';

    computed:{
        // 数组形式
        ...mapState([
            'products' //映射computed.produccts为this.$store.state.products
        ]),
        // 对象形式
        ...mapState({
            // products: 'products',
            // products: state => state.products,
            products(state) {
                return state.products;
            }
        })
    },
    methods:{
        // 数组形式
        ...mapMutations([
            'change', // 映射this.change为this.$store.commit('change')
        ]),
        // 对象形式
        ...mapMutations({
            change2: 'change', // 映射this.change2为this.$store.commit('change')

            // 函数形式:
            change3: (commit,payload) => {
                commit('change', payload);
            }
        }),
        ...mapActions({
            modify: 'minusPriceAsync', // 映射this.modify()为this.$store.dispatch('minusPriceAsync'),

            // 函数形式:自动传入dispatch,payload为调用,minus是传入的参数
            minus(dispatch,payload) {
                dispatch('minusPriceAsync', payload)
            }
        })
    }
posted on 2021-07-15 17:26  pleaseAnswer  阅读(35)  评论(0编辑  收藏  举报