- props 与 emit 交互方式
-
listtener 交互方式
- ref的交互方式
- 利用.sync实现的通信方式
- 利用vue的事件中心实现兄弟组件间的交互 eventBus
props 与 emit 交互方式,最常见的方式
父子组件利用props的方式传递参数,利用emit操作函数
// 父组件
<test :user="user" @handlerEmitFather="updateUser"></test>
<script>
import test from '@/components/01_props.vue'; // 引入组件
data(){
return {
user : '张三'
}
},
components:{test}
methods:{
// 监听的函数
updateUser(){
console.log('调用起handlerEmitFather')
},
}
</script>
// 子组件
<div>
{{user}} // 张三
<button @click="update">调用父级组件-方法1</button>
<button @click="$emit('handlerEmitFather','张四')">调用父级组件-方法2</button>
</div>
<script>
props:{
user:{
type : String, // 类型
default : '张四', // 默认值
required: true, // 是否必须
}
},
/*
props:['user'] props的多种写法
*/
methods:{
update(){
this.$emit('handlerEmitFather','李四')
},
}
</script>
- 父组件中设置v-on绑定子组件的监听函数
- props接收父级的属性值
- required 设置属性是否必传
listtener 交互方式
listtener 是祖辈组件交互最好的方法,但仅适合在子辈组件显示父组件的内容
一些特性:
$attrs 与 $listtener 实现子子级组件获取到祖辈组件传递过来的参数 2、子组件中使用插值表达式 {{ $attrs }} 或是直接使用this$attrs获取到父级传过来单未被props识别的内容 3、在这个链路中,只要游艺机一个参数在props中定义就会影响到自身的attrs和后续子组件的attrs 4、子组件使用 v-bind=“$attrs” 传递给子子组件 5、父组件修改值会响应式的修改子组件中的值,但子组件无法响应式的影响父组件 6、子组件响应式的修改父组件中的值只能通过emit的方法 7、vue中组件的加载顺序是:孙子>儿子>爸爸>爷爷 由最里面的组件开始向外加载,需要注意以后的方法执行顺序 8、 $attrs 和 $listtener 适用的场景仅是子组件不需要更改数据,仅是显示数据的作用 9、inheritAttrs属性与data同级,用于子组件中,作用是去除掉调父级传过来未定义的属性 10、子组件修改$attrs中的内容是不会被修改的
// 父组件
<child
user="张三"
age="16"
name="欧阳"
gender="男"
>
</child>
import child from './components/child.vue';
components:{child}
// 儿子组件
<grandson
v-bind="$attrs" // 通过attrs将父级传递过来的内容传递给子级
>
</grandson>
<script>
import grandson from './grandson.vue';
inheritAttrs:false, // 是否去除子组件中props未接收的属性
components:{grandson},
mounted:{
// 可获取到prop中未定义的全部组件
console.log(this.$attrs) // {user:'张三',age:'16',name='欧阳',gender='男'}
}
</script>
// 孙子组件
{{user}}
<son
v-bind="$attrs"
>
</son>
<script>
import child from './child.vue';
components:{child},
props:['user']
mounted(){
// props 定义了user字段,$attrs 中就没有了user
console.log(this.$attrs) // {age:'16',name='欧阳',gender='男'}
},
</script>
// 孙子的孙子
<div>
{{ $attrs }} // {age:'16',name='欧阳',gender='男'}
</div>
<script>
mounted(){
// 父级的props 定义了user字段,所以传过来的$attrs 中就没有了user
console.log(this.$attrs) // {age:'16',name='欧阳',gender='男'}
},
</script>
ref的交互方式
父组件快速调用子组件中的函数,父级无法调用孙辈的函数,仅调用子辈的函数
// 父组件
<div>
<button @click="Fupdate">调用子组件update方法</button>
<button @click="Fsava">调用子组件sava方法</button>
<child ref="child" user="张三"></child>
</div>
<script>
import child from './components/child.vue';
mounted(){
console.log(this.$refs.child) // 子组件的实例
},
methods:{
Fupdate(){
this.$refs.child.update()
},
Fsava(){
this.$refs.child.save()
}
}
</script>
// 子组件
<script>
methods:{
update(){
console.log('调用了update方法')
},
save(){
console.log('调用了sava方法')
},
}
</script>
eventBus
利用vue事件监听器实现组件间的相互通通信A触发一个监听函数,B监听了这个函数,当A触发后B的函数会自动执行
这种通信方式不需要实例化某个组件也能实现监听某组件内的事件,只要实例化了bus
-
定义一个vue实例
// /utils/eventBus.js import Vue from 'vue' export default new Vue()
-
定义父组件,引入组件left组件right
<template> <div> <h1>eventBus事件监听器</h1> <h3>{{user}}</h3> <div class="main"> <left>left</left> <right></right> <top></top> </div> </div> </template> import left from '@/components/组件间的通信方式/05_eventBusLeft.vue' import right from '@/components/组件间的通信方式/05_eventBusRight.vue' components:{ left,right },
-
组件left 导入并实例化eventBus,利用
bus.$on并监听一个onUpdate事件import bus from '@/utils/eventBus.js'; created() { bus.$on('onUpdate',str => { console.log(str) // 张三 }) } -
组件right导入并实例化eventBus,利用
利用bus.$emit触发一个监听事件<template> <div> <button @click="emitUpdate">触发函数一个emit</button> </div> </template> import bus from '@/utils/eventBus.js'; methods:{ // 1、设置一个监听函数 emit emitUpdate(){ bus.$emit('onUpdate','张三') } }