1.简介
(1)vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库
vuex是为vue.js开发的状态管理模式、组件状态集中管理
(2)单页面数据流
状态发生变化, 视图就重新渲染
state发生变化时, 导致view视图发生改变, 视图通过操作action行为, 又会使得state状态发生变化
(3)使用场景
多个试图依赖于同一状态
来自不同试图的行为需要变更同一状态
2.使用
(1)安装
npm i vuex -save-dev
(2)创建保存数的容器store
//main.js文件中
// 引入
import { createStore } from 'vue'
// 创建Store vuex实例
const store = createStore({
state(){
return{
count: 0
}
}
})
// 注册全局组件
app.use(store)
(3)state获取store中的数据
在vue组件中通过 this.$store访问store实例, 通过实例的state属性获取对象
通过$store.state 获取数据, 无论在哪个组件都可以获取, 无需传递数据
方式1: 在模板语法中直接使用, 不需要添加this
<!-- 选项式API -->
<div>first---{{ $store.state.count }}</div>
<!-- 组合式API -->
方式2: 通过计算属性的方式使用
<template>
<div>firstName----{{ first }}</div>
<div>secondName----{{ second }}</div>
</template>
<script>
export default{
computed: {
first(){
return this.$store.state.firstName
}
}
}
</script>
方式3: 使用辅助函数 mapState
computed: mapState({
first: state => state.first,
// 不能使用箭头函数, 箭头函数中的this指向的是函数定义位置的上下文this
// 如果想使用this, 需使用普通函数
second(state){
return state.secondName + this.preName
}
}),
方式4: 当计算属性名称与store中的数据名称一样
computed: mapState(['firstName','secondName']),
方式5: 使用解构的形式 既可以包含各自组件中的计算属性, 也可使用store中的数据
computed: {
newList(){
return this.preName
},
// 解构出来, 相当于写了几个函数
...mapState({
first: state => state.first,
second(state){
return state.secondName + this.preName
}
})
},
(4)定义getters
可以认为是 store 的计算属性, 对状态的一个值进行计算后得到新的值
//直接在组件中使用
<div>{{ $store.getters.newName }}</div>
getters: {
newName (state){
return state.firstName.toUpperCase()
},
newSecond(state,getters){
return getters.newName + 'bbbb'
}
},
// 使用getters
...mapGetters(['newName','newSecond'])
<div>newName----{{ newName }}</div>
(5)mutation修改数据(同步)
不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation, mutation必须是同步函数
// 修改, 转变, 改变, 修改
mutations: {
// 每一个mutation 都必须是一个同步函数, 不能是异步: 如果是异步,页面刷新后,数据才更新
// 每个方法都有一个state参数,表示state返回的对象
updateData(state){
console.log(state);
state.count++
},
// 第一个参数必须是state, 从第二个参数开始是载荷 payLoad
// changeMsg(state, news){
// news = state.firstName
// state.msg += news
// }
// 使用 调用时传递的参数
changeMsg(state, payLoad){
state.msg += payLoad.news
}
},
使用
methods:{
// 方式 1 :
add(){
// 修改数据只能通过 commit
// 更新数据 调了 store中的mutations的updateData方法
this.$store.commit('updateData')
},
// 方式 2
change(){
this.$store.commit({
type: 'changeMsg',
news: 'hahaha'
})
}
}
(6)actions修改数据(异步)
mutations: {
updateData(state){
console.log(state);
state.count++
},
},
// 可包含任意异步操作, Action 提交的是 mutation,而不是直接变更状态。Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,可调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters
actions: {
// context 上下文 接受一个与 store 实例具有相同方法和属性的 context 对象 可接受参数, 从第二个参数开始为载荷
dispatchMsg (context) {
context.commit('updateData')
}
},
使用时, 通过dispatch分发
methods:{
disMsg(){
this.$store.dispatch('dispatchMsg')
// 以载荷形式分发
/* this.$store.dispatch('incrementAsync', {
amount: 10
})
// 以对象形式分发
this.$store.dispatch({
type: 'incrementAsync',
amount: 10
}) */
},
}
(7)module
将 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 的状态
(8)辅助函数
import { mapState,mapGetters, mapMutations, mapActions } from 'vuex'
mapState[computed]
mapGetters[computed]
mapActions[methods]
mapMutations[methods]
官方文档: