多组件共用相同的状态时,在深层嵌套组件间传递属性过于冗长,并且不能简单地在同级别的组件间传递,直接引用 父/子 实例,又或是通过事件来修改和同步多份状态副本。这样的模型是脆弱的,代码很快会变得不可维护。
理解Vue组件之间的数据传递关系到应用的健壮性和可维护性。
通信原则 Props Down Events Up
父组件向子组件传递数据使用 props
子组件向父组件传递数据使用 event
单向数据流
组件实例的作用域是孤立的
不应该在子组件的模板内直接引用父组件的数据
prop
是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——
这会让应用的数据流难以理解。
//在父组件中使用props传递给子组件 |
自定义事件
在父组件中使用指令 v-on:cusEvent 绑定自定义事件
在子组件中使用指令 v-on:click=”this.$emit(‘cusEvent’, args1, args2 )” 来触发父组件的事件,并传递参数
//父组件绑定自定义事件increment |
全局事件总线(global event bus)
在父组件中利用vue实例的$on
注册一个事件,在子组件中使用vue实例的$emit
来触发父组件中的事件
var bus = new Vue() |
避免使用 vm.$parent / vm.$root / vm.$children
状态管理器 Vuex
一个专门为 Vue.js 应用设计的 状态管理模型 + 库
为应用内的所有组件提供集中式存储服务,其中的规则确保状态只能按预期方式
在 vue 应用中,vuex 就充当了数据提供者的角色,vue 则只需要关注页面的展示与交互。
state (状态),驱动我们应用的真实的源;
view (视图),对应着 状态 的声明式映射;
actions (动作),用户在 视图 上的输入引起状态的更改的可能方式。
Vuex 核心概念
应用场景
页面状态数据:路由、加载状态、异步数据、开关、分页页码、表单数据
state ( store 的 data)
存放整个应用状态,作为应用的唯一数据源驱动UI视图的更新
尽量初始化详细的state数据
组件中直接访问computed: {
count () {
return this.$store.state.count
}
}
使用工具函数 mapSate
访问
用于将独立的state数据映射到组件的 computed
属性中
import { mapState } from 'vuex' |
actions ( store 的 methods)
不改变状态,只提交(commit) mutation。
可以包含任意异步操作。
组件中直接访问mounted(){
this.$store.dispatch('getUserData')
}
工具函数 mapActions
访问
用于将action方法映射到组件的 methods
中
import { mapActions } from 'vuex' |
mutations ( store 的 methods)
定义了 同步 改变 state
的唯一方法
在store中,实际改变 状态(state) 的唯一方式是通过 提交(commit) 一个 mutation
组件中使用methods:{
add(){
this.$store.commit('ADD_NUMBER',{num: 1})
}
}
使用工具函数 mapMutations
将mutation映射到组件的 methods 中
import { mapMutations } from 'vuex' |
getters ( store 的 computed)
和计算属性功能相同,基于多个状态生成新的状态
组件中使用computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
工具函数 mapGetters
用于将getter属性映射到组件的computed中
import { mapGetters } from 'vuex' |
组件仍然可以具有局部状态
使用 Vuex 并不意味你应该把 所有 状态都放在 Vuex 中去管理。尽管把更多的状态放到 Vuex 管理,会让状态变化变得更加清晰和可调试,但有时也能使代码变得冗余和不直观。如果某部分状态严格属于一个单独的组件,那就只把这部分状态作为局部状态就好了。
理解:状态分为 应用级状态 和 组件级状态
原子类组件,尽量由父组件传递状态数据使用
当组件状态不影响父组件和其它同级组件时,可做为组件内部状态
页面级的数据应该做为应用级状态管理
Redux 的作者有一句话说的不错(redux与vuex都是在flux模式上的改进):
原文:Flux libraries are like glasses: you’ll know when you need them.
译文:Flux 库就像眼镜:当你需要它们的时候你会懂的。