Vue父子组件通信的三两事(prop、emit)

32次阅读

共计 4007 个字符,预计需要花费 11 分钟才能阅读完成。

组件是 Vue 核心功能之一,合理的组件化,可以减少我们代码的冗余,提高项目的可维护性。下面,我将由浅入深的讲 Vue 的组件在讲之前,首先我们先了解一下组件的命名。HTML 是对特征名不敏感的语言,他会将所有的字符全部转换成小写。我们命名了一个组件的名称为 nameTest , 然后再其他组件里面引用 <nameTest> </nameTest>,那么我们将找不到这个组件,因为这个组件一已经将名字转换为 nametest

props : 父组件 向 子组件 传参
基本使用
Parent.vue
<template>
<div>
parent:下面是我的子组件
<childSon :userName=’name’></childSon>
</div>
</template>
<script>
import childSon from ‘./Childs’
export default {
name:’Parent’,
components:{
childSon
},
data(){
return{
name:’ 啊哈 ’
}
}
}
</script>
Childs.vue
<template>
<div>
child: 这是父组件给我传的数据——{{userName}}
</div>
</template>
<script>
export default {
name:’Childs’,
props:[‘userName’],
data(){
return{

}
}
}
</script>

我们在 Parent.vue 组件里面引用子组件 Childs.vue 然后传入 userName 参数给子组件,Childs 在 props 里面接收父组件传传来的数据。
上面的例子我们传入的是一个字符串,其实,props 可以传入 String、Number、Object、Boolen、Array 等数据类型。那么我们在接受参数的时候就会有一个问题,我们怎么知道接收的应该是字符串 ’12’ 还是数字 12 呢?所以 Vue 有一个 Prop 验证 的功能。

Prop 验证
子组件在接受数据的时候,可以指定接收具体类型的数据、是否不能为空,是否有默认值等。
Parent.vue
<template>
<div>
parent:下面是我的子组件
<childSon :name=’name’ :firstName=’firstName’ :age=’18’ ></childSon>
</div>
</template>
<script>
import childSon from ‘./Childs’
export default {
name:’Parent’,
components:{
childSon
},
data(){
return{
name:’ 大卫 ’,
firstName:’ 大华 ’
}
}
}
</script>
Child.vue
<template>
<div>
child: 这是父组件给我传的数据——name:{{name}}——firstName:{{firstName}}——lastName:{{lastName}}——age:{{age}}
</template>
<script>
export default {
name:’Childs’,
props:{
name: String,
firstName: {
type: String,// 规定值的类型
required: true // 必须传值,否则报错
},
lastName: {
type: String,
default: ‘lastNameDefault’ // 如果不传值,则为 default 的值
},
age: {
type: [String,Number], // 类型可以是多种
validator: function(value) {// 自定义验证

let num = parseInt(value)
if (num > 0 && num <100) {
return true;
} else {
return false;
}
}
}
},
data(){
return{

}
}
}
</script>
运行结果如下图:
如果我们将条件改变的时候,name 传入一个数组,firstName 不传值,age 传入一个不能转换为数字的值。
<childSon :name=[11] age=’ss’ ></childSon>
运行结果如下图:根据我们的验证规则,name 必须为一个 String 类型,所以控制台报错:希望得到一个 String, 得到了一个数组;firstName 为一个必填的值,但是我们没有传值,所以报错;age 要为一个可以转换成数字的值,但是我们穿了 ”ss”,会经过我们自定义的验证,然后抛错。
Prop 传入对象
如果我们要将一个 对象 的所有属性全部传给子组件,我们不需要将属性一个个的作为 Prop 传递,只需要将整个对象传递过去就可以。
Parent.vue
template>
<div>
parent:下面是我的子组件
<childSon v-bind=’obj’ ></childSon>
</div>
</template>
<script>
import childSon from ‘./Childs’
export default {
name:’Parent’,
components:{
childSon
},
data(){
return{
obj: {
name: ‘lily’,
age: ’16’
}
}
}
}
</script>
Childs.vue
<template>
<div>
child: 这是父组件给我传的数据——name:{{name}}——age:{{age}}
</div>
</template>
<script>
export default {
name:’Childs’,
props:{
name: String,
age: {
type: [String,Number], // 类型可以是多种
validator: function(value) {// 自定义验证

let num = parseInt(value)
if (num > 0 && num <100) {
return true;
} else {
return false;
}
}
}
}
}
</script>
运行结果如下图:我们传入一个 obj 对象,然后在子组件里面可以拿到对象的所有属性。
Prop 的单向数据传递
直接作为一个本地变量
Parent.vue
<template>
<div>
parent:<input type=’text’ v-model=”content”> 下面是我的子组件
<childSon :content=’content’ ></childSon>
</div>
</template>
<script>
import childSon from ‘./Childs’
export default {
name:’Parent’,
components:{
childSon
},
data() {
return {
content:’er’
};
},
}
</script>
Childs.vue
<template>
<div>
child: 这是父组件给我传的数据——{{con}}
</div>
</template>
<script>
export default {
name:’Childs’,
props:[‘content’],
data(){
return{
con:this.content
}
}
}
</script>
运行结果如下图:

emit : 子组件 向 父组件 传递数据
基本使用
子组件向父组件传递数据,不能像上面一样实时的传递数据,必须通过 事件 触发。我们通过 $emit 方法来向父子间传递数据,第一个参数为事件的 名称,第二个为传递的 数据,是一个可选的参数。父组件必须监听同样的事件名称才能监听到我们的这个事件,事件抛出的值必须通过 $event 或者通过一个方法来访问。
**Parent.vue
<template>
<div>
parent:这是我的子组件传给我的值:{{num}}
<childSon :content=’content’ @getNum=’getMsg’></childSon>
</div>
</template>
<script>
import childSon from ‘./Childs’
export default {
name:’Parent’,
components:{
childSon
},
data() {
return {
content:’er’,
num:”
}
},
methods: {
getMsg(num){
this.num = num;
}
}
}
</script
Childs.vue
<template>
<div>
child: 这是父组件给我传的数据——{{content}} <br />
<button @click=”sendMsgtoParent”> 点击我可以向父子间传递参数哦 </button>
</div>
</template>
<script>
export default {
name:’Childs’,
props:[‘content’],
data(){
return{
num: 0
}
},
methods: {
sendMsgtoParent(){
this.$emit(‘getNum’,this.num ++);
}
}
}
</script>
运行结果如下图:子组件定义了一个 num 变量,然后点击按钮触发 method, 通过 $emit 向父组件发送事件的名称 (getNum) 和一个参数(this.num),然后 父组件 监听事件 getNum,然后将传递值赋值给父组件的一个属性上,这样就可以是实现子组件点击一次按钮,就向父组件发送一次数据。更多实例可以参考官网。
组件间的数据双向绑定
我们知道我们可以使用 v -model 来实现数据的双向绑定。但是如果这个数据是跨组件的话,我们要怎样实现绑定吗?
首先我们先要明白 v -model 的原理。v-model 其实是分为两个方面,一方面数据层的改变引起视图层的变化,我们可以使用 v -bind 来实现,另一方面视图层的变化引起数据层的变化我们可以监听事件来实现。所以我们想要双向绑定一个数据,只需要这两步操作。具体实现参考官网。
弹框嵌套表格组件化使用
(待续 …)

正文完
 0