Vuex
-
父组件向子组件传值 props
-
子组件向父组件传值 $emit
-
非父子组件之间传值:爷孙、兄弟
基于Vue实现发布订阅者模式(代码比较乱,不建议使用)
// 中介
const event = new Vue();
// 订阅事件
event.$on('event-b', (param) => {
console.log(param); // 666
});
// 发布事件
event.$emit('event-b', 666)
所以,Vuex状态管理的存在是十分有必要性
Vuex是一个专为Vue.js应用的程序开发的状态管理模式。采用集中式存储应用(统一管理,存储/变更)的所有组件的状态,非常方便地进行复杂组件之间的数据传递(非父子关系)。
- state 管理组件数据,管理的数据是响应式的,当数据改变时驱动试图更新
- mutations 更新数据,state中的数据只能使用mutation去改变数据(只能处理同步的场景)
- actions 处理异步场景,处理成功后把数据提交给mutations,进而更新state
- getters 相当于在state和组件之间添加一个环节(对state中的数据进行加工处理后再 提供给组件),不直接修改state中的数据
初始化项目
基于脚手架初始化项目,(1)初始化store对象(2)把store对象挂载到Vue实例中
npm i Vuex --save/-S
- 将Vuex挂载到main.js中
import store from './Vuex'
new Vue({
// 把store对象挂载到Vue实例对象中,这样就可以在所有的组件中获取store中的数据了
store,
render: h => h(App),
}).$mount('#app')
- 在实际项目中,为方便管理,将Vuex文件拆分成这样
除index.js(为主)的文件,其他文件只需要export default
导出相应的字段(变量);
而index.js内容:
"use strict";
import state from "./state"
import getters from "./getter"
import mutations from "./mutation"
import actions from "./action"
import Vue from 'vue'
import Vuex from "vuex"
Vue.use(Vuex);
export default new Vuex.Store({
state,
getters,
mutations,
actions,
});
状态state
- 管理数据
// 因为之前拆分,可直接使用let\const 来定义变量
// state中的数据是自定义的,但是state属性名是固定的
let userName = '乐知者',
const sex = '1',
export default {
userName,
sex
}
- 组件中获取 state 中的数据,使用原始用法 插值表达式
<div> 第一组件 state的数据: {{$store.state.userName}}</div>
<div> 第二组件 state的数据: {{userName}}</div>
- 使用计算属性中 使用方法
computed: {
// 把state中的数据,定义在组件内的计算属性中
userName () {
return this.$store.state.userName
}
}
mapState
简化获取store数据的代码
- 把vuex中的state数据映射到组件的计算属性中
import { mapState } from 'vuex'
- 使用mapState(对象)
// 使用mapState来生成计算属性,mapState函数返回值是对象
// 使用mapState使用 对象 传参
computed: mapState({
// 1.基础写法(state)代表就是vuex申明的state
userName: function(state) {
return state.userName
}
// 2.使用箭头函数
userName: state => state.userName
// 3.vuex提供写法(userName是state中的字段名称)
userName: 'userName'
// 4.当你的计算属性 需要依赖vuex中的数据 同时 依赖组件中data的数据
uerName(state) {
return state.userName + this.num
}
})
- 使用:mapState(数组)
// mapState参数是一个数组
computed: mapState(['userName', 'total'])
- 如果组件自己有计算属性,state的字段映射成计算属性
computed: {
// 组件其他计算属性
sum() {
return this.num + 1;
}
// 把mapState返回值那个对象进行展开操作(把对象的属性添加到该位置)
...mapState(['userName'])
}
状态修改mutations
为了统一管理数据,便于监控数据变化,Vuex规定必须通过mutation修改数据,不可以直接通过store修改状态数据
// mutations是固定的,同于定义修改数据的动作(函数)
mutations: {
// 定义一个mutation,age相加参数的方法
increment (state, payload) {
// state表示store中所有数据
// payload表示组件中传递过来的数据
state.age = state.age + payload
}
}
组件中调用
methods: {
handClick () {
// 通过触发mutation修改state中的age的值
this.$store.commit('increment', 2)
}
}
需要先定义mutations,再 this.$store.commit(‘mutations的名称’, ‘参数’)
mapMutations
把vuex中的mutations的函数映射到组件methods中(通过mapMutations函数可以生成methods中函数)
methods: {
// 1.对象参数写法
...mapMutations({
// 冒号右侧的increment是mutations的名称
// 冒号左侧的increment是事件函数的名称,可以自定义
increment: 'increment'
})
// 2.数组参数的写法(事件函数名称和mutation名称一致)
...mapMutations(['increment'])
// 3.与第二种等效
increment (param) {
// 点击触发该函数后要再次触发mutation的
this.$store.commit('increment', param)
}
}
异步操作action
异步任务,获取数据,一般axios请求数据是经典例子
- 安装axios的包
npm i axios
// 导入包
import axios from 'axios';
- 定义获取数据方法
// action是固定的,用于定义异步操作的动作(函数)
action: {
// 定义一个action,用于查询接口
async getData (context, payload) {
const res = await axios.get('url')
// 必须触发mutation修改res的值
// context类似于this.$store
context.commit('updateList', res.data.list)
}
},
mutations: {
updateList (state, payload) {
state.list = payload
}
}
- 组件使用
methods: {
handleQuery () {
// 触发action 必须嗲用dispatch方法
this.$store,dispatch('queryData', 111)
}
}
mapActions
mapActions辅助函数,把actions中的函数映射组件methods中(通过mapActions函数可以生成methods中函数)
...mapActions({
fn: 'queryData'
})
// 相当于methods申明一个函数 getData(num) { this.$store.dispatch('getData', num) }
...mapActions(['queryData'])
getters用法
// 相当于state的计算属性(基于State处理成另外一份数据)
// getters的主要应用场景:模板中需要的数据和State中的数据不完全一样
getters: {
getPartList (state) {
return state.list.filter(item => {
return item.id > 1;
})
}
}
用法
caleList () {
// 获取getters的值,不需要加括号(当属性使用)
return this.$store.getters.getPartList
}
// 简化用法
// mapGetters:把getters映射为计算属性
import { mapGetters } from 'vuex';
computed: {
...mapGetters(['getPartList'])
}