Vuex (替代父子组件通信和跨层级通信的库)
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。---- 工具,用于管理应用中组件间共享的状态(数据)
采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
概念
store
:仓库,用于集中式管理state
:状态,应用中组件要共享的数据mutation
:同步更新状态数据的函数,在 vuex 中仅能提交 mutation 来更新状态数据action
:和mutation
类似,但可以包含异步操作,不能直接更新状态,而是要提交mutation
更新getter
:是store
中的计算属性module
:模块,每个模块可以有自己的state、mutation、action、getter
,甚至自己的module
使用方法
安装
$ npm i vuex@3.6.2
# 或
$ yarn add vuex@3.6.2
在cmd中输入上面的其中一个指令安装即可。
创建 Store
第一步
1.先在src文件夹中添加一个新的文件夹取名 store
。
2.在 store
文件夹中新建一个 index.js
的文件夹,在这个新建的文件夹内引入 Vuex 和创建 Store(仓库,用来存放共享的数据)。
固定写法:
import Vue from 'vue'
import Vuex from 'vuex'
// 使用核心插件 Vuex
Vue.use(Vuex)
// 创建 Store
const store = new Vuex.Store({
state: { // 组件间共享的数据
todos: [],
},
getters: { // store 的计算属性
/**
* 是否所有都完成
*/
allChecked (state) {
return state.todos.every(todo => todo.completed)
},
/**
* 已完成的数量
*/
completedCount (state) {
return state.todos.filter(todo => todo.completed).length
},
/**
* 所有数量
*/
allCount (state) {
return state.todos.length
}
},
mutations: { // 唯一进行同步更新状态数据的方法
/**
* 添加新待办事项
*/
addTodoItem(state, payload) {
state.todos.push({
id: Math.random(),
title: payload.title,
completed: false,
})
},
},
})
export default store
第二步 向根实例中注入 store
一般在命名为 main.js
的根实例中引入,store
示例:
import Vue from 'vue'
// 引入 store
import store from './store' // import store from './store/index.js'
new Vue({
store, // 注入 store,这样,在所有后代组件中,都可以使用 this.$store 获取 vuex 的 Store 使用
// render: h => h(App),
}).$mount('#app')
第三部 在组件中使用 store
1.在组件中使用公用数据,可以调用存放在 store
当中的数据。
<template>
<div class="todo-list">
// 在这使用刚才调用的数据
<todo-item v-for="todo in todos" :key="todo.id" :todo="todo"></todo-item>
</div>
</template>
computed: { // 使用公用数据
todos () {
return this.$store.state.todos
}
}
2.修改存放在**store
** 的数据,先在store
中的mutations
方法中定义一个事件处理函数,然后在组件中用this.$store.commit(mutationType, payload)
定义函数接收,在标签中用v-on
方法来执行函数执行
mutations: { // 唯一进行同步更新状态数据的方法
/**
* 添加代办事项
*/
addTodoItem (state, payload) {
state.todos.push({
id: Math.random(),
title: payload.title,
completed: false
})
},
<template>
<div class="todo-input">
<input type="text"
placeholder="请输入代办事项"
v-model="inputValue"
@keydown.enter="handleAdd" // 用v-on 方法执行函数
ref="inputRef"
>
</div>
</template>
methods: { // 修改公用数据
handleAdd () {
// Vuex 的 store 的 mutation 方法,在组件中不能直接调用到。
// 需要使用 store.commit(定义的函数名称,payload) 来提交 mutation 调用。
//this.$store.commit('store中定义的事件处理函数', { 处理事件需要用到的参数,对象的形式填写如//(title: this.inputValue)})
this.$refs.inputRef.focus()
if (!this.inputValue) {
return alert('内容不能为空!!!')
}
this.$store.commit('addTodoItem', { title: this.inputValue })
this.inputValue = ''
}
}
}
3.stoare
中的 getters
计算属性,在 stoare
中使用 getters
来定义处理计算事件的函数。
定义:
getters: { // store 的计算属性
/**
* 是否所有都完成
*/
allChecked (state) {
return state.todos.every(todo => todo.completed)
},
/**
* 已完成的数量
*/
completedCount (state) {
return state.todos.filter(todo => todo.completed).length
},
/**
* 所有数量
*/
allCount (state) {
return state.todos.length
}
},
使用:
<template>
<div class="todo-footer">
<label for="checkbox"> // 调用计算函数
<input type="checkbox" id="checkbox" :checked="allChecked" @change="handleChange">全选
<span> 已完成 ({{ completedCount }}) 项 / 共 ({{ allCount }})项</span> // 调用计算函数
</label><br>
<button @click="emptyTodo">删除全部代办事项</button>
</div>
</template>
computed: {
...mapGetters(['allChecked', 'completedCount', 'allCount']) //辅助函数等价于下面注释掉的函数
// allChecked () { // 全选框状态
// return this.$store.getters.allChecked
// },
// completedCount () { // 单选框状态
// return this.$store.getters.completedCount
// },
// allCount () { // 所有数量
// return this.$store.getters.allCount
// }
},
辅助函数:
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'