Vuex 入门

安装:

npm install vuex --save
// store/index.js    
import Vue from 'vue'
import Vuex from 'vuex'
// 模块化工程中,Vue.use() 是必须的
Vue.use(Vuex);
// 抛出模块,用于跟组件注册
const store = new Vue.store({
  // ...
});
export default store
// main.js 需要引入 store 
import store from './store/index.js';
// vue 根组件注册 store
new Vue({
  store: store
});

注意:Vuex 依赖 Promise。若浏览器没实现Promise,请安装包 es6-promise 。

<!-- 单文件项目,可使用全局的script标签,省略前三步 -->
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>

概念:

 

“单向数据流”理念的极简示意

 

必须通过vuex内部方法才能修改"state"的数据

使用:

vuex实例对象的5个属性创建store

new Vuex.store({
  state: {
    list: [
      { id: 1, text: '...1...', done: true },
      { id: 2, text: '...2...', done: false }
    ]
  },
  // 用于提取"特征数据",类似组件的"computed"属性
  getters: {
    findIdIsTwo(state, id) {
      return state.list.find((e) => {
        return e.id === id;
      })
    }
  },
  // 作为修改"state"数据的唯一途径,但内部只能定义"同步函数"
  mutation: {
    addList(state, item) {
      state.list.push(item);
    }
  },
  // 类似于"mutation",但"action"提交的是"mutation",而不是直接变更数据状态,一般定义"异步函数"
  actions: {
    asyncAddList({ commit }) {
      setTimeout(() => {
        // 调用"commit"回调函数
        commit('addList');
      }, 2000);
    },
    // 组合 Action  利用Promis或async/await
    // 假设 getData() 和 getOtherData() 返回的是 Promise
    async actionA({ commit }) {
      commit('gotData', await getData())
    },
    async actionB({ dispatch, commit }) {
      await dispatch('actionA') // 等待 actionA 完成
      commit('gotOtherData', await getOtherData())
    }
  },
  // 当本组件太臃肿,需要拆分,则要用"model",较好的情况的是只有"model",其他属性均以组件引入
  // 一般使用"import"引入模块  import moduleA from './module/moduleA'
  module: {
    moduleA
  }
});
// 关于局部模块的注意事项
const moduleA = {
  state: { count: 0 },
  // 对于模块内部的 mutation 和 getter,接收的第一个参数(state)是模块的局部状态对象。
  mutations: { increment(state) { } },
  // 对于模块内部的 getter,根节点状态会作为第三个参数(rootState)暴露出来
  getters: { sumWithRootCount(state, getters, rootState) { } },
  // 对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState
  actions: { incrementIfOddOnRootSum({ state, commit, rootState }) { } }
}

 /* action 内能使用 "dispatch" */

使用/修改

// 引入"辅助函数"
import { mapState, mapGetters } from "vuex";
// 获取数据的方式(以"mounted"为例)
new Vue({
  computed: {
    // State
    // 访问数据不在模块的情况
    count1() { return this.$store.state.count1 },
    // 如果是模块内的,如 moduleA
    count2() { return this.$store.state.moduleA.count2 },
    // 使用 mapState 辅助函数 和 对象展开运算符
    ...mapState({
      count3: state => state.moduleA.count3,
      // ...
    }),
    // Getter
    // 与 State 类似的方式引入
    itemIsTwo(){ return this.$store.getters.moduleA.findId(2);},
    // 使用 mapGetters 辅助函数 和 对象展开运算符
    ...mapGetters([
      'doneTodosCount',
      // ...
    ])
  },
  methods: {
    handleClick() {
      // 使用 Mutation ,第一个参数为 Mutation 内的方法名,第二个参数为传参(可省略)
      this.$store.commit('addList', { id: 5, text: '5', done: false });
      // 使用 Action ,与 Mutation 类似
      this.$store.dispatch('asyncAddList', { id: 6, text: '6', done: false })
    }
  }
});

表单处理:

 由于 "store" 的数据不能直接修改,表单使用 "v-model" 的双向绑定会报错:

<!-- 错误做法(假设"message"来源于"store") -->
<input v-model="message">

正确做法1:( "v-on" 事件发起 "commit")

<input :value="message" @input="updateMessage">
// ...
computed: {
  ...mapState({
    message: state => state.message
  })
},
methods: {
  updateMessage (e) {
    this.$store.commit('updateMessage', e.target.value)
  }
}

正确做法2:(创建 "get""set" 方法)

<input v-model="message">
// ...
computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}

 

vuex官方文档

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值