Vuex
Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变化。(类似于在前端的数据库,这里的数据存储在内存当中)
一、安装并配置
在项目的终端中写入如下的命令来安装Vuex:
npm install vuex --save
配置main.js文件,导入Vuex:
import Vuex from 'vuex'
Vue.use(Vuex);
- 它竟然可以存多个组件的状态,当然要进行相应的一个配置,所以此时我们在项目的
src目录下创建一个新的目录store,并在内部准备一个配置文件index.js
import Vue from 'Vue'
import Vuex from 'Vuex'Vue.use(Vuex);// 公共state对象,存储所有组件的状态
const state = {user: {name:''}
}// 唯一取值的方法,计算属性
const getters = {getUser(state) {return state.user;}
}// 唯一可以修改state值的方法,同步阻塞
const mutations = {updateUser(state, user) {state.user = user;}
}// 异步调用mutations方法
const actions = {asyncUpdateUser(user) {// context 是上下文的意思 针对的就是这个 js 文件// 且只能用 commit 进行调用mutations中的方法// 当调用actions中的方法也是只能dispatch进行调用context.commit('updateUser', user);}
}// 现在我们定义完了,此时就要将我们定义的内容暴露出去
export default new Vuex.Store({state,getters,mutations,actions
});
之后在main.js中配置文件,再次引入我们刚刚写好的store目录
import store from './store'

-
用户信息的添加和获取:


外界通过异步调用的方法,使用
dispatch()调用添加,但是本质上还是使用的是mutations中获取信息的方法(唯一修改方法)
二、解决浏览器刷新后Vuex数据消失问题
问题描述
Vuex的状态存储是响应式的,当Vue组件从store中读取状态的时候,若store中的状态发送变化,那么相应的组件也会得到高效的更新,但是有一个问题就是vuex的存储的数据只是在页面中的,相当于我们定义的全局变量,刷新之后,里面的数据就会恢复到初始状态。但是这种情况并不是我们所希望的
解决方案
监听页面是否刷新,如果页面刷新了,将state对象存入到sessionStorage中。页面打开之后,判断sessionStorage中是否存在state对象,如果存在,则说明页面是被刷新过的,将sessionStorage中存的数据取出来给vuex中的state赋值,如果不存在,说明是第一次打开,则取vuex中定义的state初始值
代码实现:
因为我们在任何一个组件中进行刷新,我们都需要判断,但是我们不可能每一个组件中都设置判断,所以我们干碎就直接定义为全局的组件,故需要在根组件
App.vue中设置监听刷新操作的事件
-
在
App.vue中添加监听刷新事件export default {name: 'App',mounted() {window.addEventListener('unload', this.saveState);},methods: {saveState() {window.sessionStorage.setItem('state', JSON.stringify(this.$store.state))}} } -
修改
store/index.js中的stateconst state = null != window.sessionStorage.getItem('state') ? JSON.parse(window.sessionStorage.getItem('state')) : {user: {name: ''} }
三、模块化
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就可能变得相当臃肿。为了解决以上的问题,Vuex允许我们将store分割成模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块一一从上至下进行同样方式的分割
-
创建
user模块在
store目录下创建一个名为modules的目录并创建一个名为user.js的文件,代码如下:const user = {state : {user: {name:''} }// 唯一取值的方法,计算属性 getters : {getUser(state) {return state.user;} }// 唯一可以修改state值的方法,同步阻塞mutations : {updateUser(state, user) {state.user = user;} }// 异步调用mutations方法actions : {asyncUpdateUser(user) {// context 是上下文的意思 针对的就是这个 js 文件// 且只能用 commit 进行调用mutations中的方法// 当调用actions中的方法也是只能dispatch进行调用context.commit('updateUser', user);}} }export default user;注意:定义的
user.js内部仍然是key : value格式的,且最外层拿上const user = {}包裹 -
修改
store/index.jsimport Vue from 'Vue' import Vuex from 'Vuex' import user from './modules/user'Vue.use(Vuex);// 现在我们定义完了,此时就要将我们定义的内容暴露出去 export default new Vuex.Store({modules : {user} });由于组件中使用的是
getters和actions处理,所以调用代码不变 -
修改
App.vueexport default {name: 'App',mounted() {window.addEventListener('unload', this.saveState);},methods: {saveState() {window.sessionStorage.setItem('userState', JSON.stringify(this.$store.state.user))}} }