【 web高级 01vue 】 vue预习课12 状态管理

vuex


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

一、安装

vue add vuex

二、起始

2.1 State

将应用全局状态定义在state中

vuex中
state: {
    
     
	isLogin: false 
}

2.2 Mutation

修改state只能通过mutation

vuex中
mutations: {
    
     
	login(state) {
    
     
		state.isLogin = true 
	},
	logout(state) {
    
    
		state.isLogin = false 
	} 
},

2.3 获取和修改状态

使用store.state获取状态

Login.vue中
<button @click="login" v-if="!$store.state.isLogin">登录</button> 
<button @click="logout" v-else>登出</button>

修改状态只能通过store.dispatch(mutation)

Login.vue中
this.$store.commit('login') 
this.$store.commit('logout')

2.4 Action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作
vuex中
actions: {
    
    
	//参数1是vuex传递的上下文context:{commit,dispatch,state}
	login({
    
     commit }, username) {
    
    
		//模拟登录api调用,1s钟以后如果用户名是admin则登陆成功
		return new Promise((resolve, reject) => {
    
    
			setTimeout(() => {
    
    
				if (username == "admin") {
    
    
					commit("login");
					resolve();
				} else {
    
    
					reject();
				}
			}, 1000);
		});
	},
},

派发动作

Login.vue中
this.$store.dispatch('login', 'admin').then(() => {
    
     	
	this.$router.push(this.$route.query.redirect) 
}).catch(() => {
    
     
	alert('用户名或密码错误') 
})

三、最佳实践

3.1 模块化

使用modules定义多个子模块利于组件复杂状态

store/index.js中
import user from './user' 
export default new Vuex.Store({
    
     
	modules: {
    
     user, } 
})

移动先前登录状态相关代码到user.js

store/user.js
export default {
    
     
	namespaced: true, // 避免命名冲突 // 
	... 
}

访问方式响应变化

Login.vue中
<button @click="login" v-if="!$store.state.user.isLogin">登录</button> 
Login.vue中
this.$store.dispatch('user/login', 'admin').then(() => {
    
     
	 this.$router.push(this.$route.query.redirect);
}).catch(() => {
    
     
	alert('用户名或密码错误') 
})
router/index.js中
store.state.user.isLogin

3.2 mapState() / mapMutation() / mapAction()

通过这些映射方法可以让大家少敲几个字,避免对$store直接访问。
state相关修改
Login.vue

Login.vue中
import {
    
     mapState } from 'vuex' 
computed: {
    
     
	...mapState('user', ['isLogin']) 
}
Login.vue中
<button @click="login" v-if="!isLogin">登录</button>

action相关修改

Login.vue中
import {
    
     mapActions } from 'vuex' 
methods: {
    
     
	...mapActions(['user/login', 'user/logout']) 
	login() {
    
     
		this['user/login']('admin').then(...) 
	},
	
},

3.3 Getter

可以使用getters从store的state派生出一些状态

store/user.js中

export default {
    
    
	namespaced: true, //设置独立命名空间,避免命名冲突
	state: {
    
    
		isLogin: false,
		username:""
	},
	mutations: {
    
    
		login(state,username) {
    
    
			state.isLogin = true;
			state.username = username;
		},
		logout(state) {
    
    
			state.isLogin = false;
			state.username = "";
		},
	},
	getters:{
    
    
		welcome : (state) => {
    
    
			return  state.username + ",欢迎回来"
		}
	},
	actions: {
    
    
		//参数1是vuex传递的上下文context:{commit,dispatch,state}
		login({
    
     commit }, username) {
    
    
			//模拟登录api调用,1s钟以后如果用户名是admin则登陆成功
			return new Promise((resolve, reject) => {
    
    
				setTimeout(() => {
    
    
					if (username == "admin") {
    
    
						commit("login",username);
						resolve();
					} else {
    
    
						reject();
					}
				}, 1000);
			});
		},
	},
};


getters的使用

 <span v-if="isLogin">
	{
   
   {welcome}}
	<button>注销</button>
</span>
App.vue中

import {
    
    mapState,mapGetters} from "vuex";

export default {
    
    
  computed: {
    
    
    ...mapGetters('user',["welcome"]),
    ...mapState('user',["isLogin"])
  },
}

四、严格模式

严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。开启严格模式 strict: true

const store = new Vuex.Store({
    
     
	// ... 
	strict: true 
})

五、插件

Vuex 的 store 接受 plugins 选项,这个选项暴露出每次 mutation 的钩子。Vuex 插件就是一个函数,它接收 store 作为唯一参数:

const myPlugin = store => {
  // 当 store 初始化后调用
  store.subscribe((mutation, state) => {
    // 每次 mutation 之后调用
    // mutation 的格式为 { type, payload }
  })
}

然后像这样使用:

const store = new Vuex.Store({
    
    
  // ...
  plugins: [myPlugin]
})

范例:实现登录状态持久化,store/plugins/persist.js

export default (store) => {
    
    
  //1.store初始化的时候,将存储在 localStorage 中的状态还原
  if (localStorage) {
    
    
    const user = JSON.parse(localStorage.getItem("user"));
    if (user) {
    
    
      store.commit("user/login", user.username);//login的mutations方法
    }
  }

  //2.如果用户相关状态发生变化,自动存入 localStorage
  //监听,订阅所有的 mutation
  store.subscribe((mutation, state) => {
    
    
    //mutation.type
    //{type:'user/login'}
    //{type:'user/logout'}
    //{type:'cart/addCart'}
    if (mutation.type === "user/login") {
    
    
      const user = JSON.stringify(state.user);
      localStorage.setItem("user", user);
    } else if (mutation.type === "user/logout") {
    
    
      localStorage.removeItem("user");
    }
  });
};

store/index.js中

import Vue from "vue";
import Vuex from "vuex";
import user from "./user";
import persist  from './plugins/persist'

Vue.use(Vuex);

export default new Vuex.Store({
    
    
  strict: true,
  modules: {
    
    
    user,
  },
  plugins:[persist]
});


//页面一刷新,登录状态就变成false
//数据持久化
//插件

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42580704/article/details/111120337