Vuex
- vuex是什么(有什么用)
- 概念介绍及使用方法
1. 什么是vuex
官网描述如下
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
store和全局变量的区别
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
通俗的理解
- Vuex是一个仓库(store),用来保存组件间的状态(比如两个组件之间有事件交互需要一些状态量)。
2.这个状态量是响应式的,并且通过commit到mutation进行修改
为什么要用vuex
其实通过子组件$emit可以通过事件传递将父组件的状态量进行改变,父组件也可以通过子组件的props属性传递参数给子组件,但是这样存在的问题是当项目很大的时候,这样传递很麻烦,用vuex就相当于把这些状态量都从组件中抽离出来, 如果用模块化编程我们要使用Vue.use(‘vuex’)来导入,然后store保存在store.js中,再main.js中导入store.js即可
2. 概念介绍
为了具体了解 先上一波简单的代码
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
status: false,
n: 0
},
mutations: {
toggle(state, addN) {
const innerState = state;
innerState.status = !innerState.status;
innerState.status += addN;
},
},
actions: {
},
});
这里先介绍三个常用功能(基本上够用)
1. state: 用来保存的是公共的全局变量,这里定义了status和n
2. mutation: 如果在子组件中需要来修改status或者n, 那么一定是通过子组件中调用mutation中的方法对state中的参数进行修改
这里抛出两个问题:(1)子组件如何修改store中的参数 (2)当store中的参数修改时,子组件如何响应监听数据
子组件如何修改store中的参数
// subComponent1.vue
methods(){
iconFilter(idx) {
this.$store.commit('toggle', 1);
},
}
定义在vue对象中的methods方法中,通过this.$store指向我们的store仓库,然后commit方法来调用toggle方法,这里要注意toggle传入的为函数名(字符串), 1 为传入的参数,就是定义的toggle方法中的addN, 这里传参的时候特别注意!!只有一个传参位,多个参数尽量打包成一个对象进行书写
// 错误
// store.js
toggle(state, a1, a2, a3) {
const innerState = state;
innerState.status = !innerState.status;
innerState.status += a1;
},
// subComponents1.vue
this.$store.commit('toggle', 1, 2, 3);
// 这里a2, a3都无法拿到
// 正确做法
// store.js
toggle(state, a) {
const innerState = state;
innerState.status = !innerState.status;
innerState.status += a.a1;
},
// subComponents1.vue
this.$store.commit('toggle', {a1: 1, a2: 2, a3: 3});
子组件如何监听响应
这里用到两个重要的vue对象属性,计算属性computed和侦听器watch
不熟悉的可以看官方文档 vue官方文档
// subComponents2.vue
computed: {
showType() {
return this.$store.state.status;
},
},
watch: {
showType: {
handler(newV) {
console.log(newV);
// 业务代码,响应newV
},
deep: true,
},
},
先定义了一个computed 的计算属性showType,这个值就是指向我们的store里面的state.status
然后我们听过监听showType, 当showType更改的时候我们响应式的更改视图
这里说一下 deep: true 做深度监听,因为如果这里status是一个对象,我们通过对对象的属性赋值他是不会触发这个监听属性的
这里很关键!!!!
3. Action属性
上面两个基本能够满足大多数的需求,在这里在介绍一下actions属性,action与mutation的主要区别
- 提交的是mutation, 相当于通过控制mutation控制state的变化,本身不直接控制state的变化
- 可以支持异步操作,mutation一定是同步操作
// store.js
actions: {
asynConsole(context) {
setTimeout(() => {
commit('counter');
}, 1000);
},
},
// subComponents1.vue
this.$store.dispatch('asynConsole');
// subComponents2.vue
computed: {
resetCounter() {
return this.$store.state.count;
},
},
watch: {
resetCounter: {
handler(newV) {
console.log(newV);
},
deep: true,
},
}
这里传入的context指向的是this.$store
当触发asynConsole的时候 会过1s再输出1 2 3 4 等等