07-组件通信、slot插槽
一、组件通信
① 父 => 子
-- 步骤
1)子组件中通过 props 键接受父组件传值
2)父组件通过 v-bind 向子组件传值
--例子
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> <meta charset="UTF-8"> </head> <body> <div id="app"> <parent></parent> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> Vue.component('parent',{ data(){ return { parentMsg : 'parent' } }, template:` <div> <p>父组件</p> <p>组件值 {{ parentMsg }}</p> //调用子组件,并传值 <son v-bind:sendMsg="parentMsg"></son> </div> `, // 子组件 components:{ son:{ //接受父组件传递的值 props:['sendMsg'], template:` <div> <p>子组件</p> <p>接受父组件的值:{{ sendMsg }}</p> </div> ` } } }) let vm = new Vue({ el: '#app', }) </script> </body> </html>
效果图:
② 子 => 父
-- 步骤
1)子组件自定义事件,通过 $emit 触发
语法:this.$emit( ' 事件名称 ',数据1,... ,数据n )
2)父组件调用事件获取数据
-- 例子
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> <meta charset="UTF-8"> </head> <body> <div id="app"> <parent></parent> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> Vue.component('parent', { data(){ return { sendsonMsg:null } }, template: ` <div> <p>父组件</p> <p>子组件值 {{ sendsonMsg }}</p> <!-- 2.调用子组件 --> <son @sonSend = 'showSonMsg'></son> </div> `, methods: { // 3.定义方法 showSonMsg(data){ this.sendsonMsg = data; } }, // 子组件 components: { son: { template: ` <div> <p>子组件</p> <p>子组件的值:{{ sonMsg }}</p> </div> `, data() { return { sonMsg:'sonData' } }, // 1.$emit 触发 mounted() { this.$emit('sonSend', this.sonMsg) }, } } }) let vm = new Vue({ el: '#app', }) </script> </body> </html>
效果图
③ 兄弟组件通信 (event bus)
-- 步骤
1)定义数据共享中心
const eventBus = new Vue();
2)发送数据
eventBus .$emit( ' 事件名 ',数据1,... ,数据n )
3)接收数据
eventBus .$on(' 事件名 ',处理函数)
-- 例子
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> <meta charset="UTF-8"> </head> <body> <div id="app"> <mytag1></mytag1> <mytag2></mytag2> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> Vue.component('mytag1',{ data(){ return { tagMsgOne:'tag1Data', tagMsg:null } }, template:` <div> <p>兄弟组件一</p> <button @click='sendDataOne'>传递信息</button> <p>兄弟组件一数据:{{ tagMsgOne }}</p> <p>兄弟组件二传递的数据:{{ tagMsg }}</p> <hr /> </div> `, methods: { sendDataOne(){ eventBus.$emit('event', this.tagMsgOne) } }, mounted(){ // 3.接收数据 eventBus.$on('tagTwo',(data) => { this.tagMsg = data }) } }) Vue.component('mytag2',{ data(){ return { tagMsgTwo:'tag2Data', tagMsg:null } }, template:` <div> <p>兄弟组件二</p> <button @click='sendDataTwo'>传递信息</button> <p>兄弟组件二数据:{{ tagMsgTwo }}</p> <p>兄弟组件一传递数据:{{ tagMsg }}</p> </div> `, mounted() { eventBus.$on('event',(data) => { this.tagMsg = data; }) }, methods:{ // 2.发送数据 sendDataTwo(){ eventBus.$emit('tagTwo',this.tagMsgTwo) } } }) // 1.创建共享数据中心 const eventBus = new Vue(); let vm = new Vue({ el: '#app', data: { }, methods: { } }) </script> </body> </html>
效果图
二、solt 插槽
为什么要用插槽:封装一个组件,每次调用显示不同的信息
① 后备内容
-- 步骤
1)定义组件时内容去用 <slot></slot> 占位
2)调用组件时,组件标签内容后同步到插槽占位符中
--例子
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> <meta charset="UTF-8"> </head> <body> <div id="app"> <mytag>提示信息</mytag> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> // 定义组件 Vue.component('mytag',{ template:` <div style='border:1px solid red;max-width:200px'> <!-- 占位符 --> <slot></slot> </div> ` }) let vm = new Vue({ el: '#app', }) </script> </body> </html>
效果图
② 具名插槽
--步骤
1)定义组件时,用 slot 占位
<slot name=' 标识 '></slot>
2)调用组件时,根据标识显示数据
<template v-slot:标识>
//html 标签
</template>
--例子
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> <meta charset="UTF-8"> </head> <body> <div id="app"> <mytag> <template v-slot:test> test </template> </mytag> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> // 定义显示数据 // 定义组件 Vue.component('mytag',{ template:` <div style='border:1px solid red;max-width:200px'> <!-- 占位符 --> <slot name= 'test'></slot> </div> ` }) let vm = new Vue({ el: '#app', }) </script> </body> </html>
效果图
③ 作用域插槽
--步骤
1)定义组件时,用 slot 占位
<slot name=' 标识 ' v-bind:任意名称 = ' data 中的键 '></slot>
2)调用组件
<template v-slot:标识 = ' 任意名称 '>
//html 标签
</template>
--例子
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> <meta charset="UTF-8"> </head> <body> <div id="app"> <mytag> <template v-slot:index='item'> this is index {{ item.data }} </template> </mytag> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> // 定义显示数据 // 定义组件 Vue.component('mytag', { data() { return { msg1:'msg1', msg2:'msg2' } }, template: ` <div> <!-- 占位符 --> <slot name='index' :data='msg1'></slot> </div> ` }) let vm = new Vue({ el: '#app', }) </script> </body> </html>
效果图
特此声明:如需转载请注明出处,如有疑问请及时提出以便于改正,如有侵权,联系删除,谢谢