一,学习目标:
-
跨组件通信能力
-
vuex的基础使用
二:vuex介绍
2.1两个目标:
-
什么是vuex
-
为什么学习vuex
2.2引入问题:组件通信 (组件通信方式)
分为子向父,父向子
父向子:在子组件内设置props定义变量 在父组件内使用子组件的位置加属性(属性名是在子组件没定义的变量名)传入父组件数据
子向父:子组件 在恰当时机使用vue内置的this.$emit('自定义事件名', 值) 父组件内 给组件@自定义事件="父methods函数"
总结:以前的通信方案只能实现父子传值
问题:如果两个没有直接关系的组件想要通信 使用父子通信就很难操作
我们需要新的技术实现通信 vuex (官方文档)
2.3什么是vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理数据,以相应的规则保证状态以一种可预测的方式发生变化
2.4vuex为何学
程序页面多, 数据变量多
-
不同组件数据保持同步
-
数据的修改都是可追踪
三,vuex使用
3.1 vuex安装(固定)
3.2vuex5个配置项(固定)
我将一个介绍他们如何定义及他们的用法
3.3vuex-store准备
我们在给项目使用vuex时 比如vue初始化了脚手架项目 我们要在src下新建store文件夹
里面存放的一个仓库对象 类似路由模块router/index.js
src/store/index.js
// 目标: 创建store仓库对象
// 1. 下载vuex: 终端命令(yarn add vuex)
// 2. 引入vuex
import Vue from 'vue'
import Vuex from 'vuex'
// 3. 注册
Vue.use(Vuex)
// 4. 实例化store对象
const store = new Vuex.Store({})
// 5. 导出store对象
export default store
main.js
import Vue from 'vue'
import App from './App.vue'
import store from '@/store' // 导入store对象
Vue.config.productionTip = false
new Vue({
// 6. 注入到Vue实例中(确保组件this.$store使用)
store,
render: h => h(App),
}).$mount('#app')
3.3vuex-state数据源
目标:
-
定义state
-
直接使用state
-
辅助函数mapState
3.3.1定义state
在store/index.js定义state
语法:
/*
const store = new Vuex.Store({
state: {
变量名: 初始值
}
})
*/
3.3.2state使用方式
第一种:直接使用 this.$store.state.变量名
第二种:映射使用 引入vuex内置的mapState辅助函数 将变量映射到使用变量组件的计算属性里
// 1. 拿到mapState辅助函数
import { mapState } from 'vuex'
export default {
computed: {
// 2. 把state里变量映射到计算属性中
...mapState(['state里的变量名'])
}
}
3.4vuex-mutations定义-同步修改 (唯一可以修改state定义的变量的地方)
mutations类似数据管家, 操作state里的数据
目标:
-
定义mutations
-
直接使用mutations
-
辅助函数mapMutations
3.4.1定义mutations
在store/index.js定义mutations
语法:
/*
const store = new Vuex.Store({
mutations: {
函数名 (state, 可选值) {
// 同步修改state值代码
操作state
}
}
})
*/
3.4.2mutations使用方式
第一种:直接使用 this.$store.commit("mutations里的函数名", 具体值)
第二种:映射使用 引入vuex内置的mapMutations辅助函数 将这个方法映射到使用变量组件的methods里 (因为它就相当于是一个方法)谁要用就可以调用这个方法
// 1. 拿到mapMutations辅助函数
import { mapMutations } from 'vuex'
export default {
methods: {
// 2. 把mutations里方法映射到原地
...mapMutations(['mutations里的函数名'])
}
}
注意:mutations函数上, 只能接收一个参数值, 如果传多个, 请传一个对象
state, mutations, 视图组件, 3个关系是什么?
3.5vuex-actions定义-异步修改
代码不仅有同步的还有异步代码 比如:ajax请求 定时器 计时器
目标:
-
定义actions
-
直接使用actions
-
辅助函数mapActions
3.5.1定义actions
在store/index.js定义actions
语法:
/*
const store = new Vuex.Store({
actions: {
函数名 (store, 可选值) {
// 异步代码, 把结果commit给mutations给state赋值
setTimeout(() => { // 1秒后, 异步提交给add的mutations
store.commit('mutations定义的函数名', 可选值)
}, 1000)
}
}
})
*/
为什么要把结果commit给mutations给state赋值 因为mutations是唯一可以修改state变量的地方
注意 actions定义的函数名第一个参数是store对象
3.5.2actions使用方式
第一种:直接使用 this.$store.dispatch('actions函数名', 具体值)
第二种:映射使用 引入vuex内置的mapActions辅助函数 将这个方法映射到使用变量组件的methods里 (因为它就相当于是一个方法)谁要用就可以调用这个方法
// 1. 拿到mapActions辅助函数
import { mapActions } from 'vuex'
export default {
methods: {
// 2. 把actions里方法映射到原地
...mapActions(['actions里的函数名'])
}
}
视图组件, state, mutations, actions的关系是?
3.6vuex-getters定义-计算属性
目标:
-
getters
-
直接使用getters
-
辅助函数mapGetters
3.6.1定义getters
在store/index.js定义getters
相当于vue里的计算属性
语法:
/*
const store = new Vuex.Store({
getters: {
计算属性名 (state) {
return 值给计算属性
}
}
})
*/
3.6.2getters使用方式
第一种:直接使用 this.$store.getters.计算属性名
第二种:映射使用 引入vuex内置的mapGetters辅助函数 将它映射到使用变量组件的计算属性里
// 1. 拿到mapGetters辅助函数
import { mapGetters } from 'vuex'
export default {
computed: {
// 2. 把getters里属性映射到原地
...mapGetters(['getters里的计算属性名'])
}
}
.3.7vuex-modules定义-分模块
目标:
-
为何要分模块
-
modules定义
-
模块化的影响
-
命名空间
3.7.1 为何要分模块化
由于使用单一状态树,应用的所有的状态会集中在一个比较大的对象。当应用变得非常复杂时,store对象变得非常臃肿。
为了解决以上问题,Vuex允许我们将store模块化。每个模块拥有自己的state,mutation、action、getter
3.7.2定义modules
语法:
modules: {
模块名: 模块对象
}
实列
单独创建一个文件
const userModule = {
state(){
return {
name: "",
age: 0,
sex: ''
}
},
mutations: {},
actions: {},
getters: {}
}
export default userModule
src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import cartModule from './modules/cart'
import userModule from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user: userModule,
cart: cartModule
}
})
export default store
3.7.3影响state取值方式
只要分模块, state取值方式改变, 其他暂时不变
state分模块使用语法 直接使用 this.$store.state.模块名.变量名
组件内 - 映射使用
...mapState({
'变量名': state => state.模块名.变量名
})
3.7.4 命名空间
防止多个模块之间, mutations/actions/getters的名字冲突
在模块对象内设置namespaced: true
开启命名空间的影响
state使用方式修改
直接使用无变化: this.$store.state.模块名.变量名
辅助函数需要遵守格式 ...mapState("模块名", ['state变量名'])
mutations使用方式修改
直接使用
this.$store.commit("模块名/mutations里的函数名", 具体值)
映射使用
...mapMutations("模块名", ['mutations里方法名'])
actions使用方式修改
直接使用
this.$store.dispatch("模块名/actions里的函数名", 具体值))
映射使用
...mapActions("模块名", ['actions里方法名'])
getters使用方式修改
直接使用
this.$store.getters['模块名/计算属性名']
映射使用
...mapGetters("模块名", ['getters里计算属性名'])
总结图 两张图意思一样