VUEX的使用

VUEX文档

概念

vuex 是 Vue 配套的 公共数据管理工具,它可以把一些共享的数据,保存到 vuex 中,方便整个程序中的任何组件直接获取或修改我们的公共数据;即Vuex是一个全局的共享数据存储区域,就相当于是一个数据的仓库。

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

使用步骤

  1. 安装包cnpm i vuex -S

  2. 导入包import Vuex from 'vuex',前提是要导入VUE包import Vue from 'vue'

  3. 将vuex注册到vue中Vue.use(Vuex)

  4. new Vuex.Store() 实例,得到一个数据仓储对象

    var store = new Vuex.Store({
       state: {
     	 isLogin : false,
     	 username:' '
       },
      mutations: {
    		login(state){
    			state.isLogin = true,
    			state.username = username
    		},
    		loginout(state){
    			state.isLogin = false
    		},
       },
        getters: {
    	    welcome: function (state) {
    	      return '欢迎:' + state.username
    	    }
         },
         actions:{
    		login({commit}, username) {
    			return new Promise((resolve, reject) => {
    				setTimeout(() => {
    				//模拟用户登录完成后调用increment
    					if (username === 'admin') {
    						commit('login',username)
    						resolve()
    					} else {
    						reject()
    				}}, 1000);
    			})
    		}
         }
    })
    
  5. 将 vuex 创建的 store 挂载到vue实例上, 这样任何组件都能使用 store 来存取数据

    const vm = new Vue({
      el: '#app',
      render: c => c(App),
      store
    })
    

vue-cli安装:vue add vuex

核心概念

  1. state
  • state 相当于组件中的 data ,专门用来存储数据的
  • 如果在组件中,想要访问store 中的数据,可以通过 this.$store.state.*** 来访问
  1. mutations
  • 如果要操作 store 中的 state 值,只能通过调用 mutations 提供的方法,才能操作对应的数据,不推荐直接操作 state 中的数据,因为 万一导致了数据的紊乱,不能快速定位到错误的原因,因为,每个组件都可能有操作数据的方法;
  • mutations 相当于组件中的方法,可以通过 this.$store.commit('方法名')
  • 这种调用 mutations 方法的格式,和 this.$emit('父组件中方法名')相似。
  • 在这里定义的方法最多支持两个参数,参数1 是 state 状态; 参数2是 通过 commit 提交过来的参数; 由于参数只能有两个参数,所以如果要传多个参数,可以以对象的形式把参数传过来
  1. 派生状态getters

    已经有了一些状态,可以对这些状态做一些操作,得到一些新的状态,getters是一旦原有状态发生变化,这些派生的状态也跟着变化,其实是计算属性在vuex中的迁移

  • getters 中的方法, 和组件中的过滤器比较类似,过滤器和 getters 都没有修改原数据, 都是把原数据做了一层包装,提供给了调用者;
  • getters, 只负责对外提供数据,不负责修改数据,如果想要修改 state 中的数据,请去找 mutations
  • getters 和 计算属性computed 比较像, 只要function 内部,所用到的任何数据发生变化时,就会立即触发 getters 的重新求值;
  • getters 可以通过 this.$store.getters.方法名调用
  • getters 的方法必须return一个值
  1. action
  • action 提交的是 mutation,而不是直接变更状态。

  • action可以包含任意异步操作。

  • 参数1是vuex传递的上下文context:{commit,dispatch,state},参数2是通过dispatch提交过来的参数

  • action 可以通过 this.$store.dispatch.方法名调用,如下

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

模块化

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

1.创建子模块并导出它
在这里插入图片描述
user.js:

export default {
	  namespaced: true, 
	  state: {
	 	 isLogin : false
	   },
	  mutations: {
			login(state){
				state.isLogin = true
			},
			loginout(state){
				state.isLogin = false
			},
	   },
	    getters: {
	
         },
         actions:{
			login({commit}, username) {
				return new Promise((resolve, reject) => {
					setTimeout(() => {
						if (username === 'admin') {
							commit('login')
							resolve()
						} else {
							reject()
					}}, 1000);
				})
			}
         }
	}

注意:要设置namespacedtrue,避免多个子模块命名冲突

  1. 在index.js中导入子模块,并在modules中注册模块
import Vue from 'vue
import Vuex from 'vuex' 
import user from './user' 

vue.use(Vuex)

export default new Vuex.Store({
	modules:{
		user 
	}
})
  1. 在入口文件中引入
new Vue({
	router,
	store,
	render:h=>h(App)
}).$mount('#app')

访问方式响应变化,访问子组件时要加上命名空间

// 在state后加上命名空间后访问
<button @click="login" v-if="!$store.state.user.isLogin">登录</button>

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

mapState()/mapMutation()/mapAction()/mapGetters

通过这些映射方法可以让大家少敲几个字,避免对$store直接访问。
访问state:

//在对应的子组件中引入mapState
import { mapState } from 'vuex'

computed: {
	...mapState('user', ['isLogin'])  //this.$store.state.user.isLogin
	//在html中可以直接使用isLogin访问,mapStateu全部在computed使用
}

访问action

import { mapActions } from 'vuex'

methods: {
	login() {
	this['user/login']('admin').then(...)   //  this.$store.dispatch("user/login",admin).then(...)
},
...mapActions(['user/login', 'user/logout'])
},

访问actiongetters

import { mapGetters } from 'vuex'

computed: {
	...mapGetters ('user', ['welcome'])    //this.$store.getters.welcome
		//在html中可以直接使用welcome访问
}

注:映射的名字不要和data中的变量冲突

严格模式

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

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

vuex插件

Vuex 的 store 接受 plugins 选项,这个选项暴露出每次 mutation 的钩子。Vuex 插件本身是一个函数,它的形参是当前的store实例

const myPlugin = store => {
	// 当 store 初始化后调用
}

注册插件:

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

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

步骤1:创建plugins目录和js插件persist.js
在这里插入图片描述
步骤2:完成插件功能,并导出

export default store => {
	// 初始化时从localStorage获取数据
	if(localStorage) {
		const user = JSON.parse(localStorage.getItem('user'))
		if (user) {
			store.commit('user/login')
			store.commit('user/setUsername', user.username)
		}
	}
	
	// 用户状态发生变化时缓存之
	 //vuex的API  subscribe,可以订阅所有的mutation,只要mutation有变化就执行这个回调函数
	store.subscribe((mutation, state) => {  
		if (mutation.type === 'user/login') {     //调用登录方法时存储登录信息
			localStorage.setItem('user', JSON.stringify(state.user))
		} else if (mutation.type === 'user/logout') {   //调用注销方法时删除登录信息
			localStorage.removeItem('user')
		}
	})
}

vuex的API subscribe,可以订阅所有的mutation,只要mutation有变化就执行这个回调函数
mutation.type返回调用的mutation中的方法名,如果是子组件的,就返回组件名/方法名

步骤3:在index.js中导入插件,并在plugins中注册插件

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({
	modules:{
		user 
	},
	plugins:[persist ],   //注册插件
	strict: true
	
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值