• vuex那些事儿


    vuex适用于大型单页应用。每一个Vuex应用的核心就是store(仓库),store中储存大量状态,Vuex的状态存储是响应式的。vuex使用单一状态树,一个对象包含了全部的应用层级状态,每个应用仅仅包含一个store实例。调试页面,有可能会用到dev-tools

    一、概念

    1、state(共享的状态)

    get状态,需要在计算属性computed中返回状态。要get多个状态,可以借助mapState辅助函数生成计算属性。

    state属性在store实例中设置,mapState函数在vue实例的computed属性中写。

    state:{
      a: ''
    }
    //实例中
    computed: { getStateA(){
    return store.state.a } }
    //组件中
    import { mapState } from 'vuex'
    
    export default {
      computed: {
         ...mapState(['a']),
         getStateA(){
            return this.a;
         }
      }
    }

    2、getters(共享的方法,该方法用于get状态)

    实现多个组件共享同一个状态,getters属于store的计算属性,根据依赖缓存返回值,当依赖变化时,重新计算。

    getters属性在store实例中设置,mapGetters函数在vue实例或组件的computed属性中写。

    getters: {
      getterA: state => {
        return state.a
      }
    }
    //实例中
    computed: { getGetterA() { return store.getters.getterA } }
    //组件中
    import { mapGetters } from 'vuex'
    
    export default {
      computed: {
         ...mapGetters(['getterA']),
         getGetterA(){
             return this.getterA;
         }
       }
    }

    3、mutations(修改状态)

    mutation必须是同步函数,因为回调函数进行的状态改变不能被追踪,因为mutation触发的时候,回调函数还没有被调用。

    mutations属性在store实例中设置,直接修改状态,mapMutations函数在vue实例或组件的methods属性中写。

    mutations: {
      mutationA: state => {
        state.count++
      }
    }
    //实例中
    methods: { eventA() { this.$store.commit('mutationA'); } }
    //组件中
    import { mapMutations } from 'vuex'
    
    export default {
      methods: {
         ...mapMutations(['mutationA']),
         eventA(){
            this.mutationA();
         }
       }
    }

    4、actions(提交mutation)

    store中的状态是响应式的,要set状态,不能直接改变数据,而是需要提交mutation。actions属性在store实例中设置,不会直接变更状态,而是提交mutation,可以包含异步操作。mapActions函数在vue实例或组件的methods属性中写。下面介绍4种提交mutaion的办法,仅供参考。

    vuex

    A、在组件中提交mutation

    mutations:{
        //改变状态
        mutationA(state, { adata }) {
          state.awords = adata;
        }
    }
    //全局定义store,在组件中提交mutation
    methods:{
       eventF(adata){
          // 以载荷形式提交mutation
          store.commit('mutationA',{ adata });
       }
    }
    //在组件内提交mutation
    methods:{
       eventF(adata){
          // 以载荷形式提交mutation
          this.$store.commit('mutationA',{ adata });
       }
    }

    B、在组件中提交mutation之mapMutations

    import { mutationA, mutationB } from './mutation-types'
    
    export default {
        [mutationA](state,payload){
            state.dataA = payload;
        }, 
        [mutationB](state,payload){
            state.dataB = payload;
        }
    }
    import { mapMutations } from 'vuex'
    export default {
      methods: {
        ...mapMutations([
           'mutationA',
           'mutationB' 
        ]),
        ...mapMutations({
            add: 'mutationA' 
        }),
        eventA(){
           this.mutationA();
        },
        eventB(bdata){
           this.mutationB(bdata);
        },
        eventC(cdata){
           this.add(cdata);
        }
      }
    }

    C、在actions中提交mutation

    mutations:{
        //改变状态
        mutationA(state, payload) {
          state.awords = payload;
        },
        //改变状态
        mutationB(state, payload) {
          state.bwords = payload;
        }
    },
    //在actions中提交mutation,同步,异步
    actions:{
        actionA({commit,state},payload){
          commit('mutationA',payload);
        },
        actionB({commit},payload){
          new Promise((resolve,reject)=>{
            setTimeout(()=>{
              commit('mutationB',payload);
              resolve();
            },1000)
          })
        }
    }
    //在组件中分发action
    methods:{
      eventA(){
         store.dispatch('actionA','我是老大');
      }
    }

    D、在actions中提交mutation之mapActions 

    import { mutationA, mutationB } from './mutation-types'
    
    export default {
        [mutationA](state,payload){
            state.dataA = payload;
        }, 
        [mutationB](state,payload){
            state.dataB = payload;
        }
    }
    //actions.js,提交mutation
    import { mutationA, mutationB } from './mutation-types'
    
    export default {
        actionA({commit,state}, payload){
           commit(mutationA, payload);
        },
        actionB({commit,state}, payload){
           commit(mutationB, payload);
        }
    }
    import { mapActions } from 'vuex'
    
    //在组件中分发action
    methods:{
        ...mapActions(['actionA', 'actionB']),
        eventA(){
           this.actionA('我是老大');
        },
        eventB(){
           this.actionB('我是老二');
        }
    }

    5、modules

    解决状态多导致store对象臃肿,将store分割成模块,每个模块拥有自己state,getters,mutations,actions。

    二、vuex的引用方法
    1、用script标签

    <script src="https://unpkg.com/vuex"></script>

    2、npm安装

    cnpm install vuex
    //在js文件引入
    var Vue = require('vue')
    var Vuex = require('vuex')
    
    Vue.use(Vuex)

    三、参考案例

    四、简单版父子组件通信

    const store = new Vuex.Store({
      state:{
        fwords: '一朵红花',
        awords: '我是老大'
      },
      getters:{
        getAwords(state){
          return state.awords
        }
      },
      mutations:{
        //改变状态
        listenA(state, { adata }) {
          state.awords = adata;
        }
      }
    })

    1、父组件给子组件传递消息

    //父组件
    <com-a :apropVal="getFwords"></com-a>
    
    computed:{
        getFwords(){
          return store.state.fwords
        }
    }
    //子组件
    <h3>父亲给我了,{{ apropVal }}</h3>
    
    props:['apropVal']

    2、子组件给父组件传递事件

    //子组件
    <input type="button" value="A和父亲说话" @click="eventAf">
    
    methods:{
      eventAf(){
        this.$emit('a-f-msg',`谢谢父亲`);
      }
    }
    //父组件
    <com-a @a-f-msg="eventFa"></com-a>
    
    methods:{
       eventFa(adata){
          // 以载荷形式提交mutation
          store.commit('listenA',{ adata });
       }
    }

    五、简单版兄弟组件通信

    const store = new Vuex.Store({
      state:{
        awords: '',
        bwords: ''
      },
      getters:{
        getAwords(state){
          return state.awords
        },
        getBwords(state){
          return state.bwords
        }
      },
      mutations:{
        //改变状态
        mutationA(state, payload) {
          state.awords = payload;
        },
        //改变状态
        mutationB(state, payload) {
          state.bwords = payload;
        }
      },
      actions:{
        actionA({commit,state},payload){
          commit('mutationA',payload);
        },
        actionB({commit},payload){
          new Promise((resolve,reject)=>{
            setTimeout(()=>{
              commit('mutationB',payload);
              resolve();
            },1000)
          })
        }
      }
    })
    //子组件A
    <h4>B传过来的数据是:{{ store.getters.getBwords }}</h4>
    <input type="button" value="把值传给B" @click="eventAb">
    
    methods:{
        eventAb(){
            store.dispatch('actionA','我是老大');
        }
    }
    //子组件B
    <h4>A传过来的数据是:{{ store.getters.getAwords }}</h4>
    <input type="button" value="把值传给A" @click="eventBa">
    
    methods:{
        eventBa(){
           store.dispatch('actionB','我是老二');
        }
    }

    六、综合版父子兄弟组件通信

    1、语法基础

    A、引入和输出模块

    //store.js,默认输出
    export default store;
    //main.js
    import store from 'store.js';
    // constants.js
    export const A = 1;
    export const B = 3;
    //main.js
    import { A, B } from './constants.js';
    // constants.js,跨模块常量
    export const A = 1;
    export const B = 3;
    export const C = 4;
    // main.js 
    import * as constants from './constants';
    console.log(constants.A); // 1
    console.log(constants.B); // 3

    B、对象扩展运算符

    将多个对象合并为一个,传给computed属性。

    # 安装插件
    npm i -D babel-plugin-transform-object-rest-spread
    #配置文件babelrc
    {
      "presets": ["env"],
      "plugins": ["transform-runtime","transform-object-rest-spread"]
    }
    //组件内
    computed:{ ...mapGetters([
    'getterA','getterB','getterC']) }

    C、对象属性名用常量表达式

    //mutation-types.js
    export const MUTATION_A = 'MUTATION_A';
    //mutations.js
    import { MUTATION_A } from './mutation-types';
    
    export default {
      [MUTATION_A](state,payload){
        state.dataA = payload;
      }
    }

    D、对象参数的解构赋值

    //actions.js
    import { MUTATION_A } from './mutation-types';
    //解构赋值前,context是一个对象
    export default {
       actionA(context, payload){
           context.commit(MUTATION_A, payload);
       }
    }
    //解构赋值后
    export default {
       actionA({commit, state}, payload){
           commit(MUTATION_A, payload);
       }
    }

    commit = context.commit,为什么这样解构赋值?查看原理

    2、父组件给子组件传递

    3、子组件给父组件传递

    4、兄弟组件相互传递

  • 相关阅读:
    boost::asio在VS2008下的编译错误
    Java集合框架——接口
    ACM POJ 3981 字符串替换(简单题)
    ACM HDU 1042 N!(高精度计算阶乘)
    OneTwoThree (Uva)
    ACM POJ 3979 分数加减法(水题)
    ACM HDU 4004 The Frog's Games(2011ACM大连赛区第四题)
    Hexadecimal View (2011ACM亚洲大连赛区现场赛D题)
    ACM HDU 4002 Find the maximum(2011年大连赛区网络赛第二题)
    ACM HDU 4001 To Miss Our Children Time (2011ACM大连赛区网络赛)
  • 原文地址:https://www.cnblogs.com/camille666/p/vuex.html
Copyright © 2020-2023  润新知