Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库
vuex实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享
优点:
1、vuex集中式管理共享数据,易于开发和后期维护
2、有效地实现组件之间数据共享
3、vuex中的数据都是响应式的,能够保持数据与页面的同步
一般情况下只有组件之间共享的数据,存储在vuex中,对于组件中的私有数据,存储在组件的data中。数据与页面的同步
1、安装
npm install vuex --save
2、在src目录下store目录中新建index.js,在index.js中声明Store’
index.js文件在文件中导入vue, vuex等, 并让vue引用vuex
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
strict: true,
state: { // 声明状态 相当于vue中的data,存放全局共享的数据
count:0,
},
mutations: {},
actions: {},
getters: {},
modules: {
user
},
})
export default store
3、导入store(将创建的共享数据挂载到vue实例中)
vue项目入口文件main.js中导入store并将其传入vue实例
import store from './store'
// ...
new Vue({ // eslint-disable-line
el: '#app',
router,
//将创建的共享数据挂载到vue实例中
//所有的组件,可以直接从store中获取全局的数据了
store,
template: '<App/>',
components: { App }
})
vuex属性 state、getters、mutations、actions、modules
state状态
state提供唯一的公共数据源,所有共享的数据都要统一放到store的state中进行存储
声明store时声明状态数据
export default new Vuex.Store({
state: {
// 声明状态 相当于vue中的data
count: 0,
},
mutations: {},
actions: {},
getters: {},
modules: {}
});
两种组件访问状态数据方式
1、this.$store.state.count //count是键名
<template>
<div >
{{$store.state.count}}
</div>
</template>
2、一个组件访问多个状态数据时的简写,从vuex中按需导入mapState函数
import { mapState } from 'vuex'
通过导入的mapState函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性:
computed:{
...mapState(['count','key2]) //映射函数,需要导入
}
注意:不能直接更改$store.state中的全局数据
mutaions状态(用于变更store中的数据)
1、只能通过mutations变更store数据,不可以直接操作store中的数据
2、集中监控所有数据的变化
声明store时声明方法
export default new Vuex.Store({
state: {
// 声明状态 相当于vue中的data
count: 0,
name: '曹操',
},
mutations: {
// 参1必须为 state 状态数据 参数2为可变参数 可传可不传 取决于自己
increment(state, payload) {
// payload.num获取参数字典中的num
state.count += payload.num
},
add(state){ //第一个形参就是当前的state对象
state.count++
}
},
actions: {},
getters: {},
modules: {}
});
1、组件内调用方法
this.$store.commit('store中的方法名',{参数1,参数2}),通过commit调用对应的mutations函数
2、映射组件调用方法
// 导入mapMutations
从vuex中按需导入mapMutations函数
import {mapState,mapMutations} from 'vuex'
通过导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法
export default {
methods: {
...mapMutations(["increment"])
}
}
注意:不能在mutations函数中,执行异步操作
action异步事件(用于处理异步任务)
1、如果通过异步操作变更数据,必须通过action,而不能使用mutation,但是在action中还是要通过触发mutation 的方式变更数据。
2、在actions中,不能直接修改state中的数据
3、必须通过context.commit()触发某个mutation,来修改state中的数据
改变state里面的数据,定义一个方法,两个参数,第一个参数为我们的store,第二个为我们的对象
action可以提交mutation,在action中可以执行store.commit,而且action中可以有任何的异步操作。在页面中如果我们要调用这个action,则需要执行store.dispatch
export default new Vuex.Store({
state: {},
mutations: {},
actions: {
// context和store 实例有着相同的方法和属性
async getChanels(context) { //context相当于store实例
// 异步请求后台获取数据 获取到返回数据时
const { data } = await
Axios.get('http://toutiao.itheima.net/v1_0/user/channels');
// 通过context触发已经声明好的方法 参数1为方法名 参数2为参数
context.commit('updateCount', data) //将我们的数据提交到我们的数据扭转工具中
}
},
getters: {},
modules: {}
});
访问方式1、触发action(组件内使用异步事件)
this.$store.dispatch('getChanels') // dispatch类似于我们的$emit方法
访问方式2、// 导入mapActions
1、从vuex中按需导入mapActions函数
import {mapActions} from 'vuex'
2、通过导入的mapActions函数,将需要的actions函数,映射为当前的methods方法
import {mapState,mapMutations,mapActions} from 'vuex'
export default {
methods: {
...mapActions(["getChanels"])
},
created(){
this.getChanels()
}
}
简化后 触发事件直接绑定action里边的方法
getter计算属性(getters只对store中的数据进行包装的作用)
1、getter用于对store中的数据进行加工处理形成新的数据(getter不会修改store中的源数据)
2、getter可以对store中已有的数据加工处理之后形成新的数据,类似vue中的计算属性
3、store中的数据发生变化,getter的数据也会跟着变化
访问方式1、this.$store.getters.名称
访问方式2、过导入的mapGetters函数,将需要的getters函数,映射为当前的computed方法:
<h3>{{formatUser}}</h3>
<a href="" v-for="(item) in formatUser" :key="item">{{item}}</a>
import {mapGetters} from 'vuex'
export default {
computed: {
...mapGetters(["formatUser"])
}
}
module模块
Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态