Vuex概述
是什么:
vuex是一个vue的状态管理工具,状态就是数据。
Vuex是一个插件,可以帮我们管理vue通用的数据(多组件共享的数据)
例如:购物车数据、个人信息数据
场景:
1)某个状态在很多个组件来使用(个人信息)
2)多个组件共同维护一份数据(购物车)
优势:
1)共同维护一份数据,数据集中化管理
2)响应式变化
3)操作简洁(vuex提供了一些辅助函数)
构建vuex[多组件数据共享]环境
为了练习先不勾选Router和Vuex,后期练习熟练时,可以加上
后面选项与下文中介绍一致即可
创建一个空仓库
前期创建项目时没有勾选vuex,所以需要安装,练习熟练后,可以前期勾选vuex。
Vue2->VueRouter3.x+Vuex3.x
Vuex3.x官方文档:Vuex 是什么? | Vuex
Vue3->VueRouter4.x+Vuex4.x
在src下创建store文件夹,再创建index.js
// 这里面存放的就是vuex相关的核心代码
import Vue from 'vue'
import Vuex from 'vuex'
// 插件安装
Vue.use(Vuex)
// 创建仓库(空仓库)
const store = new Vuex.Store()
// 导出给main.js使用
export default store
main.js中添加
import store from '@/store/index'
new Vue({
render: h => h(App),
store
}).$mount('#app')
验证是否配置仓库成功,任意找一个组件使用如下代码
created () {
console.log(this.$store)
}
如下为成功;如果是undefined,则失败
提供&访问vuex的数据(State&mapState)
提供数据
State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储。
在state对象中可以添加要共享数据。
state状态即数据,类似于vue组件中的data
区别:
1.data是组件自己的数据
2.state是所有组件共享的数据
const store = new Vuex.Store({
state:{
count:101
}
})
使用数据
1)通过store直接访问
template模块中:{{$store.state.xxx}}
export default组件逻辑中:this.$store.state.xxx
JS文件中:
import store from '@/store/index'
store.state.xxx
2)通过辅助函数(简化)
mapState是辅助函数,帮助我们把store中的数据自动映射到组件的计算属性中
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['count', 'title'])
}
}
在template中直接使用{{count}}访问
修改Vuex中的数据(mutations&mapMutations)
vuex同样遵循单向数据流,组件中不能直接修改仓库的数据
通过strict:true可以开启严格模式,新手可以开启及时纠错,正式上线时移除
const store = new Vuex.Store({
// 开启严格模式
strict: true,
state: {
count: 100,
title: '共享数据'
}
})
state数据的修改只能通过mutations(修改)
mutations基本语法
1.定义mutations对象,对象中存放修改state的方法
const store = new Vuex.Store({
// 1.state提供数据
state: {
count: 100,
title: '共享数据'
},
// 2.mutations提供修改数据的方法
mutations: {
// 所以mutation函数,第一个参数,都是state
addCount (state) {
state.count++
}
}
})
2.组件中提交调用mutations
methods: {
handleAdd () {
this.$store.commit('addCount')//与store仓库中的mutations方法名一致
}
}
mutations传参语法
1.提供mutation函数(带参数-提交载荷payload)
mutations: {
addCount (state, n) {
state.count+=n
}
}
2.页面中提交调用mutation
this.$store.commit('mutations方法名',参数)
不支持传递多个参数,可以写成对象的形式,传递多个参数
handleAdd (n) {
this.$store.commit('addCount', {
count: n,
msg: ''
})
}
mutations: {
addCount (state, obj) {
state.count += obj.count
}
}
练习--输入框修改数据
<input type="text" :value="count" @input="handleCount"/>
methods: {
handleCount (e) {
this.$store.commit('handleCount', e.target.value)
}
}
mutations: {
handleCount (state, count) {
state.count = count
}
}
辅助函数:mapMutations
mapMutations和mapState很像,它是把位于mutations中的方法提取了出来,映射到组件methods中
import { mapMutations } from 'vuex'
methods: {
...mapMutations(['addCount']),//映射mutations方法
handleAdd (n) {
this.addCount(n)//调用
}
}
处理异步操作(actions&mapActions)
需求:一秒钟之后,修改state的count成999
说明:mutations必须是同步的(便于监测数据变化,记录调试)
1.提供action方法
注意:不能直接操作state,操作state还是需要commit、mutation
操作mutation里的方法使用context.commit('mutation方法名',额外参数)
操作getters里的属性使用context.getters.属性名
actions:{
//context上下文(此处未分模块,可以当成state仓库)
//context.commit('mutation方法名',额外参数)
setAsyncCount(context,num){
// 这里是setTimeout模拟异步,以后大部分场景是发请求
setTimeout(()=>{
context.commit('changeCount',num)//再调用mutation中的方法
},1000)
}
}
2.页面中dispatch调用
this.$store.dispatch('actions中的方法名',参数值)
辅助函数:mapActions
mapActions是把位于actions中的方法提取了出来,映射到组件methods
import { mapActions } from 'vuex'
methods: {
...mapMutations(['setAsyncCount']),//映射actions方法
handleAdd (n) {
this.setAsyncCount(n)//调用
}
}
类似于计算属性(getters)
说明:除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters,只有获取没有修改,修改只能靠mutation
例如:state中定义了list,为1-10的数组,组件中,需要显示所有大于5的数据
state:{
list:[1,2,3,4,5,6,7,8,9,10]
}
1.定义getters
注意:
1)getters函数的第一个参数是state
2)getters函数必须要有返回值
getters:{
filterList(state){
return state.list.filter(item=>item>5)
}
}
2.访问getters
1)通过store访问getters
{{$store.getters.filterList}}
2)通过辅助函数mapGetters
computed:{
...mapGetters(['filterList'])
}
{{filterList}}
3)在getters中访问getters的其他属性
Getter 也可以接受其他 getter 作为第二个参数
getters: {
// ...
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
跨模块调用
若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true }
作为第三参数传给 dispatch
或 commit
即可。
context.commit('模块名/方法名', 参数, { root: true })
context.dispatch('模块名/属性名', 参数, { root: true })