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等
- 事件类型 ---- 固定的几个
- 回调函数 ---- 自己去定义的
- 触发(分发、触发事件) 谁调用 ---- 系统调用浏览器去调用
- event事件对象 ----- 默认事件数据对象
2.2、自定义事件
- 事件类型 ---- 无数个
- 回调函数 ---- 自己去定义的
- 谁调用 ---- 自己去调用 通过$emit('自定义事件名',传参)
- 默认传递的是什么 ---- 默认传递的是自己给的参数 (有就有,没有就没有)
2.3、原生dom事件在html标签和组件标签上的区别
- 在html标签上添加就是原生的dom事件
- 在组件标签上添加就是自定义事件,添加修饰符.native变成原生dom事件,事件添加在组件根元素上,(事件委派)
2.4、vue自定义的事件在html标签和组件标签上的区别
- 在html标签上添加自定义事件无意义
- 在组件上添加自定义事件,事件名可以任意,也可以和原生的dom事件名相同,但是自定义事件
3、全局事件总线(三)
所有场合都可以用
3.1、成为全局事件总线对象的标准?
- 所有的组件对象都可以看到
- 可以使用emit方法
3.2、怎么添加事件总线
-
安装总线,一般在main.js中 new vue内部,在创建之前
-
beforeCreate(){ Vue.prototype.$bus = this }
-
-
接收数据组件
-
//获取总线给总线绑定自定义事件 this.$bus.$on('xxx', 回调函数(形参接收数据))
-
-
发送数据组件
-
// 获取总线触发总线身上绑定的自定义事件 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修饰符父子组件同步数据流程
- 父组件当中money传递给子组件,子组件使用
- 子组件当中要修改父组件的数据,必须触发父组件给子组件绑定的的自定义事件
- 子组件触发自定义事件传递过来新的数据,父组件更改
- 父组件当中数据更改之后,重新传递给子组件,子组件也就发生变化了
6、linsteners(六)
-
本质:
- 就是父组件中给子组件传递的,所有属性组成的对象,及自定义事件方法组成的对象
-
使用场景
- listeners主要是用来让我们根据已有的组件封装自己的组件
-
描述
- $attrs,所有属性组成的对象,排除props声明接收的属性 以及class style
- $linsteners,所有自定义事件方法组成的对象
//可以通过v-bind 一次性把父组件传递过来的属性添加给子组件
//可以通过v-on 一次性把父组件传递过来的事件监听添加给子组件
7、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、作用域插槽(八)
原理:
- 父组件传递数据给到子组件 子组件props接收数据 然后通过遍历展示数据
- 但是数据的结构或样式由父组件决定 此时需要将遍历过的数据重新传递给父组件,
- 将要改变的数据部分用slot包裹 在slot标签中将数据传递给父组件
- 父组件接收到子组件传递过来的数据 在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],
},
当混入对象和组件对象发生冲突时,会递归合并,以组件对象优先