vue3中组件prop和emit的使用
[TOC]
组件是带有自定义名称的可复用实例,prop
向下传递,emit
向上传递。
组件prop
通过组件prop可以实现父组件向子组件传递数据
命名规则
HTML中的attribute名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用DOM中的模板时,camelCase (驼峰命名法) 的prop名需要使用其等价的kebab-case (短横线分隔命名) 命名。
在JavaScript中使用camelCase
1 2 3 4 5 6
| const app = Vue.createApp({})
app.component('blog-post', { props: ['postTitle'], template: '<h3>{{ postTitle }}</h3>' })
|
在HTML中使用kebab-case
1
| <blog-post post-title="hello!"></blog-post>
|
静态动态数据
给prop
传入一个静态的值:
1
| <blog-post title="这是个静态数据"></blog-post>
|
通过v-bind
或简写:
动态赋值:
1 2 3 4 5
| <blog-post :title="post.title"></blog-post>
<blog-post :title="post.title + ' by ' + post.author.name"></blog-post>
|
类型检查
通常组件prop
可以在组件中以简写的形式定义:
1
| props: ['title', 'likes', 'isHot', 'categoryIds', 'author']
|
也可以对每个组件prop
指定值的类型,组件prop
的类型可以是下列原生构造函数中的一个,当组件prop
验证失败的时候,vue将会产生一个控制台的警告。
null
和 undefined
值会通过任何类型验证。
- String 字符串
- Number 数值
- Boolean 布尔值
- Array 数组
- Object 对象
- Date 日期
- Function 函数
- Symbol 唯一值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| 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
通过自定义事件可以实现子组件向父组件传递数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| <!-- 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> <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
形成父子组件双向绑定来更新数据,例子参照上面代码