vue组件传值之Props和$emit
前言
上次我们谈了$refs和$parent传值,发完之后我发现还有种传值方式$attrs和$listeners,小Q可能一时间想不起来那么多,希望大家见谅,有错误的地方也欢迎大家指正😁
今天我们就来说说目前比较常用props和$emit😎
正文
首先props是什么?怎么用?我们来看官方文档
有小伙伴说这个解释看不懂啊,简单来说就是组件间传值,我们再来看官方文档传值的方法
很显然,可以传数组和对象嘛,但是这里小Q要说一下,数组方式目前已经不推荐了,尽量少用
那这玩意到底怎么用呢,废话不多说上码
<template>
<div class="father">
<h2>父组件</h2>
<!-- 01.基本使用 -->
<son info="你好吗?" skill="不,我不好" food="吃西兰花可以平复心情哦"></son>
</div>
</template>
<script>
// 导入子组件
import son from './components/01.son.vue'
export default {
// 注册子组件
components: {
son
}
}
</script>
<style>
body {
margin: 0;
}
.father {
height: 100vh;
background-color: skyblue;
/* 去除 因为h2 造成的塌陷 */
overflow: hidden;
}
</style>
<template>
<div class="son">
<h3>子组件</h3>
<p>{{ info }}</p>
</div>
</template>
<script>
export default {
name: 'son',
// 定义props 数组 基本用法
props: ['info', 'skill', 'food']
}
</script>
<style>
.son {
border: 3px solid hotpink;
width: 300px;
height: 300px;
background-color: orange;
}
</style>
这种是简单的父组件传值给子组件父组件中的值要与props中的值要相对应,不然无法取到,那么对象用法怎么用呢?
对象的用法相比于数组的用法多了类型校验
<template>
<div class="son">
<h3>子组件</h3>
<p>{{ info }}</p>
</div>
</template>
<script>
export default {
name: 'son',
props: {
info: {
// 类型
type: String,
// 默认值
default: '喜洋洋,美羊羊'
},
food: {
type: String,
// 必填项
required: true,
validator (value) {
// console.log('value:', value)
// 返回 true 成功 false 失败
// return false
// 必须传
const res = ['鲱鱼罐头', '黑蒜', '榴莲', '逆风十里臭豆腐'].includes(
value
)
// 存在 true 反之就是false
return res
}
}
}
}
</script>
<style>
.son {
border: 3px solid hotpink;
width: 300px;
height: 300px;
background-color: orange;
}
</style>
type是定义类型,常见的有(Number,String,Boolean,Array,Object)
required是否必填 validator是自定义验证函数
小Q提醒大家子组件中获取过来的值不建议去修改(虽然可以修改)因为子组件中的值是父组件流过来的,如果子组件修改了值,父组件中出现了数据变化,子组件中的值也会随之改变(单项数流)
$emit使用:
子组件:
-
子组件这次叫做
emit-use -
通过
$emit('事件名'),触发事件 -
事件名可以随便写,有意义即可
<template>
<div class="emit-container">
<input @click="add" type="button" value="点击累加">
</div>
</template>
<script>
export default {
name: 'emit-use',
methods:{
add(){
// 触发add事件
this.$emit('add')
}
}
}
</script>
<style></style>
父组件:
-
注册并实现add事件
-
可以实现一个计数功能
<template>
<div>
<!-- emit基本使用 -->
<h2>你点了:{{ num }} 次</h2>
<emit-use @add="fatherAdd"></emit-use>
</div>
</template>
<script>
export default {
data() {
return {
num:0
}
},
methods:{
fatherAdd(){
console.log('fatherAdd')
this.num++
}
}
}
</script>
有的时候,我们不仅仅要触发事件,还需要传递自定义的参数,只需要在emit方法的后面依次写上需要的参数即可
语法:emit('事件名',参数1,参数2....)
子组件:
-
子组件这次叫做
emit-param -
子组件中通过双击事件来触发
emit -
同时传递数据
<template>
<div class="emit-container">
<input @dblclick="add" type="button" value="双击加2">
</div>
</template>
<script>
export default {
name: 'emit-param',
methods:{
add(){
// 触发add事件,同时传递参数
this.$emit('add',2)
}
}
}
</script>
<style></style>
父组件
-
注册事件,并定义参数
-
获取并使用参数
-
这里为了对比,上一步不传递数据的组件也一起保留作为对比
-
点击第一个组件,一次加1
-
双击第二个组件,一次加2
<template>
<div>
<!-- emit传递参数 -->
<h2>你点了:{{ num }} 次</h2>
<!-- 不传递参数 -->
<emit-use @add="fatherAdd"></emit-use>
<!-- 传递参数 -->
<emit-param @add="fatherAdd"></emit-param>
</div>
</template>
<script>
export default {
data() {
return {
num: 0
}
},
methods: {
fatherAdd(num) {
console.log('fatherAdd')
console.log(`num:${num}`)
// 如果有参数,获取并累加
if(num){
this.num+=num
}else{
// 如果没有参数,累加1
this.num++
}
}
}
}
</script>
<style></style>
注意:
-
如果要传递多个参数,用逗号分隔,继续向后写
-
父组件注册事件时,也定义对应个参数即可
-
如果不想挨个传递,可以把多个数据放到一个对象中,也是可以的
END
这就是props和$emit的使用了,多在测试代码中摸索,找到属于自己的理解方式,这样对这种传值的方法理解能更深一些。如果有什么问题可以直接私我,欢迎大家和我一块学习进步。