查漏补缺,温故知新
父子组件之间如何进行通信?
- 父组件传递给子组件:通过props属性
- 子组件传递给父组件:通过 $emit 触发事件
使用场景
父组件有些数据,需要子组件进行展示
什么是Props?
- Props 是在组件上注册的一些自定义attribute
- 父组件给这些attribute赋值,子组件通过attribute的名称获取到对应的值
Props常见的用法:
- 字符串数组,数组中的字符串就是attribute的名称
- 对象类型,可以在指定attribute名称的同时,指定它需要传递的类型、是否必须、默认值等
父组件 App.vue
<template>
<div>
<show-message title="来自app的title" content="来自app的content"></show-message>
</div>
</template>
子组件ShowMessage.vue
<template>
<div>
<h2>组件展示title:${{title}}</h2>
<p>组件展示content:${{content}}</p>
</div>
</template>
<script>
export default{
props:["title","content"]
}
</script>
数组用法中只能说明传入的attribute的名称,并不能对其进行任何形式的限制
组件ShowMessage.vue
export default{
props:{
title:String,//指定类型
conetnt:{
type:String,
require:true,
default:"姥姥姥姥“
}
}
}
使用对象语法的时候,可以限制传入的类型,是否必须的,默认值
细节一 :type的类型都可以是哪些?
String,Number,Boolean,Array,Object,Date,Function,Symbol
细节二:对象类型的其他写法
props:{
messageInfo:String,
propA:Number,
propB:[String,Number] ,// 多个可能的类型
propC:{
type:String,
required:true,//必须传值
},
// 带有默认值的数字
propD:{
type:number,
default:100
},
//带有默认值的对象
propE:[
type:Object,
// 对象或数组默认值必须从一个工厂函数获取
default(){
return {message:"hello"}
},
//带有默认值的函数
propF:{
type:Function,
// 用作默认值的函数
default(){
return "default function"
}
},
// 自定义验证函数
propG:{
validator(value){
// 这个值必须匹配下列字符串中的一个
return ['success','warning','danger'].includes(value)
}
},
]
}
细节三 : Prop的大小写命名
- html中的attribute名是大小写不敏感的,浏览器会把所有大写自负解释为小写
- 这意味着当使用DOM模版时,camelCase(驼峰)的prop名需要使用其等价的kebab-case(短横线分隔命名)
<show-message messageInfo='' />
<show-message message-info='' />
非Prop的Attribute
- 当传递给一个组件某个属性,但是该属性并没有定义对应的props或者emits时,就称为非Prop的Attribute
- 常见的包括class,style,id属性等
Attribute继承
当组件有单个根节点时,非prop的父组件attribute将自动添加到子组件根节点
禁用Attribute继承和多根节点
如果不希望组件的根元素继承attribute,可以在组件中设置inheriAttrs:false。
禁用attribute继承的常见情况是需要将attribute应用于根元素之外的其他元素;不禁用会默认加在根元素上
可以通过$attrs来访问所有非props的attribute
<template>
<h2 :class="$attrs.class">只继承class</h2>
<p v-bind='$attrs">全部继承</p>
</template>
多个根节点的attribute
多个根节点的attribute如果没有显示绑定,控制台会报警告,必须手动的指定要绑定到哪一个属性上
<template>
<h2> 多个根节点01</h2>
<h2 > 多个根节点02</h2>
<p :id='$attrs.id'> 多个根节点 03</p>
</template>
子组件传递给父组件
使用场景
- 子组件有事件发生(比如点击),父组件需要切换内容
- 子组件有内容想要传递给父组件的时候
使用过程
- 子组件中定义好在某些情况下触发的事件名称
- 父组件中以v-on的方式传入要监听的事件名称,并且绑定到对应的方法中
- 子组件中发生某个事件的时候,根据事件名称触发对应的事件
自定义事件
父组件App.vue
<template>
<counter-operation @addOne = "add" @subOne = 'sub" />
</template>
<scrpit>
export default{
methods:{
add(){
...
},
sub(){
....
}
}
}
</script>
CounterOperation.vue
<template>
<div>
<button @click='increment">+1</button>
<button @click='decrement'>-1</button>
</div>
</template>
<script>
export default{
emits:["addOne","subOne"] ,// vue3 里面注册事件
methods:{
increment(){
this.$emit("addOne")
},
decrement(){
this.$emit("subOne")
}
}
}
</script>
如果需要传值给父组件
increment(){
this.$emit("addOne",10,20,30) ,//可以一次传递多个数据
}
在vue3中,还可以对传递的参数进行验证
对象写法,目的是为了进行参数验证
emits:{
add:null.
sub:null,
addN:payload = >{
},
subN:(num,name,age)=>{
if(num > 10){. return true} // 小于10的时候也会传递过去,但是控制台会报警告
return false
}
}