组件的通信小结

组件通信的分类

  • 组件通信, 无论效果是如何的, Vue都是单向数据流(组件之间的数据通信)
  • 通信的目的:传参、控制(A操控B做一个事件)、数据共享

1.父子组件的通信

  • 绑定的是简单类型数据
    1. 父组件中定义数据, 通过单向数据绑定的形式, 将数据绑定在子组件身上, 属性是自定义属性,
    2. 子组件通过配置项中的props接收数据, props可以是一个数组,数组中放的是自定义属性名称
    3. 那么这个自定义属性可以向data中的数据一样直接在子组件模板中使用
    4. 父组件中数据一旦修改, 子组件数据就会修改, 那么这也就是单项数据流
    • 子组件用改变父组件中传来的数据,虽然会改变,但也会有警告
<div id="app">
    <father></father>
</div>
<template id="father">
    <div>
        这是父组件
        <son :money='money'></son>
    </div>
</template>
<template id="son">
    <div>
        这是子组件{{num}}
        收到来自父亲的钱
        {{money}}
        <button @click='change_father_money'>点击钱加1</button>
    </div>
</template>
components:{
    'father':{
        template:'#father',
        data() {
            return {
            money:1000
            }
        },
        components:{
            'son':{
                template:'#son',
                props:['money'],
                data() {
                    return {
                        num:13
                    }
                },
                methods:{
                change_father_money(){
                    this.money++;
                }  
                }

2.子父组件的通信(效果上像, 间接的使用了父组件的东西 ) 【不推荐使用】

  • 绑定复杂数据类型 --------
    1. 父组件中的数据是一复杂数据类型, 那么父组件绑定数据的时候, 给子组件的是一个引用地址
    2. 子组件可以通过这个引用地址, 修改这个数据
    3. 效果上像, 子组件和父组件通信了, 违背单项数据流
    • 子组件修改父组件传过来的值,父组件里面的值也发生改变
<template id="son">
    <div>
        这是子组件
        收到来自父亲的钱
        <input type="text" v-model='money.a'>
        {{money.a}}
        <br>
        {{money.b}}
    </div>
</template>
Vue.component('son',{
        template:'#son',
        props:['money'],
    })
  • 父组件可以传递一个方法给子组件
    1. 父组件定义方法, 然后将这个方法通过单向数据绑定的形式传递给子组件
    2. 子组件通过props属性接收, 然后通过 @click = “方法名”
    • 子组件操作父组件传过来的方法,会对父组件起作用
<template id="son">
        <div>
            这是子组件
            收到来自父亲的钱
            <button @click='incrementmoney'>点击父组件的数值改变</button>
        </div>
    </template>
Vue.component('father',{
    template:'#father',
    methods:{
        incrementMoney(){
            this.money.a++;
        }
    }
})
Vue.component('son',{
    template:'#son',
    props:['incrementmoney'],
})
  • 通过自定义事件来实现通信
    1. 父组件中定义 数据 和 方法(方法时用来操作数据的)
    2. 在子组件身上绑定自定义事件
    3. 子组件定义方法, 在这个方法中通过 this.$emit(eventType,实际参数) 来调用自定义事件的事件处理程序
    <template id="father">
        <div>
            <son @give='give'></son>
        </div>
    </template>
    Vue.component('father',{
       methods:{
           give(value){
                this.money.a+=value
           }  
       }
    })
        Vue.component('son',{
        methods:{
            giveyou(){
                this.$emit('give',100)
            }
        }
    })

非父子组件通信

  • 使用ref来绑定组件, (注意:ref也可以绑定DOM元素) 【ref链】
    • 在父组件的模板中, 使用ref = refName 绑定在两个兄弟组件身上
    • 在任意一个子组件中, 就可以通过 this. p a r e n t . parent. parent.refs.refName 就可以获得另一个子组件了, 同时这个自组件身上的数据和方法同样也得到了
    • 效果就是:点击girl的按钮,son里面的数值会发生改变
    <div id="app">
        <father></father>
    </div>
    <template id="father">
        <div>
            <h3>这是父组件</h3>
            <son ref='son'></son>
            <girl ref='girl'></girl>
        </div>
    </template>
    <template id="son">
        <div>
            <h4>这是son</h4>
            {{this.money}}
        </div>
    </template>
    <template id="girl">
        <div>
            <h4>这是girl</h4>
            <button @click='give_son_money'>点击son的money值添加</button>
        </div>
    </template>
    Vue.component('father',{
        template:'#father',
    })
    Vue.component('son',{
        template:'#son',
        data(){
            return {
                money:100
            }
        },
        methods: {
            get_girl_money(value){
                this.money+=value
            }
        },  
    }) 
    Vue.component('girl',{
        template:'#girl',
        data(){
            return {
                money:20000
            }
        },
        methods:{
            give_son_money(){
                this.$parent.$refs.son.get_girl_money(this.money/2)
            }
        }
    }) 
  • 通过事件总线(bus)
    • 它是通过事件的发布(声明), 以及事件的订阅(触发)来做的
    • 首先在js中 创建一个bus对象(vm)
      var bus = new Vue()
      
    • 在Count组件中定义数据, 和修改数据的方法
    • 在Count组件中 通过 created 钩子 , 进行bus事件的发布
          created: {
          bus.$on('add',this.addCount)
          }
      
    • 在MyButton组件的方法中通过 bus进行事件的订阅
          increment () {
          bus.$emit( 'add' )
          }
      
  • 案例中的两个组件不是父子关系,也不是’兄弟姐妹’的关系
  • 但是一个组件可以使用另一个组件的方法
    <div id="app">
        <one></one>
        <another></another>
    </div>
    <template id="one">
        <div>
            <h4>这是one</h4>
            {{this.money}}
        </div> 
    </template>
    <template id="another">
        <div>
            <h4>这是another</h4>
            <button @click='add_one_money'>点击one里面的数值添加</button>
        </div>
    </template>
var bus=new Vue()
    Vue.component('one',{
        template:'#one',
        data(){
            return {
                money:0
            }
        },
        methods:{
            addMoney(){
                this.money++;
            }
        },
        created(){
            bus.$on('add',this.addMoney)
        }
    })
    Vue.component('another',{
        template:'#another',
        data(){
            return {
                money:100
            }
        },
        methods: {
           add_one_money(){
               bus.$emit('add')
           }
        },  
    }) 

多组件共享状态

  • 使用 Vue-Router
  • 使用状态管理工具 Vuex
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值