Vue 组件,组件通信(父子,子父,非父子组件通信)

Vue 组件

Vue组件 其实是一个html、css、js等的一个聚合体。

组件定义:
Vue.extend() 得到的是一个构造函数VueComponent( options )
options即我们之前在new Vue( options )

 Vue.component('VueHello', Hello )
 const Hello = Vue.extend({ // 组件选项
    template: `
      <div>
        <p> Vue Hello</p>
      </div>
    `,
  })

组件注册

  • 全局注册
  • 局部注册
<div id="app">
    <Demo></Demo> 
    <Hello></Hello>
</div>
  
//js代码
Vue.component('Hello',{
    template: '<div> 全局组件注册简写 </div>',
    data () { //data为啥是一个函数?
    return {
       }
     }
  })
  new Vue({
    el: '#app',
    data: {},
    components: {
      'Demo': {
        template: '<div> 局部注册简写 </div>'
      }
    },
  })

data为啥是一个函数?
因为组件是一个独立的整体,我们希望它的数据也是独立的,所以使用函数会有独立作用域,返回值必须是一个对象,因为要经过数据劫持处理。

父子组件通信

  • 在父组件模板中,将父组件数据赋值给子组件的自定义属性
  • 在子组件模板中,通过 props 属性来接收绑定在自己身上的自定义属性
<div id="app">
    <Father/>
</div>

<template id="father">
 <div>
    <h3> 父组件 </h3>
    <!-- 在父组件模板中,使用单项数据绑定,将父组件数据赋值给子组件的自定义属性 -->
    <Son :money = "money"/>
  </div>
</template>

<template id="son">
   <div>
     <h5> 子组件 </h5>
     <p> 我老爸给了我: {{ money }} </p>
   </div>
 </template>

js代码

Vue.component('Father',{
    template: '#father',
    data () {
      return {
        money: 2000
      }
    }
 })

 Vue.component('Son',{
    template: '#son',
    /* 子组件通过props属性来接收绑定在自己身上的自定义属性 */
    props: ['money'] // 这个属性在子组件模板中相当于全局变量,可以直接使用
 })

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

子父组件通信

  • 在父组件模板中,使用自定义事件绑定(v-on监听)父组件的方法
  • 在子组件模板中,通过 $emit 调用(触发)自定义事件
<div id="app">
    <Father/>v-on
</div>

  <template id="father">
    <div>
      <h3> father - 组件 </h3>
      <p> 我的小金库有: {{ gk }} </p>
      <hr>
      <!-- 在父组件模板中,使用自定义事件绑定父组件的方法 - get是自定义事件,名称随意 -->
      <Son @get = "changeGk"/>
    </div>
  </template>

  <template id="son">
    <div>
      <h5> son - 组件 </h5>
      <button @click = "give"> 给老爸红包 </button>
    </div>
  </template>

js代码

Vue.component('Father',{
    template: '#father',
    data () {
      return {
        gk: 0
      }
    },
    methods: {
      changeGk ( val ) {
        this.gk = val
      }
    }
  })


  Vue.component('Son',{
    template: '#son',
    data () {
      return {
        hongbao: 888
      }
    },
    methods: {
      give () {
        // 在这里调用自定义事件 get 
        // this.$emit('get',参数1,参数2,参数3 )
        this.$emit('get', this.hongbao )
      }
    }
  })

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

非父子组件通信

第一种:ref链实现

  • 在父组件模板中,通过ref 获得son组件的信息,并执行son组件的事件
  • 在girl组件模板中,通过 $emit 触发父组件的事件(实际上是son的事件)
<div id="app">
    <Father/>
</div>
  
  <template id="father">
    <div>
      <h3> 父组件 </h3>
      <hr>
      <Son ref = "son"></Son>  
      <hr>
      <Girl @kick = "kick"/>
    </div>
  </template>

  <template id="son">
    <div>
      <h4> Son组件 </h4>
      <p v-if='f'>我被姐姐打了</p>
    </div>
  </template>

  <template id="girl">
    <div>
      <h4> Girl组件 </h4>
      <button @click = "hit"></button>
    </div>
  </template>
Vue.component('Father',{
    template: '#father',
    methods: {
      kick () {
        // 通过ref 获得son 组件,并执行son组件的changeF
        // console.log( this )
        this.$refs.son.changeF()
      }
    }
  })

  Vue.component('Son',{
    template: '#son',
    data () {
      return {
        f: false 
      }
    },
    methods: {
      changeF () {
        this.f = !this.f
      }
    }
  })

  Vue.component('Girl',{
    template: '#girl',
    methods: {
      hit () {
        this.$emit('kick')  //触发父组件的kick事件
      }
    }
  })

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

第二种:bus事件总线实现

  • 在son组件模板中,通过bus.$on监听一个自定义事件
  • 在girl组件模板中,通过 bus.$emit 触发son组件的自定义事件
<div id="app">
    <Father/>
</div>
  
  <template id="father">
    <div>
      <h3> 父组件 </h3>
      <hr>
      <Son></Son>  
      <hr>
      <Girl/></Girl>
    </div>
  </template>

  <template id="son">
    <div>
      <h4> Son组件 </h4>
      <p v-if='f'>我被姐姐打了</p>
    </div>
  </template>

  <template id="girl">
    <div>
      <h4> Girl组件 </h4>
      <button @click = "hit"></button>
    </div>
  </template>

js代码

const bus = new Vue() // 事件总线
  //console.log(bus)
  
  Vue.component('Father',{
    template: '#father',
  })

  Vue.component('Son',{
    template: '#son',
    data () {
      return {
        f: false 
      }
    },
    mounted () { // 表示组件已经挂载结束,也就是表示这个组件已经渲染到了页面
      // console.log('mounted')
      bus.$on('cry',() => {  //监听事件
        this.f = !this.f
      })
    }
  })

  Vue.component('Girl',{
    template: '#girl',
    methods: {
      hit () {
        bus.$emit('cry')  //触发son组件的事件
      }
    }
  })
  new Vue({
    el: '#app',
    data: {},
    methods: {
      
    },
  })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值