一、vuex是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,

这个状态管理应用包含以下几个部分:

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

给出一张官方的“单向数据流”理念的简单示意: 

理解vuex实现的原理

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

Vuex 和单纯的全局对象有以下两点不同:

  • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。(也就是所谓的MVVM)
  • 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit)

看官网的一张图,更加方便能看懂:

理解vuex实现的原理

 如果理解了这张图,你就能知道vuex的工作原理了!

 需要注意的点:

  • 改变状态的唯一途径就是提交mutations
  • 如果是异步的,就派发(dispatch)actions,其本质还是提交mutations
  • 怎样去触发actions呢?可以用组件Vue Components使用dispatch或者后端接口去触发
  • 提交mutations后,可以动态的渲染组件Vue Components

觉得是不是少了什么,没错,就是getters 下面原理实现的时候会说 

二、实现原理

1.准备工作

先npm i store 下载vuex插件,然后在mian.js中引入,如下:

理解vuex实现的原理

 mian.js代码:

import Vue from 'vue'
import App from './App.vue' 
import router from './router'
import store from './store' 
import axios from 'axios'
import { Button, Card } from 'element-ui'
Vue.use(Button)
  .use(Card)
// import ElementUI from 'element-ui'
// import 'element-ui/lib/theme-chalk/index.css'
Vue.prototype.$http = axios
// // 注册 会自动将所有组件注册为全局组件
// Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
  router, 
  store, // 挂载到vue实例上,这样全部的组件都可以使用store
  render: h => h(App)
}).$mount('#app')

 store文件下的index.js代码:

import Vue from 'vue'
import Vuex from 'vuex'
import item from './modules/item'
import cart from './modules/cart'
import VuexPersistence from 'vuex-persist'
// 缓存部分数据
const vuexLocal = new VuexPersistence({
  storage: window.localStorage,
  reducer: state => {
    return {
      item: state.item
    }
  }
})
/*
  storage属性的值应该是一个对象
  三个方法
  setItem(key, v)
  getItem(key)
  removeItem
*/
Vue.use(Vuex)
// 初始化 vuex 仓库实例
const store = new Vuex.Store({
  strict: true,
  state: {
    num: 5000
  },
  modules: {
    item,
    cart
  },
  plugins: [vuexLocal.plugin]
})
export default store

 store文件下modules文件下的cart.js

import axios from 'axios'
export default {
  namespaced: true, //命名空间
  state: {
    num: 10,
    items: []
  },
  mutations: {
    ADD_NUM (state, n) {
      state.num += n
    },
    REDUCE_NUM (state, n) {
      state.num -= n
    },
    INIT_ITEMS (state, items) {
      state.items = items
    }
  },
  actions: {
    FETCH_ITEMS ({ commit }, params = {}) {
      axios.post('/conner/shop/goods/list/v2', params).then(res => {
        if (res.data.code === 0) {
          commit('INIT_ITEMS', res.data.data.result)
        }
      })
    }
  },
  getters: {
    doubleNum (state) {
      return state.num * 2
    }
  }
}

这里面运用到了state, mutations,actions,getters,modules 那这五个属性分别代表什么意思呢?
 

  • state: vuex的基本数据,用来存储变量。 
  • getter:从基本数据(state)派生的数据,相当于store的计算属性;getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
  • mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler) 。 回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
  • action:和mutation的功能大致相同,不同之处在于:
  1.  Action 提交的是 mutation,而不是直接变更状态;
  2.  Action 可以包含任意异步操作。
  • modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,管理更为方便。

使用下面这两种方法存储数据:
dispatch:异步操作,写法: this.$store.dispatch(‘mutations方法名’,值)

commit:同步操作,写法:this.$store.commit(‘mutations方法名’,值)

总结

使用vuex一共大致可以分为五步

  1. 下载          npm i store -S
  2. 引入         import Vuex from 'vuex'
  3. 注册         Vue.use(Vuex)
  4. 实例化      const store = new Vuex.Store({  //写配置   })
  5. 挂载到vue实例    new Vue({
      store, // 挂载到vue实例上,这样全部的组件都可以使用store
      render: h => h(App)
    }).$mount('#app')
     

发表回复