父子组件间的三种通信方式
通过props实现通信
子组件的props选项能够接收来自父组件的数据。props是单项绑定的
props静态传递
子组件通过props选项来声明一个自定义的属性,然后父组件就可以再嵌套标签的时候,通过这个属性往子组件传递数据了!
father_props.vue
<template>
<div>
<h1>我是父组件!</h1>
<child message="我是子组件一!"></child> <!-- 通过自定义属性传递数据 -->
</div>
</template>
<script>
import Child from '../components/child_props.vue'
export default {
components: {
Child
}
}
</script>
<style lang="stylus" scoped>
</style>
child_props.vue
<template>
<h3>{{ message }}</h3>
</template>
<script>
export default {
props: ['message'] // 声明一个自定义的属性
}
</script>
<style lang="stylus" scoped>
</style>
props动态传递
更多的时候我们需要传送一个动态的数据。这时候就可以用==v-bind(:)==实现。通过v-bind绑定props的自定义的属性,传递过去的就不是静态的字符串了,它可以是一个表达式,布尔值,对象等等任何类型的值
father_props.vue
<template>
<div>
<h1>我是父组件!</h1>
<child message="我是子组件一!"></child>
<!-- 这是一个 JavaScript 表达式而不是一个字符串 -->
<child v-bind:message="a+b"></child>
<!-- 用一个变量进行动态赋值 -->
<child v-bind:message="msg"></child>
</div>
</template>
<script>
import Child from '../components/child_props.vue'
export default {
components: {
Child
},
data () {
return {
a: '我是子组件二!',
b: 41,
msg: '我是子组件三!' + Math.random()
}
}
}
</script>
<style lang="stylus" scoped>
</style>
child_props.vue 子组件不变
通过$ref实现通信
对于ref官方的解释是:ref是被用来给元素或子组件注册引用信息的。引用信息将会注册在父组件的$refs对象上。
props是父组件给子组件信息,那么,
$ref就是子组件给父组件信息。
简单来说,父组件可以通过$ref来调用子组件的信息,包括data和methods
father_ref.vue
<template>
<div>
<h1>我是父组件!</h1>
<child ref="msg"></child>
</div>
</template>
<script>
import Child from '../components/child_ref.vue'
export default {
components: {
Child
},
mounted: function () {
console.log(this.$refs.msg)
this.$refs.msg.getMessage('我是子组件一!')
}
}
</script>
<style lang="stylus" scoped>
</style>
child_ref.vue
<template>
<h3>{{ message }}</h3>
</template>
<script>
export default {
data () {
return {
message: ''
}
},
methods: {
getMessage (m) {
this.message = m
}
}
}
</script>
<style lang="stylus" scoped>
</style>
props和$ref的对比
- 1.前者着重于数据的传递,它并不能调用子组件里的属性和方法
- 2.后者着重于索引,主要用来调用子组件里的属性和方法。特别地,ref用在dom元素的时候,能起到选择器的作用,这个功能比作为索引更加重要
$emit实现通信
上面两种方法主要都是父组件为主,给子组件信息,调用子组件的信息。
那么,第三种方法就是以子组件为主。
$emit绑定一个自定义事件event,当这个语句被执行的时候,就会将参数arg传递给父组件,父组件通过@event
监听并接收参数。
father_emit.vue
<template>
<div>
<h1>{{ title }}</h1>
<child @getMessage="showMsg"></child>
</div>
</template>
<script>
import Child from '../components/child_emit.vue'
export default {
components: {
Child
},
data () {
return {
title: ''
}
},
methods: {
showMsg (title) {
this.title = title
}
}
}
</script>
<style lang="stylus" scoped>
</style>
child_emit.vue
<template>
<h3>我是子组件!</h3>
</template>
<script>
export default {
mounted: function () {
this.$emit('getMessage', '我是父组件!')
}
}
</script>
<style lang="stylus" scoped>
</style>
总而言之,说一下三种方法
- 1.对于props,就是子组件设置一个props,父组件给这个props赋值就可以通信,动态赋值可以用v-bind(😃 是主要的通信方式
- 2.对于 r e f , 给 子 组 件 一 个 r e f , 我 们 就 可 以 通 过 这 个 ‘ t h i s . ref,给子组件一个ref,我们就可以通过这个` this. ref,给子组件一个ref,我们就可以通过这个‘this.refs.`来调用子组件的属性和方法,这主要是用在dom树中,起到选择器的作用
- 3.对于$emit,子组件绑定一个方法和参数,父组件可以绑定子组件这个绑定方法的监听,获得子组件返回的参数。第三种方法少见一些。有些逆思维了。目前不懂它存在的意义。