vue3中组件prop和emit的使用
组件是带有自定义名称的可复用实例,prop
向下传递,emit
向上传递。
组件prop
通过组件prop可以实现父组件向子组件传递数据
命名规则
HTML中的attribute名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用DOM中的模板时,camelCase (驼峰命名法) 的prop名需要使用其等价的kebab-case (短横线分隔命名) 命名。
在JavaScript中使用camelCase
const app = Vue.createApp({})
app.component('blog-post', {
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
在HTML中使用kebab-case
<blog-post post-title="hello!"></blog-post>
静态动态数据
给prop
传入一个静态的值:
<blog-post title="这是个静态数据"></blog-post>
通过v-bind
或简写:
动态赋值:
<!-- 动态赋予一个变量的值 -->
<blog-post :title="post.title"></blog-post>
<!-- 动态赋予一个复杂表达式的值 -->
<blog-post :title="post.title + ' by ' + post.author.name"></blog-post>
类型检查
通常组件prop
可以在组件中以简写的形式定义:
props: ['title', 'likes', 'isHot', 'categoryIds', 'author']
也可以对每个组件prop
指定值的类型,组件prop
的类型可以是下列原生构造函数中的一个,当组件prop
验证失败的时候,vue将会产生一个控制台的警告。
null
和 undefined
值会通过任何类型验证。
- String 字符串
- Number 数值
- Boolean 布尔值
- Array 数组
- Object 对象
- Date 日期
- Function 函数
- Symbol 唯一值
// blog-post子组件prop定义
props: {
title: {
type: String,
required: true
},
likes: {
type: Number,
default: 0
},
isHot: {
type: Boolean,
default: false
},
category: {
type: String,
required: true,
validator(value) {
return ['frontend', 'backend', 'devops'].includes(value)
}
},
author: {
type: Object,
default() {
return { name: '佚名', country: '未知' }
}
},
commentIds: {
type
}
}
<!-- 父组件调用blog-post -->
<blog-post :title="post.title" :category:="post.category"
:author="{
name: 'Xiguapengpeng',
country: 'China'
}"
></blog-post>
自定义事件emit
通过自定义事件可以实现子组件向父组件传递数据
<!-- info-modal子组件定义 -->
<template>
<div id="center" v-if="isOpen">
<input type="text" :value="inputName"/>
<input type="text" :value="age"/>
<button @click="closeModal">关闭模态框</button>
</div>
</template>
export default defineComponent({
name: 'info-modal',
data: function () {
return {
isOpen: false
}
},
props: {
inputName: {
type: String,
required: true
},
age: {
type: Number,
required: true
}
},
emits: ['close', 'update:inputName', 'update:age'],
setup(props, context) {
const closeModal = () => {
context.emit('close', !isOpen)
context.emit('update:inputName', props.inputName)
context.emit('update:age', props.age)
}
return {
closeModal
}
}
})
<!-- 父组件调用info-modal -->
<template>
<!-- v-model的作用是父子组件变量双向绑定 -->
<!-- v-model可以创建多个绑定 -->
<info-modal v-model:input-name="username" v-model:age="age" @close="closeClick"></info-modal>
</template>
export default defineComponent({
components: {
InfoModal
},
data () {
return {
username: "xiguapengpeng",
age: 18
}
},
setup(props, context) {
const closeClick = () => {
alert('i am closed')
}
return {
closeClick
}
}
})
v-model绑定
子组件可以进行事件通知以外,还可以使用v-model
形成父子组件双向绑定来更新数据,例子参照上面代码