vuex总结

873 阅读2分钟

1. 定义

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

通过官方文档提供的流程图我们知道,vuex的工作流程

1、数据从state中渲染到页面;

2、在页面通过dispatch来触发action;

3、action通过调用commit,来触发mutation;

4、mutation来更改数据,数据变更之后会触发dep对象的notify,通知所有Watcher对象去修改对应视图(vue的双向数据绑定原理)。

应用场景

  1. 多个视图依赖于同一状态
  2. 来自不同视图的行为需要改变同一个状态

vuex的组成介绍

  1. State: 数据仓库

  2. Getter: 用来获取数据的

  3. Mutation: 用来修改数据的

  4. Action: 用来提交mutation

  5. Module: 模块化store

流程图

2. 安装步骤

  1. 安装vuexnpm i vuex --save
  2. 创建vuex实例: new Vuex.store()
  3. main.js中将vuex实例挂载到vue对象上

3. 引用

  • 在main.js的同级目录下新建store文件夹。 store文件夹下新建index.js。 以下为index.js中用来引入vuex的代码
import Vue from 'vue' // 引入vue
import Vuex from 'vuex' // 引入vuex

Vue.use(Vuex)

// 使用 vuex 实例
const store = new Vuex.Store({
    state: {
        count: 121
    },
    getters : {
      newCount (state) {
       return state.count + 100
      }
    },
    mutations: {
        numAdd(state, num) {
            state.count += num
        }
    },
    actions: {
        deleteNum({ commit }, num) {
            setTimeout(() => {
                commit('numAdd', num)
            }, 2000)
        }
    }    
})

export default store // 导出store
  • 在main.js中引入store文件夹下的index.js文件
import Vue from 'vue'
import App from './App'
import store from './store'  // 主要是这一行

new Vue({
  el: '#app',
  store,     // 还有这一行
  render: h => h(App)
})

4.vuex中常用方法和属性的调用

// 方法1 需要引入store  import store from '@/store'
store.state.count
// 方法2(需要使用vue.use注入)
this.$store.state.count
// 方法3,通过辅助函数mapState
import { mapState } from 'vuex';
export default {
    computed: {
        // 使用ES6的扩展运算符来达到将state释放出来
        ...mapState([
          // 映射 this.count 为 store.state.count
          'count'
        ])
    }
}

state

<div>这里是store的state--->{{this.$store.state.count}}</div>
const state = {
    name: 123456,
    greatToken: ''
}

mutations(通过commit触发,一般处理同步操作)

vuex为什么不能直接操作实例化state。而是先通过commit一个mutations函数,然后再改变state的值呢?
答案: 因为每次提交mutations都会有一个记录, 更方便的记录每个记录改变的历史, 方便vue中的回滚,历史的操作

// 定义
CHANGE_NAME: (state,name) => {
        state.name = name;
}

// 使用    注意如果是封装成了modules,还需要加上例如 greatwall 这样的路径
this.$store.commit('greatwall/CHANGE_NAME','andy凌云')

actions(通过dispatch触发,一般处理异步操作)

// 定义: 其中CHANGE_NAME是mutations中定义的函数, view是传递的值
const actions = {
    changeName({commit, state}, view){
        commit('CHANGE_NAME', view)
    }
}

// 使用   注意如果是封装成了modules,还需要加上例如 greatwall 这样的路径
this.$store.dispatch('greatwall/changeName','andy')

getters(一般处理异步事件)

  1. 直接在store中写getters的方式
<div>
这里是store的getter---->{{this.$store.getters.newCount}}
</div>
// 定义
const getters = {
  sidebar: state => state.app.sidebar,
  size: state => state.app.size,
  device: state => state.app.device,
}
export default getters

//使用
return this.$store.getters.roles
  1. 将getters单独提取出来写getters.js的方式
export default {
    memberInfo(state) {
        if(state.userStatus === 0) {
            return "普通会员"
        } else if (state.userStatus === 1){
            return "vip会员"
        } else if(state.userStatus === 2) {
            return `高级${state.vipLevel}会员`
        } else {
            return "普通会员"
        }
    }
}    

5. 将v-model的值和vuex中的数据绑定上

<input v-model="message">

computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}
  1. 将各个功能注册到一个store下的index.js中
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'

Vue.use(Vuex)

const store = new Vuex.Store({
    state,
    mutations,
    actions,
    getters
})

export default store;

6. 解决刷新vuex的state状态就丢失的问题

可以在App.vue中进行处理。 添加beforeunload回调。 每次页面刷新时,将vuex里的信息保存在sessionStorege中。

created() {
    this.init();
},
methods: {
    init() {
      //在页面加载时读取sessionStorage里的状态信息
      if (sessionStorage.getItem("store")) {
        this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store"))))
      }

      //在页面刷新时将vuex里的信息保存到sessionStorage里
      window.addEventListener("beforeunload", () => {
        sessionStorage.setItem("store", JSON.stringify(this.$store.state))
      })
    }
}