10分钟学会-10种vue组件通信

132 阅读6分钟

vue组件通信汇总

1、组件间通信props(一)

props 子组件声明接收属性三种写法

  • 数组方式【‘todos’】
  • 对象限定类型 { todos:Array}
  • 对象限定类型+默认值等 { todos:{type:Array,default:[]}}

功能:父子之间通信

  • 父可以给子传递 非函数和函数

  • 传非函数数据 就是父给子

  • 传函数数据 本质是父想要子的数据

    特殊: 路由配置 props(三种) 路由组件之间没有标签,但是可以把参数通过路由映射为属性 在路由器中使用props 1- props:true 只能传递params参数 2- props:{name:'xxx',age:'20'} 传递额外的参数 3- props:(route)=>{ adress:route.query.adress, skuId:route.params.skuId }

2、组件间通信自定义事件(二)

2.1、原生dom事件

浏览器自己调用 固定的几个 click mouseEnter mouseLeave等

  1. 事件类型 ---- 固定的几个
  2. 回调函数 ---- 自己去定义的
  3. 触发(分发、触发事件) 谁调用 ---- 系统调用浏览器去调用
  4. event事件对象 ----- 默认事件数据对象

2.2、自定义事件

  1. 事件类型 ---- 无数个
  2. 回调函数 ---- 自己去定义的
  3. 谁调用 ---- 自己去调用 通过$emit('自定义事件名',传参)
  4. 默认传递的是什么 ---- 默认传递的是自己给的参数 (有就有,没有就没有)

2.3、原生dom事件在html标签和组件标签上的区别

  • 在html标签上添加就是原生的dom事件
  • 在组件标签上添加就是自定义事件,添加修饰符.native变成原生dom事件,事件添加在组件根元素上,(事件委派)

2.4、vue自定义的事件在html标签和组件标签上的区别

  • 在html标签上添加自定义事件无意义
  • 在组件上添加自定义事件,事件名可以任意,也可以和原生的dom事件名相同,但是自定义事件

3、全局事件总线(三)

所有场合都可以用

3.1、成为全局事件总线对象的标准?

  1. 所有的组件对象都可以看到
  2. 可以使用onon和emit方法

3.2、怎么添加事件总线

  1. 安装总线,一般在main.js中 new vue内部,在创建之前

    • beforeCreate(){
          Vue.prototype.$bus = this
      }
      
  2. 接收数据组件

    • //获取总线给总线绑定自定义事件
      this.$bus.$on('xxx', 回调函数(形参接收数据))
      
  3. 发送数据组件

    • // 获取总线触发总线身上绑定的自定义事件
      this.$bus.$emit('xxx', 发送的数据)
      

4、v-model 深入(四)

element-ui表单相关项都使用到了v-model

  • 官方网站也提出了怎么去使用
  • 本质上还是自定义事件和props组合
  • 实现父子数据双向同步

v-model一般用于表单类元素或组件标签上,在组件标签内部也会有表单类元素,实现父子数据双向同步

  • 子组件中有表单类元素,用v-model
  • 子组件中没有表单类元素,用.sync修饰符

4.1、在html标签上使用v-model

//v-model的本质 必须要在表单类或组件标签中使用
<input type="text" 
    :value = “data”  //读取数据
    @input = "data = $event.target.value"  //写数据
>
//等同于
<input type="text" v-model="data">

4.2、在组件标签上使用v-model

//组件标签上 v-model本质
//父组件,数据在父组件当中
<Child
    :value = "data"  父组件传递属性给子组件,子组件用props接受
    @input = "data = $event" 必须是input事件,需要子组件内部触发
></Child>
​
//子组件
//先接收数据
    props:['value']
//子组件表单类元素
<input type="text" 
    :value="value"  //显示父组件传过来的数据
    @input="$emit('input',$event.target.value)"  //触发自定义事件,修改父组件的数据
>

5、sync 属性修饰符(五)

  • 功能:

    • 实现父子组件双向数据同步问题,和 v-model 实现效果几乎一样
    • 本质上还是自定义事件和props组合
  • 区别:

    • v-model一般用于带表单项的组件
    • .sync属性修饰符一般用于不带表单项的组件
//.sync本质,一般用于非表单元素,(其实表单元素页可以用)
//父给子传数据后面添加.sync
//父组件
<Child 
    :money="money" 
    @update:money="money = $event"
></Child>
//等同于
<Child :money.sync="money"></Child>
//子组件
//触发的事件名称必须是update:XXX,.sync的要求就是它
<button 
    //触发事件,更新数据
    @click="$emit('update:money',money - 100)"
>花钱</button>

注意:父子之间传递的如果基本数据类型,各自有各自的数据。如果传递的是对象数据类型,引用地址是同一个

v-model和sync修饰符父子组件同步数据流程

  1. 父组件当中money传递给子组件,子组件使用
  2. 子组件当中要修改父组件的数据,必须触发父组件给子组件绑定的的自定义事件
  3. 子组件触发自定义事件传递过来新的数据,父组件更改
  4. 父组件当中数据更改之后,重新传递给子组件,子组件也就发生变化了

6、attrsattrs和linsteners(六)

  • 本质:

    • 就是父组件中给子组件传递的,所有属性组成的对象,及自定义事件方法组成的对象
  • 使用场景

    • attrsattrs和listeners主要是用来让我们根据已有的组件封装自己的组件
  • 描述

    • $attrs,所有属性组成的对象,排除props声明接收的属性 以及class style
    • $linsteners,所有自定义事件方法组成的对象
//可以通过v-bind    一次性把父组件传递过来的属性添加给子组件
//可以通过v-on      一次性把父组件传递过来的事件监听添加给子组件

7、parentparent 和 children以及$ref(七)

  • $children:所有子组件对象的数组
  • $parent:代表父组件对象
  • $refs:可以直接操作子组件内部的数据及方法
//1.给子组件标签使用ref标识
// 通过this.$refs.son拿到组件对象  
// his.$refs.son.msg=XXX 直接修改组件数据
<Son ref="son" />
// 2.给html标签使用ref
// this.$refs.pp拿到html标签dom元素
<p ref='pp'></p>

一般慎用以下方法:

  • 找子组件时【$children】 是将子组件对象放入数组中 不能通过索引操作 因为位置不固定
  • 找父组件时【$parent】 存在组件共用 此时可能不是一个父组件 会存在多个父组件

8、作用域插槽(八)

原理:

  1. 父组件传递数据给到子组件 子组件props接收数据 然后通过遍历展示数据
  2. 但是数据的结构或样式由父组件决定 此时需要将遍历过的数据重新传递给父组件,
  3. 将要改变的数据部分用slot包裹 在slot标签中将数据传递给父组件
  4. 父组件接收到子组件传递过来的数据 在template标签中 使用slot-scope='{结构出来的数据}' 然后进行样式或结构的改变

例如:

//父组件
//1、先将数据传递给子组件
<List :todos='todos'>
    //4-父组件接收slot-scope="{todo}"子组件传递的数据然后改变结构
    <template slot-scope="{todo}">
        //5、根据父组件的数据,判断决定子组件的样式和结构
        <li :style="{color:todo.isComplete?'red':'yellow'}">{{todo.text}}</li>
    </template>
</List>
//子组件
//接收数据
props:['todos']
//2、遍历展示数据
<li v-for="(todo, index) in todos" :key="index">
    //3、将遍历后的数据需要发生结构变化的数据传递给父组件
    <slot :todo='todo' :index='index'>
        {{todo.text}}
    </slot>
</li>

9、vuex(九)

5个核心概念 state mutations actions getters modules

10、消息的订阅和发布 PubSubJS (十)

下载安装pubsub.js     
import pubSub from "pubsub-js"; 
​
发布消息组件中传递数据:
pubSub.publish("消息名", 传递数据); 
​
订阅一个消息:接收数据
  pubSub.subscribe('消息名',(接收数据)=>{})

11、element-uix相关

element-ui的button添加click事件会触发,添加dblclick就不会触发的问题

element-ui的button  子组件内部触发了这个单击事件
element-ui的button  子组件内部没有触发这个双击事件  必须在@dblclick.native转化为原生dom事件  就可以触发双击事件
​
扩展双击点击触发element-ui button事件,使用原生.native

12、扩展

多个组件有部分相同的js代码

  • html js css 相同 ---- 封装组件
  • 单个组件js代码重复 ---- 封装函数
  • 不同的组件js代码重复 ---- 封装混合(混入)

12.1、vue混入

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

例子:

新建一个myminxi.js文件,在js文件中暴露一个对象 对象内部可以有data methods computed...

//定义一个混入对象
//会将js文件中暴露出的数据 方法等混入到组件内部
export const xxxMixin = {
    methods:{
        重复的代码写在这        
    }
}
​
//在组件内部引入混入对象
import myminxi from './myminxi.js'
//使用mixins:[mymixin]  例如:
import mymixin from './mymixin'
export default {
    name: 'Daughter',
    mixins:[mymixin],
},

当混入对象和组件对象发生冲突时,会递归合并,以组件对象优先