创建一个空实例Bus, export default 导出Bus
过程:由A组件对Bus组件进行监听,B组件触发Bus对应的事件,由于A组件进行监听,触发事件之后就会进行A组件的回调,那么就可以将消息发送给A了
在src文件夹下新建utils文件夹(工具类文件一般放在utils),文件夹下新建EventBus.js文件
创建一个空vue实例 Bus:// 1.创建一个都能访问到的事件总线(空的 Vue实例) import Vue from 'vue' const Bus = new Vue() export default Bus // 导出事件总线,将来任何需要借助事件总线的地方都可以直接导入该文件
B组件通过点击按钮触发Bus 实例传递消息:
<template> <div class="base-b"> 我是B组件(发布方) <button @click="clickSendd">发布通知</button> </div> </template> <script> import Bus from '../utils/EventBus' export default { methods:{ clickSend(){ //3.B(发送方)触发事件的方式传递参数 Bus.$emit('sendMsg','今日天晴') } } } </script> <style> .base-b { background-color: white; width: 200px; height: 300px; text-align: center; line-height: 300px; border: 1px solid #000; } </style>
A组件通过监听Bus实例,接收消息进行处理
在data中定义变量msg,将传过来的消息赋值给变量msg,然后进行页面显示
<template> <div class="base-a">我是A组件(接收方) <p>{{msg}}</p> </div> </template> <script> import Bus from '../utils/EventBus' export default { created() { // 2.在A组件(接收方)进行监听Bus事件 Bus.$on('sendMsg',(msg) => { this.msg = msg }) }, data(){ return { msg:'' } } } </script> <style> .base-a { background-color: white; width: 200px; height: 300px; text-align: center; line-height: 300px; border: 1px solid black; } </style>
扩展:非父子通信
创建爷爷组件App.vue<template> <div class="app"> 我是APP组件 <button @click="change">修改数据</button> <SonA></SonA> <SonB></SonB> </div> </template> <script> import SonA from './components/SonA.vue' import SonB from './components/SonB.vue' export default { provide() { return { // 简单类型 是非响应式的 color: this.color, // 复杂类型 是响应式的 userInfo: this.userInfo, } }, data() { return { color: 'pink', userInfo: { name: 'zs', age: 18, }, } }, methods: { change() { this.color = 'red' this.userInfo.name = 'ls' }, }, components: { SonA, SonB, }, } </script> <style> .app { border: 3px solid #000; border-radius: 6px; margin: 10px; } </style>
创建儿子组件SonA,其中调用孙子组件GrandSon
<template> <div class="SonA">我是SonA组件 <GrandSon></GrandSon> </div> </template> <script> import GrandSon from './GrandSon.vue' export default { components:{ GrandSon } } </script> <style> .SonA { border: 3px solid #000; border-radius: 6px; margin: 10px; height: 200px; } </style>
创建另一个儿子组件SonB
<template> <div class="SonB"> 我是SonB组件 </div> </template> <script> export default { } </script> <style> .SonB { border: 3px solid #000; border-radius: 6px; margin: 10px; height: 200px; } </style>
创建孙子组件GrandSon:
<template> <div class="grandSon"> 我是GrandSon {{ color }} -{{ userInfo.name }} -{{ userInfo.age }} </div> </template> <script> export default { inject: ['color', 'userInfo'], } </script> <style> .grandSon { border: 3px solid #000; border-radius: 6px; margin: 10px; height: 100px; } </style>
过程:将爷爷组件中要传递到孙子组件的数据写在provide方法里,孙子组件中通过 inject:[ ]接收
v-model原理 :
v-model是不能跟props传过来的数据进行双向绑定的//App.vue <template> <div class="app"> <HelloWorld :cityId="selectId" @changeId="selectId=$event" ></HelloWorld> </div> </template> <script> import HelloWorld from './components/HelloWorld.vue' export default { data(){ return{ selectId:'102' } }, components:{ HelloWorld } } </script> <style> </style>
//HelloWorld <template> <div> <select :value="cityId" @change="handleChange" > <option value="101">北京</option> <option value="102">上海</option> <option value="103">武汉</option> <option value="104">深圳</option> <option value="105">广州</option> </select> </div> </template> <script> export default { props:{ cityId:String }, methods:{ handleChange(e){ // console.log(e.taget.value); this.$emit('changeId',e.target.value) } } } </script> <style> </style>