Vuex

基本概念

Vuex 是状态管理工具。集中式存储管理 应用的所有组件的状态,可以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里面,并将这个变量放在顶层的Vue实例中,让其他组件可以使用,并且实现了响应式。
那么什么状态需要多个组件间共享呢?
例如:用户的登录状态、用户名称、头像、地理位置信息 以及 商品的收藏、购物车中的物品等。

安装

npm install vuex --save

基本结构

├── src
  ├── index.js       入口js
  ├── App.vue
  ├── components
  │ ├── HelloWorld.vue
  │ └── …
  └── store
   ├── index.js   我们组装模块并导出 store 的地方
   ├── mutations-types.js    定义类型常量

index.js:

import Vue from 'vue';
import store from './store';
import App from './App.vue';

Vue.config.Vue.config.productionTip = false;

new Vue({
  el: '#root',
  store,  // 挂载之后,每个组件都有一个 $store 对象
  render: h => h(App)
});
store/index.js:

import Vue from 'vue';
import Vuex from 'vuex';

//安装插件
Vue.use(Vuex)

//创建并导出对象store
export default new Vuex.Store({
  state:{
  	counter : 0
  },
  mutations:{},
  actions:{},
  getters:{},
  modules:{}
})

每个组件都有一个 $store 对象 , $store 对象有 state 、mutation 、actions 、getters 、modules 属性, 所以各个组件可以通过 ** $store . state . counter ** 来使用此处定义的属性或者方法;通过 this. $state . commit ( mutation 中定义的方法 ) 来修改状态。

【注意】我们通过提交mutation 的方式修改状态,而不是直接更改 $store . state . counter ,这是为了devtools 该工具更明确的追踪状态的变化

getters

getters 相当于计算属性

使用方式一:内部定义的方法默认的参数是 state

getters : {
	powerCounter (state) {
		return state.counter * state.counter
	}
}
<h2>{ $store.getters.powerCounter }</h2>

使用方式二:还能传递另一种参数,就是 getters 本身

getters : {
	//筛选年龄大于20的学生
	more20stu (state) {
		return state.students.filters(s => s.age > 20)
	},
	//求出年龄大于20的学生的数量
	more20stuLength ( state , getters ) {
		return getters.more20stu.length
	}
}
<h2>{ $store.getters.more20stu }</h2>
<h2>{ $store.getters.more20stuLength }</h2>

使用方式三:getters 本身不能传递其他参数,若想传递其他参数,需要return 一个函数

getters : {
	//筛选年龄大于age的学生,age 为传递的参数
	moreAgestu (state) {
		return function (age) {
				return state.students.filters(s => s.age > age)
		}
	},
}
<!-- 年龄大于18 -->
<h2>{ $store.getters.moreAgestu(18) }</h2>

mutations

更改 store 中state 状态的唯一方式是 : 提交 mutation
mutation 中的方法必须是 同步 方法
mutation 的默认第一个参数是 state

使用方式

使用方式一:不传自定义参数
1、定义mutation:

mutations : 
	increment ( state ) {     //   state 是默认参数
		state.counter ++
	}
}

2、在事件发生的组件中定义函数,在此函数内部提交mutation:

	methods : {
		addition () {
			this.$store.commit ( ' increment ' )
		}
	}

使用方式二:传一个自定义参数
1、定义mutation:

mutations : 
	increment ( state  , num) {
		state.count += num
	}
}

2、在事件发生的组件中定义函数,在此函数内部提交mutation:

	methods : {
		addition ( num ) {
			this.$store.commit ( ' increment ' , num )
		}
	}

使用方式三:传多个自定义参数,需要传递一个 payload 对象
1、定义mutation:

mutations : 
	increment ( state  , payload) {
		state.counter +=  payload.num
	}
}

2、在事件发生的组件中定义函数,在此函数内部提交mutation:

	methods : {
		addition ( num ) {
			this.$store.commit ( {
			type :  ' increment ',
			num
			} )
		}
	}

类型常量

在 store 文件下新建一个 mutations-types.js

store/mutations-types.js:

export const INCREMENT = 'increment'
store/index.js:

import Vue from 'vue';
import Vuex from 'vuex';

//导入mutations的类型常量
import {
	INCREMENT
} from './mutations-type.js'

//安装插件
Vue.use(Vuex)

//创建并导出对象store
export default new Vuex.Store({
  state:{
  	counter : 0
  },
  mutations:{
  	// 使用类型常量
  	[INCREMENT](state){
  		state.counter ++
  	}
  },
  actions:{},
  getters:{},
  modules:{}
})
App.vue:

<script>
	//导入mutations的类型常量
	import {
		INCREMENT
	} from './store/mutations-type.js'

	export default {
		name: 'App',
		data(){},
		methods : {
 		addition ( num ) {
 			this.$store.commit ( INCREMENT )  // 使用类型常量
 		}
 	}
	}
</script>

actions

actions 中的默认第一个参数context
actions 中的方法必须是 异步 方法
mutation 更改属性,actions 用 commit 提交mutation , 组件里的方法用 dispatch 提交 actions

基本使用方法

store/index.js:

mutations : {
	updateInfo (state) {
		return state.info.name = 'sea'
	}
},
actions : {
	aUpdateInfo (context) {
		setTimeout( () => {
			context.commit('updateInfo') // commit( ' mutations方法 ' )
		} , 1000)
	}
}
App.vue:

methods : {
	update(){
		this.$store.dispatch('aUpdateInfo')  // dispatch( ' actions方法 ' )
	}
}

actions 传递参数

actions 的第二个参数payload , 当传递多个参数时,就传递一个 payload 对象

store/index.js:

mutations : {
	updateInfo (state) {
		return state.info.name = 'sea'
	}
},
actions : {
	//传递 payload 形参
	aUpdateInfo (context , payload) {
		setTimeout( () => {
			context.commit('updateInfo') // commit( ' mutations方法 ' )
			console.log( payload.message )
		} , 1000)
	}
}
App.vue:

methods : {
	update(){
		//传递 payload 实参
		this.$store.dispatch('aUpdateInfo' , {
			message : 'Hello',
			fn : function(){}
		})  // dispatch( ' actions方法 ' )
	}
}

异步 actions 执行成功后,通知组件并执行其他代码

利用 Promise:

store/index.js:

mutations : {
	updateInfo (state) {
		return state.info.name = 'sea'
	}
},
actions : {
	//传递 payload 形参
	aUpdateInfo (context , payload) {
	
		return new Promise(resolve , reject ){
		
			setTimeout( () => {
				context.commit('updateInfo') // commit( ' mutations方法 ' )
				console.log( payload );
				
				resolve('执行成功')
			} , 1000)
		}
	}
}
App.vue:

methods : {
	update(){
		//传递 payload 实参
		this.$store
			.dispatch('aUpdateInfo' , "我是 payload ")
			
			.then(
				res => { console.log (res) }
			)
	}
}

优化:Vuex的辅助函数mapState,mapGetters, mapActions, mapMutations用法

computed : {
	count () {
		return this.$store.state.count
	}
}

优化为:

import { mapState, mapMutations, mapGetters, mapActions } from 'vuex'

computed : {
	...mapState(['count']),
	...mapGetters(['evenOrodd'])
}
methods : {
	...mapMutations({
		increment : 'INCREMENT',
		decrement : 'DECREMENT'
	})
}
### Vuex 的核心概念与使用方法 Vuex 是专门为 Vue.js 设计的一个状态管理模式,用于集中管理应用中的状态。通过 Vuex,可以更方便地处理组件间的全局状态以及复杂的组件间通信。 #### 1. 安装与初始化 在项目中引入 Vuex 需要先安装依赖包 `vuex` 并将其注册为 Vue 插件[^1]: ```javascript import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: { count: 0, }, mutations: {}, actions: {}, getters: {} }); export default store; ``` #### 2. 创建简单的 Vuex Store 创建一个基本的 Vuex Store 可以定义四个主要部分:`state`, `mutations`, `actions`, 和 `getters`[^1]。下面是一个完整的简单示例: ```javascript // store/index.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { // 存储数据的地方 count: 0, }, mutations: { // 同步修改 state 的唯一方式 increment(state) { state.count++; } }, actions: { // 提交 mutation 的地方,支持异步操作 incrementAsync({ commit }) { setTimeout(() => { commit('increment'); }, 1000); } }, getters: { // 访问经过计算后的 state 数据 doubleCount(state) { return state.count * 2; } } }); ``` #### 3. 模块化组织状态 对于较大的应用程序,推荐将 Vuex Store 划分为模块来提高可维护性和清晰度[^2]。每个模块都可以拥有自己的 `state`, `mutations`, `actions`, 和 `getters`: ```javascript // store/modules/exampleModule.js const exampleModule = { namespaced: true, // 开启命名空间 state() { return { text: 'Hello Vuex Module', }; }, mutations: { updateText(state, newText) { state.text = newText; } }, actions: { changeText({ commit }, payload) { commit('updateText', payload); } }, getters: { getText(state) { return state.text.toUpperCase(); } } }; export default exampleModule; // store/index.js import Vue from 'vue'; import Vuex from 'vuex'; import exampleModule from './modules/exampleModule'; Vue.use(Vuex); export default new Vuex.Store({ modules: { example: exampleModule } }); ``` #### 4. 状态持久化 为了防止页面刷新丢失状态,可以通过插件 `vuex-persistedstate` 将 Vuex 中的状态保存到浏览器的本地存储中[^3]: ```bash npm install vuex-persistedstate ``` 配置如下所示: ```javascript // store/index.js import createPersistedState from 'vuex-persistedstate'; import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { user: null, }, plugins: [ createPersistedState() ] }); ``` #### 5. Vuex 常见问题解答 - **何时应该使用 Vuex?** 当存在多组件共享状态、组件间通信复杂或者需要多个视图监听同一状态变化时,建议采用 Vuex 来统一管理和分发这些状态[^3]。 - **如何与 Vue Router 结合使用?** 可以在路由守卫中调用 Vuexaction 方法完成权限校验或其他逻辑处理[^3]: ```javascript router.beforeEach((to, from, next) => { if (to.meta.requiresAuth && !store.getters.isAuthenticated) { next('/login'); // 如果未登录则跳转至登录页 } else { next(); // 继续导航 } }); ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值