zoukankan      html  css  js  c++  java
  • 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、兄弟组件相互传递

  • 相关阅读:
    【转】分治法求最大值最小值
    JPA基本实体映射学习
    android权限
    Servlet实现基本文件上传
    Flask项目部署(nginx+supervisor+uwsgi)
    DevExpress学习笔记(三)XtraGrid
    DevExpress学习笔记(五)-以拖拽的方式构建树(TreeList)
    使用ICE建立C++与C#的通讯
    带有Wallet的impdp导入过程
    调用ODAC报BadImageFormatException异常的解决方法
  • 原文地址:https://www.cnblogs.com/camille666/p/vuex.html
Copyright © 2011-2022 走看看