《vue-组件-组件通信》

51 阅读1分钟

1、组件通信

组件关系可分为父子组件通信、兄弟组件通信、跨级组件通信

1.1、$emit()自定义事件—子组件给父组件传递数据

子组件用$emit()来触发事件,可以调用父组件的方法并传递数据。

实例:通过加减给父组件传递数据-源库

<div id="app">
    <span>支付宝到账{{money}}元</span>
    <app2 @change="handle"></app2>
    
</div>
Vue.component('app2',{
    props[],
    template:'\
    <div>\
        <button @click='handleincrease'>+1000</button>\
        <button @click='handlereduce'>-1000</button>\
    <div>\
    ',
    data(){
        count = 2000
    },
    methods:{
        handleincrease(){
            this.count += 1000;
            this.$emit('change',this.count);
        },
        handlereduce(){
            this.count -= 1000;
            this.$emit('change',this.count);
        }
    }
})
new Vue({
    el:'#app',
    data:{
        money:2000,
    },
    methods:{
        change(money){
            this.money = money;
        }
    }
})

1.2、在组件中使用v-model(子传父)

$emit的代码,这行代码实际上会触发一个 input事件, input后的参数就是传递给v-model绑定的属性的值

v-model 其实是一个语法糖,这背后其实做了两个操作:

  • v-bind 绑定一个 value 属性
  • v-on 指令给当前元素绑定 input 事件

要使用v-model,要做到:

  • 接收一个 value 属性。
  • 在有新的 value 时触发 input 事件
<span>您的支付宝到账{{money}}元</span>
<app2 v-model="money"></app2>
   Vue.component('app2',{
          template:"\
            <div>\
              <button @click='handleincrease'>+1000</button>\
              <button @click='handlereduce'>-1000</button>\
            </div>",
          data(){
            return{
              count:2000
            }
          },
          methods:{
            handleincrease(){
               this.count += 1000;
               this.$emit('input',this.count);
            },
            handlereduce(){
               this.count -= 1000;
               this.$emit('input',this.count);
            }
          },
          
        })

        new Vue({
            el:'#app',
            data:{
              money:2000,
            },
        })

1.3、非父组件之间的通信(兄弟组件通信)

非父子关系需要通信,在简单的场景下,可以使用一个空的vue实例作为中央事件总线

var bus = new Vue();
 Vue.component('app3',{
    template:'<div>我是app3,我接收到:{{msg}}</div>',
         data(){
           return{
             msg:'我是app3,我还没有数据',
           }
         },
        created(){
          //在app3组件创建钩子监听事件
        this.$root.bus.$on('getData',value =>{
          this.msg = value;
        });
      }
          
        })
        
        Vue.component('app2',{
          template:'<button @click="handle">点击把数据传递app3</button>',
          data(){
            return{
              msg:'来自app2的数据',
            }
          },
         methods:{
                   handle(){
                   //触发app2组件的事件
                    this.$root.bus.$emit('getData',this.msg);
                   }   
        }
      })

        new Vue({
            el:'#app',
            data:{
            //Bus中介
             bus:new Vue()
            },
        })

1.4、父链 this.$parent(父传子,子修改父数据)

 Vue.component('child-component',{
          template:'<button @click="setData">点击修改父组件数据</button>',
          
         methods:{
                   setData(){
                    this.$parent.msg = '我是子组件,我修改了数据';
                   }   
        },
      })

1.5、子链 this.$refs(子传父)

//定义的a,b,c是ref
<app2 ref='b'></app2>
<app3 ref='a'></app3>
<hr>
<child-component ref='c'></child-component>
<span>{{msg}}</span>
<button @click='getChildData'>我是父组件,点我拿到子组件内容</button>
<span>{{childData}}</span>
data(){
  return{
    msg:'我是app1的数据',
  }
},
 new Vue({
     el:'#app',
     data:{
      bus:new Vue(),
       msg:'我是父组件,我的数据还没更新',
       childData:'还未拿到值'
     },
   methods:{
     getChildData(){
     //用来拿子组件中的内容
       this.childData = this.$refs.b.msg;
     }
   }
 })