盒子
盒子
文章目录
  1. 父子组件通信
    1. 组件的基本写法
    2. 简单的对应规则
    3. 需求分析
  2. 爷孙组件间的通信
    1. 需求分析
    2. 爷爷只控制孙子
    3. 孙子逐级冒泡通知爷爷

Vue的组件间通信

组件是插槽式的,例如某个页面有两个组件,其中搜索作为其中一个组件,当它作为组件的时候,它作为子组件的时候需要把参数通过属性的方式传递进来,通知父组件的时候通过触发事件来进行通信。

以上是组件化的简单描述,与模块化的组要区别在于组件化课深度定制不同的属性,借助父组件的参数值。

那么问题来了,组件间如何进行通信呢?

父子组件通信

最经典的通信方式就是:父组件与子组件之间进行通信。

组件的基本写法

1
2
3
4
5
6
Vue.component('shareLink', {
data() {},
props: ['shareLink'],
methods: {},
template: ``,
})

上述的代码就创建了一个名为shareLink的组件,并且可传递一个名为shareLink的参数值。

但是注意:

  • HTML的规范规定,标签名与属性名都必须是小写字母,所以上述的组件在HTML代码里面默认写成share-link
  • 组件里面的data必须是函数,而不是app.js中的对象写法。

具体一点的写法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
Vue.component('share', {
props: ['shareLink'],
template: `
<div class="share" v-cloak>
<h2>
请将下面链接分享给面试官
</h2>
<div>
<textarea readonly>{{shareLink}}</textarea>
</div>
</div>
`,
})

其中props中是参数的名字,接受别的组件传递的信息。

1
2
<share v-bind:share-link="shareLink" v-show="shareVisible"></share>
//在html的页面中这样写

v-bind将参数的名字绑定上,值是通过app.js获得的shareLink

简单的对应规则

v-bind :share-link = “shareLink”
对应的 props: [‘shareLink’] app.js中{shareLink: ‘ ‘}

需求分析

  1. 子组件想改父组件的data。例如登录后的关闭按钮无用的例子。
1
2
<login v-show="loginVisible"></login> 
//这是父组件的写法,loginVisible是父组件的变量,很明显儿子无法修改爸爸的数据啊
  1. 但是儿子特别像修改爸爸的数据
  2. 那么唯一的解决方案就是叫爸爸去修改

解决方案:

  1. 子组件通过事件告诉爸爸,我需要你做一些改变。

@click="$emit('close')"

  • 注意:在methods中需要使用this.$emit(''),但是在@click中不需要用this
  1. 那么爸爸根据儿子的需要做出如下改变

<login v-show="loginVisible" @close="loginVisible = false">

@close等同于v-on:close

父子组件通信的demo链接

父子组件通信图示

爷孙组件间的通信

需求分析

  1. 爷爷看不到孙子在哪里
  2. 但是呢,爷爷就是想控制孙子
  3. 所以呢,借助爸爸来间接的去控制孙子就好啦

本质上Vue只有父子间通信,爷孙间通信需要使用两次父子间通信

爷爷只控制孙子

该版本中爷爷只能控制孙子的显示,但是目前孙子无法反向操作爷爷。

demo的链接

孙子逐级冒泡通知爷爷

孙子先冒泡到爸爸那里,使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Vue.component('child', {
props: ['visible'],
template: `
<div>
我是儿子
<grand-child v-show="visible" @close="$emit('close')"></grand-child>
</div>
`
})
Vue.component('grandChild', {
template: `
<div>
我是孙子
<button @click="$emit('close')">关闭</button>
</div>
`
})

爷爷那里就可以监听到孙子的动作了

1
2
3
4
5
6
7
8
9
<body>
<div id="app">
<p>{{ message }}</p>
<button @click="xxx = true">打开</button>
<hr>
<child :visible="xxx" @close="log"></child>
</div>

</body>

demo的链接

爷孙间的通信图示