props/emit
参数下传,事件上传,这个方式最常用,简单父子组件之间交互使用,比较推荐。
// 子组件
props: {
page: {
type: String,
default: "1"
}
}
method: {
handleEmit(){
this.$emit('pagination', { page: val })
}
}
// 父组件
<template>
<child page="1" @pagination="handlePageChange"></child>
</template>
tips:
- 当props 传递的参数不是固定的,而是动态获取时,在created、mounted 等中获取不到,原因是父组件中的要传递的 props 属性 是通过 发生ajax请求回来的, 请求的这个过程是需要时间的,但是子组件的渲染要快于ajax请求过程,所以此时 created 、 mounted 这样的只会执行一次的生命周期钩子,已经执行了,但是 props 还没有流进来(子组件),所以只能拿到默认值。这个时候用watch:
watch: {
page: function(newVal,oldVal){
this.cpage = newVal; //newVal即是请求后获取的page值
newVal&& this.init(); //newVal存在的话执行drawChar函数
}
},
- 子组件中直接改变props会影响到父组件, 因为是引用,所以用子组件的data,通过computed 或 watch 获取
vuex
对于组件嵌套比较深、以及兄弟组件之间可用。
本质是利用 this.$options
获取属性 + 动态数据更新
即把this.$options.parent.xxx.store
通过mixin
注入到this.$store
中。
稍微大点的项目推荐使用。
$attrs / $listeners
在创建高级别的组件时非常有用, 对一些UI库进行二次封装,但是又想保留他自己的属性和方法,那么这个时候时候 a t t r s 和 attrs和 attrs和listners是个完美的解决方案。
$attrs
获取父作用域不被 prop 识别的特性绑定 (class和style除外), 不用写 props。
如果想要添加其他属性,可继续绑定属性。但要注意的是,继续绑定的属性和 $attrs 中的属性有重复时,继续绑定的属性优先级会更高。
$listeners
包含父作用域中的 (不含.native修饰器的)v-on事件监听器,即接收除了带有.native事件修饰符的所有事件监听器
如果想要添加其他事件监听器,可继续绑定事件。但要注意的是,继续绑定的事件和 $listeners 中的事件有重复时,不会被覆盖。当 grandson.vue 触发 customEvent 时,child.vue 和 parent.vue 的事件都会被触发,触发顺序类似于冒泡,先到 child.vue 再到 parent.vue。
event bus
如果咱们的应用程序不需要类似Vuex这样的库来处理组件之间的数据通信,就可以考虑Vue中的 事件总线(EventBus)来通信。较好的实现兄弟组件之间的数据通讯。
在Vue中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件,但也就是太方便所以若使用不慎,就会造成难以维护的“灾难”,因此才需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。
// 初始化 1:main.js中全局的事件总线
Vue.prototype.$EventBus = new Vue()
// 发送消息
EventBus.$emit(channel: string, callback(payload1,…))
EventBus.$emit("aMsg", '来自A页面的消息');
// 监听接收消息
EventBus.$on(channel: string, callback(payload1,…))
EventBus.$on("aMsg", (msg) => { this.msg = msg;});
provide/inject
provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
// ...
}
// 子组件注入 'foo'
var Child = {
inject: ['foo'],
created () {
console.log(this.foo) // => "bar"
}
// ...
}