Vue2组件通信深入

1. 组件间通信的六种方式

  1. 第一种:props

    • 适用场景:父子组建通信

    • 注意事项:

    如果父组件给子组件传递的是「函数」:本质是子组件给父组件传递数据

    如果父组件给子组件传递的是「非函数」:本质是父组件给子组件传递数据

    • 书写方式:3种

      1. 第一种方式(只接收):props:['name']

      2. 第二种方式(限制类型):props:{name:String}

      3. 第三种方式(限制类型、限制必要性、指定默认值):

        props:{
        	name:{
        	type:String, //类型
        	required:true, //必要性
        	default:'老王' //默认值
        	}
        }
        
        
    • 小提示:路由的props书写形式:布尔值、对象、函数形式

  2. 第二种:自定义事件

    • 适用场景:子组件给父组件传递数据
    • $on和$emit
  3. 第三种:全局事件总线

    • 适用场景:万能
    • Vue.propotype.$bus = this
  4. 第四种:发布订阅pubsub-js(在React中使用比较多)

    • 适用场景:万能
  5. 第五种: Vuex

    • 适用场景:万能
  6. 第六种:插槽

    • 适用场景:父子组件通信(标签)
    • 默认插槽
    • 具名插槽
    • 作用域插槽

2. 自定义事件深入

  1. 事件分类

    • 原生事件:鼠标事件、键盘事件等等
    • 自定义事件
  2. 事件三要素

    • 事件源
    • 事件类型
    • 事件回调
    <!-- 1. 原生DOM绑定原生事件 -->
    <button @click="handler"></button>
    
    <!-- 2. 组件标签绑定原生事件(不起作用,因为默认当成自定义事件,需要添加.native修饰符)本质上是个子组件的根节点绑定事件——利用了事件的委派 -->
    <Event1 @click.native="handler1"></Event1>
    
    <!-- 3. 原生DOM绑定自定义事件(没有意义,无法触发$emit) -->
    <button @xxx="handler2"></button>
    
    <!-- 4. 组件标签绑定自定义事件 -->
    <Event2 @click="handler3" @xxx="handler3"></Event2>
    <!-- 并在Event组件中使用$emit触发事件 -->
    <button @click="$emit('click','自定义事件click')"></button>
    <button @click="$emit('xxx','自定义事件xxx')"></button>
    

3. v-model深入【组件通信方式的一种】

  • v-model是Vue框架中的指令,主要结合表单元素一起使用(文本框、单选、复选框等)

  • v-model实现原理:value与input事件实现的

  • 需求1:用户在input输入框输入的数据在span中同步展示

    <!-- 首先在data中配置 -->
    data() {
    	return {
    		message: ""
    }
    }
    
    <!-- 1. 通过v-model双向数据绑定实现 -->
    <input type="text" v-model="message">
    <span>{{message}}</span>
    
    <!-- 2. 通过v-bind单项数据绑定和原生DOM事件oninput实现 
    		oninput事件:当表单元素文本内容发生变化时会触发一次回调,与onchange不同的		是:不需要失去焦点即可触发 
    -->
    <input 
           type="text" 
           :value="message" 
           @input="message = $event.target.value">
    <span>{{message}}</span>
    
    
  • 需求2:用户在子组件input输入框输入的数据在父组件的span中同步展示

    一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的model 选项可以用来避免这样的冲突

    <!-- 3. 深入学习v-model,实现父子组件数据同步(实现父子组件通信)-->
    <!-- 首先在父组件data中配置 -->
    data() {
    	return {
    		message: ""
    }
    }
    
    <!-- 方法一:利用props和自定义事件
    	 组件标签中须要注意的两个问题:
    	(1):value到底是什么?是父组件向子组件传递的props
    	(2)@input到底是什么?是自定义事件 这里的$event不能更改否则无法接收参数
    -->
    <CustomInput :value="message" @input="message = $event"/>
    <span>{{message}}</span>
    
    <!-- 方法二:在组件标签中使用v-model指令 -->
    <CustomInput v-model="message"/>
    <span>{{message}}</span>
    
    <!-- 在子组件中须要注意的两个问题:
    	(1):value到底是什么?是v-bind绑定的动态属性,它的值为父组件传递过来的		 	  	  message
    	(2)@input到底是什么?是给原生DOM绑定的原生事件
    -->
    <input
           type="text"
           :value="value"
           @input="$emit('input',$event.target.value)">
    <!-- 并声明接收props -->
    props: ['value']
    

4. 属性修饰符sync【组件通信方式的一种】

  • 需求:props的双向绑定,即可以在子组件中修改props并反馈到父组件中

  • 注意使用.sync修饰符时不要忘了在子组件中声明接收props

  • :number.sync的含义

    1. 代表父组件给子组件传递props:[‘number’]
    2. 给当前子组件绑定了一个自定义事件:update:number=“number = $event”
    <!-- 在父组件中:-->
    <!-- 方法一:不使用sync修饰符 -->
    <syncTest
      :number="number"
      @update:number="number = $event"
    ></syncTest>
    <span>{{number}}</span>
    
    <!-- 方法二:使用sync修饰符 -->
    <syncTest
      :number.sync="number"
    ></syncTest>
    <span>{{number}}</span>
    <!-- 配置number的值 -->
    data() {
    	number: 100
    }
    
    <!-- 在子组件中:-->
    <button @click="$emit('update:number',number-1)">
        点我number-1
    </button>
    <span>{{number}}</span>
    <!-- 声明接收number -->
    props: ['number']
    

5. $attrs$listeners

  1. $attrs是子组件一个属性,可以用来获取父组件传递过来的props属性
  • 例:在父组件中给子组件传递属性

    <HintButton 
                type="success"
                icon="el-icon-delete"
                size="mini"
                title="提示按钮"
    ></HintButton>
    
  • 在子组件中通过$attrs获取传递过来的属性可以通过v-bind绑定到元素上

  • 注意:绑定的时候v-bind不能简写为:

    <el-button v-bind:"$attrs"></el-button>
    
  • 也可以单独绑定(比较麻烦)

    <el-button 
               :type="$attrs.type" 
               :icon="$attrs.icon"
               :size="$attrs.size"
    ></el-button>
    
  • 如果父组件传递过来的属性在子组件中已经使用props声明接收,则$attrs获取不到

    props: ['title']
    

在这里插入图片描述

> 第一行为不使用props声明接收title属性,打印```this.$attrs```的结果
> 第二行为使用props声明接收title属性,打印```this.$attrs```的结果
  1. $listeners也是子组件的一个属性,可以获取到父组件传递给子组件的不含.native修 饰符的自定义事件
  • 在子组件中通过$listeners获取传递过来的自定义事件可以通过v-on绑定到元素上

  • 注意绑定的时候v-on不能简写为@

    使用方法同$attrs

6. $children$parent

  1. $children是组件实例的属性,可以获取到当前组件的所有直接子组件,如果有多个则返回「数组」
  • 例:使用forEach()方法遍历并操作

    this.$children.forEach(item => item.money -= 100)
    
  • 注意:$children并不能保证顺序,切记不要这样书写

    this.$children[0]
    this.$children[1]
    

    $refs也可以获取子组件,但每次只能获取一个,进行批量操作的时候比较麻烦

  1. $parent是组件实例是属性,可以获取到当前组件的父组件
  • 例:操作父组件的money数据

    this.$parent.money -= 100;
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值