组件是插槽式的,例如某个页面有两个组件,其中搜索作为其中一个组件,当它作为组件的时候,它作为子组件的时候需要把参数通过属性的方式传递进来,通知父组件的时候通过触发事件来进行通信。
以上是组件化的简单描述,与模块化的组要区别在于组件化课深度定制不同的属性,借助父组件的参数值。
父子组件通信
最经典的通信方式就是:父组件与子组件之间进行通信。
组件的基本写法
Vue.component('shareLink', {
data() {},
props: ['shareLink'],
methods: {},
template: ``,
})
上述的代码就创建了一个名为shareLink
的组件,并且可传递一个名为shareLink
的参数值。
但是注意:
- HTML的规范规定,标签名与属性名都必须是小写字母,所以上述的组件在HTML代码里面默认写成
share-link
- 组件里面的
data
必须是函数,而不是app.js中的对象写法。
具体一点的写法是:
Vue.component('share', {
props: ['shareLink'],
template: `
<div class="share" v-cloak>
<h2>
请将下面链接分享给面试官
</h2>
<div>
<textarea readonly>{{shareLink}}</textarea>
</div>
</div>
`,
})
其中props
中是参数的名字,接受别的组件传递的信息。
<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: ‘ ‘} |
需求分析
- 子组件想改父组件的
data
。例如登录后的关闭按钮无用的例子。
<login v-show="loginVisible"></login>
//这是父组件的写法,loginVisible是父组件的变量,很明显儿子无法修改爸爸的数据啊
- 但是儿子特别像修改爸爸的数据
- 那么唯一的解决方案就是叫爸爸去修改
解决方案:
- 子组件通过事件告诉爸爸,我需要你做一些改变。
@click="$emit('close')"
- 注意:在
methods
中需要使用this.$emit('')
,但是在@click
中不需要用this
- 那么爸爸根据儿子的需要做出如下改变
<login v-show="loginVisible" @close="loginVisible = false">
@close
等同于v-on:close
父子组件通信的demo链接
爷孙组件间的通信
需求分析
- 爷爷看不到孙子在哪里
- 但是呢,爷爷就是想控制孙子
- 所以呢,借助爸爸来间接的去控制孙子就好啦
本质上Vue只有父子间通信,爷孙间通信需要使用两次父子间通信。
爷爷只控制孙子
该版本中爷爷只能控制孙子的显示,但是目前孙子无法反向操作爷爷。
demo的链接
孙子逐级冒泡通知爷爷
孙子先冒泡到爸爸那里,使用
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>
`
})
爷爷那里就可以监听到孙子的动作了
<body>
<div id="app">
<p>{{ message }}</p>
<button @click="xxx = true">打开</button>
<hr>
<child :visible="xxx" @close="log"></child>
</div>
</body>