vuex 是什么?Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。通俗的解释就是,Vuex 就是为 vue 组件之间进行数据共享而开发的插件。vuex 什么时候用?实现数据通信的方式对于父子组件,可以通过 props 实现数据通信;不同非父子组件可以引入 vue 对象通过 $emit/$on 实现;也可以通过不大优雅的 localStorage 存储;vuex 是另一种解决方案,如果不同组件有大量数据需要共享通信,vuex 会更适合。开始首先搭建一个 vue 项目,安装 vuex。NPMnpm n install vuex –save需要注意的是这里一定要加上 –save,因为你这个包我们在生产环境中是要使用的。Yarnyarn add vuex直接下载 / CDN 引用https://unpkg.com/vuex下载到本地,引入<script src="/path/to/vue.js"></script><script src="/path/to/vuex.js"></script>并不推荐用 script 方式引入在项目中新建一个 vuex 文件夹,并在文件夹下新建 store.js 文件,文件中我们的 vue 和vuex。import Vue from ‘vue’;import Vuex from ‘vuex’;使用 vuex,引入之后用 Vue.use 进行引用。Vue.use(Vuex);初尝试 demo1.在 store.js 文件里增加一个常量对象。const state = { count:1}2.用 export default 输出对象,让外部可以引用。export default new Vuex.Store({ state})3.新建一个 vue 组件,在 components 文件夹下,命名 counter.vue。 在模板中引入们刚建的 store.js 文件,并在模板中用 {{ $store.state.count }} 输出 count 的值。<template> <div> <h2>{{ msg }}</h2> <hr/> <h3>{{ $store.state.count }}</h3> </div></template><script> import store from ‘@/vuex/store’ export default{ data(){ return{ msg:‘Hello Vuex’, } }, store }</script>4.在 store.js 文件中加入两个改变 state 的方法。const mutations={ add(state){ state.count++; }, reduce(state){ state.count–; }}export default new Vuex.Store({ state, mutations})5.在 counter.vue 模板中加入两个按钮,并调用 mutations 中的方法。<div> <button @click=“store.commit(‘add’)">+</button> <button @click=“store.commit(‘reduce’)">-</button></div>点击按钮可以看到count数字的变化。访问state数据1.通过 computed 计算属性获取到 countcomputed: { count () { return this.$store.state.count }}或者computed: { count () { return store.state.count }}在模板里直接访问 {{ count }} 变能获取到,$store 即挂载在vue实例属性上的 store 对象通过 this.$store 可以访问 store 实例后的属性和方法2.通过 mapState 辅助函数获取到 countimport { mapState } from ‘vuex’ computed: mapState({ // 箭头函数可使代码更简练 count: state => state.count, })我们也可以给 mapState 传一个字符串数组。computed: mapState([ // 映射 this.count 为 store.state.count ‘count’])mapState 可以接受函数也可以接受一个数组,最后都统一返回一个 key value 形式的对象,使用数组意味着 key 和 value 名称是一样的。当你需要获取多个数据时,mapState 可使代码更简练。3.对象展开运算符如果 computed 需要写多个对象,展开运算符会是一个很棒的选择。computed:{ …mapState([“count”]), …mapGetters([“count”])}Mutations 修改状态状态可以理解为 state 数据,我们不能直接改变 this.$store.state 里的数据,需要调用 vuex 本身封装出来的方法,而这也恰好体现了单一数据流,$store.commit( )Vuex 提供了 commit 方法来修改状态,我们看一下在 demo 中所写的。<button @click="$store.commit(‘add’)">+</button><button @click="$store.commit(‘reduce’)">-</button>const mutations={ add(state){ state.count++; }, reduce(state){ state.count–; }}传值(payload)mutations的方法,第一个默认就是 state,第二个参数才是你所传递的const mutations={ add(state,n){ state.count+=n; }} <button @click="$store.commit(‘add’,10)">+</button>除了字符串数字类型,还可以传递对象装载更多数据mutations: { add (state, payload) { state.count += payload.amount }}store.commit(add, { amount: 10})// 也可以store.commit({ type: ‘add’, amount: 10})获取 Mutations方法import { mapState,mapMutations } from ‘vuex’;methods:mapMutations([ ‘add’,‘reduce’])// 也可以methods:mapMutations({ add: ‘add’, reduce: ‘reduce’})methods 还可以methods: { …mapMutations([ ‘add’,‘reduce’ ]), other () { }}<button @click=“add”>+</button>推荐使用数组方式,更为简单方便getters 计算过滤在 store.js 里用 const 声明我们的 getters 对象const getters = { evenOrOdd: state => state.count % 2 === 0 ? ’even’ : ‘odd’}把写好的 getters 传给 Vuex.Store 对象,输出export default new Vuex.Store({ state, mutations, getters})在组件里应用import {mapState, mapMutations, mapGetters} from ‘vuex’;computed:{ …mapState([“count”]), …mapGetters([“evenOrOdd”]),},<p>{{ evenOrOdd }}</p>便能获取到 evenOrOdd 的值actions 异步修改状态Action 类似于 mutation,不同点是,Action 提交的是 mutation,actions 是异步的改变状态,而 Mutations 是同步改变状态。注册一个简单的 actions:const actions ={ addAction(context){ context.commit(‘add’,10) }, reduceAction({commit}){ commit(‘reduce’) }}export default new Vuex.Store({ state, mutations, getters, actions})context是上下文对象,也就是就是 store 对象通过参数解构可以直接拿到commit和mutation类似直接调用 mutation 方法是 commit 调用,Action方法是使用 dispatch也可以使用辅助函数methods:{ …mapMutations([‘add’,‘reduce’]), …mapActions([‘addAction’,‘reduceAction’])}, <button @click=“addAction”>+</button> <button @click=“this.$store.dispatch(‘reduceAction’)">-</button>Actions 支持同样的载荷方式和对象方式进行分发:// 以载荷形式分发store.dispatch(‘addAction’, { amount: 10})// 以对象形式分发store.dispatch({ type: ‘addAction’, amount: 10})actions 本身是用 promise 封装实现,dispatch 依然返回 promise所以你可以store.dispatch(‘actionA’).then(() => { // …})也可以actions: { actionB ({ dispatch, commit }) { return dispatch(‘actionA’).then(() => { commit(‘someOtherMutation’) }) } }actions 往往用于结合 axios 实现异步请求数据Module大型项目多人开发大量的数据共享时,建议使用 Module之前写法export default new Vuex.Store({ state, mutations, getters, actions})Module 写法const moduleA = { state: { … }, mutations: { … }, actions: { … }, getters: { … }}const moduleB = { state: { … }, mutations: { … }, actions: { … }}const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB }})调用从 store.state.count应写成store.state.a.count若共享数据很多,可以给数据分组。总结state 用于数据存储Getter 相当于 state 的计算属性Mutation 是改变 state 的方法Action 是异步改变,提交给 Mutation分别对应辅助函数 mapState,mapGetter,mapMutation,mapActioncommit 调用 Mutation 方法dispatch 是调用 Action 方法最后看 vuex 流程图,是不是大彻大悟了?Vuex 思想理念vuex 使用单一状态树——用一个对象就包含了全部的应用层级状态。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。每一个 Vuex 应用的核心就是 store(仓库)。store 基本上就是一个容器,它包含着应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同: 1、Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新 2、不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得可以方便地跟踪每一个状态的变化,从而能够实现一些工具帮助更好地了解应用Vuex 背后的基本思想,借鉴了 Flux、Redux 和 The Elm Architecture
vuex入门
April 16, 2019 · 3 min · jiezi