组件关系 | 数据通信 |
---|---|
父子关系 | 父传子:props ; 子传父:$emit |
非父子关系 | vuex (一种组件通信方案) |
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理数据,以相应的规则保证状态以一种可预测的方式发生变化
程序页面多, 数据变量多
1)不同组件数据保持同步
2)数据的修改都是可追踪
多个组件共享状态,才存储在vuex中
某个组件中的私有数据,依旧存储在data中
配置项 | 含义 | 注意 |
---|---|---|
state | 单一状态树 | 类似data |
mutations | 数据管家(同步) | 唯一修改state地方 |
actions | 异步请求 | 要改state需要提交给mutations |
getters | vuex计算属性 | 类似computed |
modules | 模块拆分 | 分模块管理数据 |
-D: 开发依赖(开发阶段需要使用,上线不需要使用的模块)- package.json -> devDependencies
-S: 生产依赖(开发阶段需要使用,上线还需要使用的模块)-> package.json -> dependencies
-g: 全局安装,比如:@vue/cli
yarn add vuex -S
// 目标: 创建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
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')
在store/index.js定义state
const store = new Vuex.Store({
state: {
变量名: 初始值
}
})
this.$store.state.变量名
// 1. 拿到mapState辅助函数
import { mapState } from 'vuex'
export default {
computed: {
// 2. 把state里变量映射到计算属性中
...mapState(['state里的变量名'])
}
}
让数据的变化可追踪、可预测(规范程序员的代码行为),修改state必须通过mutations进行
const store = new Vuex.Store({
// 开始严格模式
strict: true,
state: {
num: 100
}
})
const store = new Vuex.Store({
mutations: {
函数名 (state, 可选值) {
// 同步修改state值代码
}
}
})
1)mutations是唯一能修改state的地方, 确保调试工具可以追踪变化
2)mutations函数内, 只能写同步代码, 调试工具可追踪变化过程
this.$store.commit("mutations里的函数名", 具体值)
// 1. 拿到mapMutations辅助函数
import { mapMutations } from 'vuex'
export default {
methods: {
// 2. 把mutations里方法映射到原地
...mapMutations(['mutations里的函数名'])
}
}
mutations函数上, 只能接收一个参数值, 如果传对个, 请传一个对象
const store = new Vuex.Store({
actions: {
函数名 (store, 可选值) {
// 异步代码, 把结果commit给mutations给state赋值
}
}
})
1)actions和mutations区别?
2)actions和mutations里函数, 第一个形参分别是什么?
this.$store.dispatch('actions函数名', 具体值)
// 1. 拿到mapActions辅助函数
import { mapActions } from 'vuex'
export default {
methods: {
// 2. 把actions里方法映射到原地
...mapActions(['actions里的函数名'])
}
}
vuex身上的全局状态-计算属性, 类似于computed
getters 依赖于 state中原始数据的变化,并返回计算后的新数据
getters就是vuex的计算属性,根据state中数据变量计算得到
const store = new Vuex.Store({
getters: {
计算属性名 (state) {
return 值给计算属性
}
}
})
this.$store.getters.计算属性名
// 1. 拿到mapGetters辅助函数
import { mapGetters } from 'vuex'
export default {
computed: {
// 2. 把getters里属性映射到原地
...mapGetters(['getters里的计算属性名'])
}
}
由于使用单一状态树
,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿
。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、
甚至是嵌套子模块
—— 从上至下进行同样方式的分割
modules: {
模块名: 模块对象
}
在子模块对象内设置namespaced: true
const userModule = {
namespaced: true,
state () {},
mutations: {},
actions: {},
getters: {},
modules: {}
}
...mapState("模块名", ['state变量名'])
this.$store.commit("mutations里的函数名", 具体值)
this.$store.commit("模块名/mutations里的函数名", 具体值)
...mapMutations(['mutations里方法名'])
...mapMutations("模块名", ['mutations里方法名'])
this.$store.dispatch("actions里的函数名", 具体值)
- 开命名空间后语法:
```javascript
this.$store.dispatch("模块名/actions里的函数名", 具体值)
...mapActions(['actions里方法名'])
...mapActions("模块名", ['actions里方法名'])
this.$store.getters.计算属性名
- 开命名空间后语法:
```javascript
this.$store.getters['模块名/计算属性名']
...mapGetters(['getters里计算属性名'])
...mapGetters("模块名", ['getters里计算属性名'])