组件通信

组件通信

注意: 组件通信, 无论效果是如何的, Vue都是单向数据流(组件之间的数据通信

1. 父子组件通信
(一)父组件往子组件传值props

①定义父组件,父组件传递 number这个数值给子组件,如果传递的参数很多,推荐使用json数组{}的形式

②定义子组件,子组件通过 props方法获取父组件传递过来的值。props中可以定义能接收的数据类型,如果不符合会报错。
当然也可以简单一点,如果不考虑数据类型,直接 props:[“number”,“string”]就可以了,中括号包裹,多个值使用,分隔。

③假如接收的参数 是动态的,比如 input输入的内容 v-model的形式

④父子组件传值,数据是异步请求,有可能数据渲染时报错
原因:异步请求时,数据还没有获取到但是此时已经渲染节点了
解决方案:可以在 父组件需要传递数据的节点加上  v-if = false,异步请求获取数据后,v-if = true

(二)、子组件往父组件传值,通过emit事件
* A: 绑定的是简单类型数据
  1. 父组件中定义数据, 通过单向数据绑定的形式, 将数据绑定在子组件身上, 属性是自定义属性,
  2. 子组件通过配置项中的props接收数据, props可以是一个数组,数组中放的是自定义属性名称
  3. 那么这个自定义属性可以向data中的数据一样直接在子组件模板中使用
  4. 父组件中数据一旦修改, 子组件数据就会修改, 那么这也就是单项数据流

代码示例

<body>
  <div id="app">
    <Father></Father>
  </div>
  <template id="father">
    <div class="father-box">
      <h3> father 组件</h3>
      <hr>
      <Son v-bind:money = "money"></Son>
      <Son :money = "money"></Son>
    </div>
  </template>
  <template id="son">
    <div class="son-box">
      <h3> son 组件</h3>
      <p> 我爸这个月给了我: {{ money }}生活费 </p>
    </div>
  </template>
</body>
<script>
  Vue.component('Father',{
    template: '#father',
    data(){
      return {
        money: 1000
      }
    }
  })
  Vue.component('Son',{
    template: '#son',
    props: ['money']
  })
  new Vue({
    el: '#app'
  })
</script>
1.5. 子父通信(效果上像, 间接的使用了父组件的东西 ) 【不推荐大家使用】
B: 绑定复杂数据类型 --------
  1. 父组件中的数据是一复杂数据类型, 那么父组件绑定数据的时候, 给子组件的是一个引用地址
  2. 子组件可以通过这个引用地址, 修改这个数据
  3. 效果上像, 子组件和父组件通信了, 违背单项数据流

代码示例

<body>
    <div id="app">
        <Father></Father>
    </div>
    <template id="father">
     <div>
        <h3>father</h3>
        <p>father现在有: {{sifangqian.money}} 块 </p>
        <Son :sifangqian = 'sifangqian'></Son>
     </div>
</template>
    <template id="son">
    <div>
     <h3>Son</h3>
     <input type="text" v-model = "sifangqian.money">
     <p> 老爸给了我:{{ sifangqian.money }}块 </p>
    </div>
</template>
</body>
<script>
    Vue.component('Father', {
        template: '#father',
        data() {
            return {
                sifangqian: {
                    money: 1000
                }
            }
        }
    })
    Vue.component('Son', {
        template: '#son',
        props: ['sifangqian']
    })
    new Vue({
        el: '#app'
    })
</script>
  • C: 父组件可以传递一个方法给子组件
  1. 父组件定义方法, 然后将这个方法通过单向数据绑定的形式传递给子组件
  2. 子组件通过props属性接收, 然后通过 @click = “方法名”

代码示例

<body>
  <div id="app">
    <King></King>
  </div>
  <template id="king">
      <div>
        <h3> 国王: </h3>
        <p> 我国库中有:{{ gk }} 钱 </p>
        <People :getmoney = "getMoney"></People>
      </div>
  </template>
  <template id="people">
      <div>
        <h3> 子民 </h3>
        <button @click = "getmoney(1000)"> 上缴 </button>
      </div>
  </template>
</body>
<script>
  Vue.component('King',{
    template: '#king',
    data(){
      return {
        gk: 0
      }
    },
   methods: {
    getMoney(value){
      this.gk += value
    }
   }
  })
  Vue.component('People',{
    template: '#people',
    props: ['getmoney']
  })
  new Vue({
    el: '#app'
  })
</script>
  • D: 通过自定义事件来实现通信
  1. 父组件中定义 数据 和 方法(方法时用来操作数据的)
  2. 在子组件身上绑定自定义事件
  3. 子组件定义方法, 在这个方法中通过 this.$emit(eventType,实际参数) 来调用自定义事件的事件处理程序
<!-- html结构代码 -->
<div id="app">
<King></King>
</div>
<template id="king">
<div>
<h3> I am king </h3>
<!-- <People v-on: get = "get"></People> -->
<p> 国库中有:{{ gk }} 钱 </p>
<People @get = "get"></People>
</div>
</template>
<template id="people">
<div>
<h3> I am people </h3>
<button @click = "give"> 交钱 </button>
</div>
</template>
<!-- js代码 -->
Vue.component('King',{
template: '#king',
data () {
return {
gk: 0
}
},
methods: {
get( value ){
this.gk += value
}
}
})
Vue.component('people',{
template: '#people',
data () {
return {
money: 2000
}
},
methods: {
give () {
this.$emit('get', this.money/2)
}
}
})
new Vue({
el: '#app'
})
3. 非父子组件通信
使用ref来绑定组件, (注意:ref也可以绑定DOM元素) 【ref链】
    1. 在父组件的模板中, 使用ref = refName 绑定在两个兄弟组件身上
    1. 在任意一个子组件中, 就可以通过 this. p a r e n t . parent. parent.refs.refName 就可以获得另一个子组件了, 同时这个自组件身上的数据和方法同样也得到了

代码示例

<!----html--->
<body>
  <div id="app">
    <Father></Father>
  </div>
  <template id="father">
    <div>
      <h3> 我是父亲 </h3>
      <hr>
      <Boy ref = "boy" ></Boy>
      <hr>
      <Girl ref = "girl" ></Girl>
      <div ref = 'hello'>
        你好
      </div>
    </div>
  </template>
  <template id="boy">
      <div>
        <h3> I am boy </h3>
        <p> 我现在有:{{ cash }} 钱 </p>
      </div>
  </template>
  <template id="girl">
    <div>
      <h3> I am girl </h3>
      <button @click = 'give'> 给body 1000块 </button>
    </div>
  </template>
</body>
<script>
  Vue.component('Father',{
    template: '#father',
    data () {
      return {
        name: 'father'
      }
    }
  })
  Vue.component('Boy',{
    template: '#boy',
    data () {
      return {
        cash: 2000
      }
    },
    methods: {
      incrementCash (value) {
        this.cash += value
      }
    }
  })
  Vue.component('Girl',{
    template: '#girl',
    data () {
      return {
        money: 1000
      }
    },
    methods: {
      give(){
        console.log('====================================');
        console.log(this.$parent);
        console.log('====================================');
        // console.log( this.$parent.$refs ) // { body: Vuecomponent,girl: VueComponent }
        this.$parent.$refs.boy.incrementCash( this.money )
        // this.$parent.$children
      }
    }
  })
  new Vue({
    el: '#app'
  })
</script>
通过事件总线(bus)
    1. 它是通过事件的发布(声明), 以及事件的订阅(触发)来做的
    1. 首先在js中 创建一个bus对象(vm)
var bus = new Vue()
    1. 在Count组件中定义数据, 和修改数据的方法
    1. 在Count组件中 通过 created 钩子 , 进行bus事件的发布
      (created表示组件在创建结束之后就会自动触发的一个方法)
created: {
bus.$on('add',this.addCount)
}
    1. 在MyButton组件的方法中通过 bus进行事件的订阅
increment () {
bus.$emit( 'add' )
}

代码示例

<body>
  <div id="app">
    <my-button></my-button>
    <Count></Count>
  </div>
  <template id="button">
    <button @click = "increment"> increment </button>
  </template>
  <template id="count">
    <div>
      {{ count }}
    </div>
  </template>
</body>
<script>
  var bus = new Vue()
  Vue.component('MyButton',{
    template: '#button',
    methods: {
      increment () {
        bus.$emit('add')
      }
    }
  })
  Vue.component('Count',{
    template: '#count',
    data () {
      return {
        count: 0
      }
    },
    methods: {
      addCount(){
        this.count ++
      }
    },
    created () { //created表示组件在创建结束之后就会自动触发的一个方法
      //表示组件的装载结束(template模板的装载)
     bus.$on('add',this.addCount)
    }
  })
  new Vue({
    el: '#app'
  })
</script>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值