利用vuex优化vue组件通信,vuex基本用法总结

100 阅读2分钟

为了让组件更容易拿到数据和方法,我们会使用到vuex插件。

Vuex是一个专为Vue.js应用程序开发的状态管理模式。

Vuex的核心是store(仓库),store基本上就是一个容器,它包含着你的应用中大部分的状态 (state)

整体上来看,难度并不大,写法都是参考vue,但是很多单词都换了,所以需要额外记忆和熟练使用。


export default new Vuex.Store({
  state: () => {
    //类似于vue的data
    return {
      a: 1,
      b: 1,
      timer: null,
    };
  },
  getters: {
      //类似于vue的computed
      //  函数中的第一参数: state -> 当前store实例中的state对象
    //  函数中的第二参数: getters -> 当前store实例中的getters对象
    doubleA: (state) => {
      return state.a * 2;
    },
    doubleB(state) {
      return state.b * 2;
    },
    doubleBoth: function (state, getters) {
      return getters.doubleA + getters.doubleB;
    },
  },
  mutations: {
      //类似于vue的methods,但只写同步方法
      //第一个参数就是state
      //第二个参数是你需要传递的参数
    addA(state) {
      state.a++;
    },
    addB(state) {
      state.b++;
    },
    addAN(state, pl) {
      state.a += pl;
    },
  },
  actions: {
      //类似vue的methods,一般写异步方法
      //第一个参数context其实就当是store
      //这里面的方法一般不直接改变数据,而需要通过mutations里面的方法修改
    addA_async(context) {
      console.log(context);
      clearTimeout(context.rootState.timer);
      context.rootState.timer = setTimeout(() => {
        console.log(111);
        context.commit("addA");
      }, 1000);
    },

    addB_async(context) {
      setTimeout(() => {
        context.commit("addB");
      }, 1000);
    },
    addAN_async(context, payload) {
      setTimeout(() => {
        context.commit("addAN", payload);
      }, 1000);
    },
  },

后续使用的时候,其实就两种方法,第一种就是通过$store,写起来比较繁琐,我们先试试这种

<div class="home">
      <div>
          <h3>state</h3>
          <p>a:{{ $store.state.a }}</p>
          <p>b:{{ $store.state.b }}</p>
      </div>
      <div>
          <h3>getters</h3>
          <p>doubleA:{{ $store.getters.doubleA }}</p>
          <p>doubleA:{{ $store.getters.doubleB }}</p>
          <p>doubleBoth:{{ $store.getters.doubleBoth }}</p>
      </div>
      <div>
          <h3>mutations</h3>
          <p>
              <button @click="$store.commit('addA')">a++</button>
              <button @click="$store.commit('addAN',10)">a+10</button>
          </p>
          <p>
              <button @click="$store.commit('addB')">b++</button>
          </p>
      </div>
      <div>
          <h3>actions</h3>
          <p>
              <button @click="$store.dispatch('addA_Async')">a++</button>
              <button @click="$store.dispatch('addAN_Async',10)">a+10</button>
          </p>
          <p>
              <button @click="$store.dispatch('addB_Async')">b++</button>
          </p>
          <p>
            <button @click="$store.dispatch('addBoth_Async')">a++,b++</button>
          </p>
          <p>
            <button @click="$store.dispatch('test')">test</button>
          </p>
      </div>
  </div>




我们可以观察到,调用同步方法需要用commit,而异步方法则是dispatch,后续的函数名和参数也要对应写入

而第二种方法,就是利用官方提供的封装函数,直接将变量和store内的数据关联起来,有点像是解构赋值

<script>
  // @ is an alias to /src
  import { mapState,mapGetters,mapMutations,mapActions } from "vuex";
  
  
  export default {
    name: 'HomeView',
    components: {
     
    },
    computed:{
        ...mapState(["a","b"]),
        ...mapGetters(["doubleA","doubleB","doubleBoth"]),
    },
    methods:{
        ...mapMutations(["addA","addAN","addB"]),
        ...mapActions(["addA_async","addAN_async","addB_async","addBoth_Async"]),
    }
  }
  </script>


然后使用起来就简单很多

      <div>
        <h1>state类似于vue-data</h1>
        <p>a:{{ a }}</p>
        <p>b:{{ b }}</p>
      </div>
      <div>
        <h1>getters类似于vue-computed</h1>
        <p>多倍a:{{ doubleA }}</p>
        <p>多倍b:{{ doubleB }}</p>
        <p>doubleBoth:{{ doubleBoth }}</p>
      </div>
      <div>
        <h1>mutations类似于vue-methods(sync only)</h1>
        <button @click="addA">a++</button>
        <button @click="addB">b++</button>
        <button @click="addAN(10)">a+10</button>
      </div>
      <div>
        <h1>actions类似于vue-methods(async only)</h1>
        <h2>不可直接改数据,必须用mutations的方法</h2>
        <button @click="addA_async">a++</button>
        <button @click="addB_async">b++</button>
        <button @click="addAN_async(10)">a+10</button>
      </div>
      
      
    </div>

总结:

  • state类似vue中的data;

  • getters类似vue中的计算属性 -> 依赖于state

// 函数中的第一参数: state -> 当前store实例中的state对象

// 函数中的第二参数: getters -> 当前store实例中的getters对象

  • mutations类似vue中的methods -> 依赖于state (mutayions中的方法只能是同步的)

// 函数中的第一参数: state -> 当前store实例中的state对象

// 函数中的第二参数: payload(载荷) 方法被调用时可以接收一个实际参数被形参接收

  • actions类似vue中的methods -> 依赖于state (actions中的方法只能是异步的)

// 函数中的第一参数: context -> 和store实例有相同属性和方法的新对象 {state,getters,commit,dispatch}

// 函数中的第二参数: payload(载荷) actions方法被调用时可以接收一个实际参数被形参接收

//actions里面的函数想要修改数据,必须要调用mutations里面的方法