目录
一、vue组件间传参概述
父子组件的关系可以总结为 prop 向下传递,$emit 事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过 $emit 事件给父组件发送消息
二、父传子(自定义属性 props)
1.父传子主要通过props来实现
原理:
父组件通过import引入子组件并注册,在子组件的标签上添加要传递的属性,子组件通过props接收。
接收有两种形式,一是通过数组形式[‘要接收的属性’],二是通过对象形式{}来接收,对象形式可以设置要传递的数据和默认值,而数组只是简单的接收,是只读的,不能进行修改。
注意:
- 传递参数可以是字符串、数字、对象、数组等类型的变量,也可以是函数
- 使用v-model时要切记:v-model绑定的值不能是props传过来的值(绑定基本数据类型修改会报错),因为props是不可以修改的!(如需修改请复制一份)
- props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。
2.运用
- 父组件代码 渲染子组件
html
<HelloWorld :name="name" :nameArr="nameArr"></HelloWorld>
js
data() {
return {
name:'爱鲲',
nameArr:['爱鲲','爱鲲']
};
},
components:{
HelloWorld,
},
- 子组件代码接收父组件。可以传多个属性。
-
第一种方式(只接收):
props:["name"]
-
第二种方式(限制数据类型):
props:{name:String}
-
第三种方式(限制类型、限制必要性、指定默认值):
数组形式:只读,不可设置
对象形式:可读写,限制类型,设置默认值
引用类型的默认值使用函数返回值 default(){return:[]}
接收方式一:
props:['name'],
接收方式二:
props:{name:String}, // 限制类型
接收方式三:
props: {
name: {
type: String, // 限制类型
default: '只因', // 默认值 传参失败时替代默认值
required: true, // 必要性
},
nameArr: {
type: Array, // 限制类型
default() {// 引用类型 设置默认值
return ['只因', '只因']
},
}
},
data() {
return {
age: this.name, // 接收过来的参数直接使用或赋值使用都可
}
},
子组件接受的父组件的值分为引用类型和普通类型两种:
普通类型:字符串(String)、数字(Number)、布尔值(Boolean)、空(Null)
引用类型:数组(Array)、对象(Object)引用类型的默认值使用函数返回值 default(){return:[ ]}
三、子传父 (自定义事件 this.$emit)
原理:
子组件向父组件传数据使用自定义事件, vue 组件提供了一个emit(‘自定义事件名’, 传递的数据) ),子组件传递数据时,触发响应的事件函数,就会自动触发通过$emit给父组件绑定的自定义事件,自定义事件接受一个参数,参数就是子组件传递过来的数据。
使用形式1 (触发后传递参数)
- 子组件绑定一个事件,通过 this.$emit() 来触发。在子组件中绑定一个事件,并给这个事件定义一个函数
<template>
<button class="active" @click="$emit('counterchange','参数1','参数2'....)">
单击传参
</button>
</template>
- 在父组件中定义并绑定 CountChange 事件
<CounterCom @counterchange="n=$event"></CounterCom>
$event 代表子组件传递给父组件的数据 使用变量 n 来接收数据,进而操作数据 "n=$event"
使用形式2 (触发后调用方法并传递参数)
子组件
// 通过函数操作emit触发自定义事件
<button class="button" @click="testEmit">自定义事件</button>
methods: {
// 通过emit触发自定义事件child
testEmit(){
this.$emit('child','参数1')
},
},
父组件
// 定义自定义事件
<Child :testProps='testProps' @child='handlerChild'/>
methods: {
// 自定义事件,在child事件触发的时候调用
handlerChild(msg){ // 接受多少参数则写对应数量形参
this.msgP = msg
}
},
解绑自定义事件($emit)
在绑定自定义事件的子组件中调用$off方法即可解绑事件
unbind(){
this.$off("add"); // 解绑单个事件
this.$off(["add","addTwo"]); // 解绑多个事件
this.$off(); // 解绑所有事件
}
this.$nextTick作用
定义:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
所以就衍生出了这个获取更新后的DOM的Vue方法。所以放在Vue.nextTick()回调函数中的执行的应该是会对DOM进行操作的 js代码;
理解:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数。
什么时候用:
当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。
如使用v-if或v-show将隐藏的输入框显示出来并使用this$refs.inputTitle.focus()自动获取焦点时即可使用该方法。
实例:
this.$nextTick(() => {
// 使用计时器也可实现,但更推荐nextTick
this$refs.inputTitle.focus()
});
Vue.nextTick(callback) 使用原理:
原因是,Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环 (event loop) 当中观察到数据变化的 watcher 推送进这个队列。如果这个watcher被触发多次,只会被推送到队列一次。这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和DOM操作。而在下一个事件循环时,Vue会清空队列,并进行必要的DOM更新。
当你设置 vm.someData = 'new value',DOM 并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新时才会进行必要的DOM更新。如果此时你想要根据更新的 DOM 状态去做某些事情,就会出现问题。。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。