Vuex使用总结

906 阅读2分钟

最近看了下vuex的文档,也写了些总结,官方文档其实也很详细,这里做下总结。

为了方便管理将store分离出来。

/**
 * 参数说明:
 * state: 这里的state类似于vue每个组件中的data参数,用来定义全局的状态键名。
 * 
 * getters: 类似于vue对象中的computed属性,也就是计算属性,例如:这里定义了一个saleNUms方法,
 * 方法内部通过使用数组的map方法,对数组中的对象进行遍历,并将每个对象中的年龄乘以2,最终输出新的数组对象。
 * 补充说明:这里的map方法和forEach已经jquery中的$each()方法用法一致。
 * 
 * mutations: 这里的mutations类似于vue组件中的methods属性。
 * 在其他组件中调用的时候使用this.$store.commit('方法名',自定义参数)
 * 一条重要的原则就是要记住 mutation 必须是同步函数
 * 也可借助mapActions将this.$store.commit('方法名',自定义参数)映射为this.方法名(自定义参数)
 * 
 * actions:这里的actions类似于vuex中的整个store。
 * 注意:这里可以用于异步也可用于同步操作,这里以异步模拟返回结果
 * 在其他组件中调用需要使用this.$store.dispatch('方法名',自定义参数)
 * 也可借助mapActions将this.$store.dispatch('方法名',自定义参数)映射为this.方法名(自定义参数)
 * 
 * 
 * */

用法示例:

1、新建store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store = new Vuex.Store({
    state:{
        name:'',
        val:'',
        projects:[
            { name: '小三', age: 18 },
            { name: '小四', age: 19 },
            { name: '小五', age: 20 }
        ]
    },
    getters:{
        saleNums:(state)=>{
            let newprojects = state.projects.map(item=>{
                return {
                    name: item.name,
                    age: item.age * 2
                }
            });
            return newprojects;
        },
        /** 
         * 这个第一个参数是store内部的state值,第二个参数是自定义参数
         * 补充说明:这里使用了数组的find方法,返回数组中对应的值(这里用来返回年龄为18的对象).
         * 注意:这里只能返回第一个找到的值,即如果数组中有个18岁的只返回找到的第一个对象
        */
        findDom: (state) => (id) => {
            return state.projects.find(a => a.age == id)
        }
    },
    mutations:{
        minAge:(state,num)=>{
            let newprojet = state.projects.forEach((res)=>{
                console.log(res);
                res.age -= num
            });
            return newprojet
        },
        /*
        *基本用法:
        *这里定义好了一个方法,可以在其它页面通过this.$store.commit('setVal','要传的值');对store中data里定义好的参数进行赋值
        */
        setVal(state,paylod){
            state.val = paylod
        }
    },
    actions:{
        chagename(context,payload){
            return new Promise((resolve,reject)=>{
                setTimeout(() => {
                    context.commit('minAge', payload)
                    resolve(5);
                }, 1000);
            })
        }
    }
})

export default store;

2、在main.js中注入即可

import store from './store/store'

new Vue({
  el: '#app',
  store,
  components: { App },
  template: '<App/>'
})

使用例子:这里以Home.vue组件为例

<template>
<div>
    <button @click="small(2)">mutations调用</button>
    <button @click="small2(1)">actions调用</button>
</div>
</template>
<script>
//这里引入组件绑定的辅助函数可以简化后边写法
import { mapState } from 'vuex'
import { mapGetters } from 'vuex'
import { mapMutations } from 'vuex'
import { mapActions } from 'vuex'
export default {
    name:'Home',
    data(){
        return {
            datas: this.$store.state.projects,//获取store中的数据
            gets: this.$store.getters.saleNums,
            fa: this.$store.getters.findDom(18),
            /**
             * 注意:以下是错误的写法,如果是在computed中通过mapGetters引入的getters
             * 在组件的data中不能直接通过this.方法名来获取值,因为有加载顺序问题,会导致拿到的值为undefined
             * 需要在其它生命周期函数中中进行使用(如下)
             * 如需在data中直接使用,则需要写完整的写法即this.$store.getters.saleNums
             * 
             * 同理通过mapState引入的state也是如此,需要在其它生命周期函数中进行使用
             * 如需在data中直接使用,则需要写完整的写法即this.$store.state.projects
             */
            hh: this.saleNums,//错误写法(不能在data中这样写,可在生命周期函数中使用,但须借用对应的map.....)
            kk: this.projects//错误写法(不能在data中这样写,可在生命周期函数中使用,但须借用对应的map.....)
        }
    },
    methods:{
        ...mapMutations([
            "minAge"
        ]),
        ...mapActions([
            'chagename'
        ]),
        small(id){
            //这里第一个参数是方法名,第二个参数是自定义参数
            //this.$store.commit('minAge',id);
            /**
             * 这里是执行了store中的mutations中的方法
             * 注意:这里使用时需要用this.$store.commit('方法名',自定义参数)
             * 这里可以写成这样,同上边的写法一致,这里是借助vuex中的mapMutations,将 `this.minAge()` 映射为 `this.$store.commit('minAge',id)`
             * 需要注意的是,使用前必须局部引入,即import { mapMutations } from 'vuex'
             *  */
            this.minAge(id);
        },
        small2(id){
            /**
             * 这里是执行了store中actions中的方法
             * 注意:这里使用时需要用this.$store.dispatch('方法名',自定义参数)
             * 这里一般用于需要异步操作的位置(这里使用了调用后.then是因为在方法中new 了一个promise)
             * 这里可以写成下边的写法,借助vuex中的mapActions将this.change()映射为this.$store.dispatch()
             * 需要注意的是,使用前必须局部引入,即import { mapActions } from 'vuex'
             * */
            // this.$store.dispatch('chagename', id).then(()=>{
            //     console.log("返回了");
            // })
            this.chagename(id).then((e)=>{
                console.log(e);//5
                console.log("返回了");
            })
        }
    },
    created() {
        console.log(this.datas);
        console.log(this.gets);
        console.log(this.fa)
        console.log(this.projects);//这里可拿到值
    },
    mounted() {
        //这里也可拿到值
        let cc = this.saleNums;
        console.log(cc);
    },
    computed: {
        /**
         * getters中的自定义方法一般在 组件的computed中注入(因为getters本身就是计算属性)
         * 在computed中注入的使用时只需以this.名称即可(即采用属性的形式使用)
        */
        ...mapGetters([
            'saleNums',
            'findDom'
        ]),
        ...mapState([
            'name',
            'projects'
        ])
    },
}
</script>