Vue 3 中的 props
和 emits
是组件通信的基础,它们允许组件之间的数据流动和事件触发。以下是 Vue 3 中 props
和 emits
的详细知识点:
Props
一. 基础用法
在Vue中,props
是父组件传递给子组件的数据。以下是在父组件中定义和传递 props
的步骤:
1. 定义子组件
首先,你需要有一个子组件,它声明了它期望接收的 props
。
<!-- ChildComponent.vue -->
<template><div>{{ message }}</div>
</template><script>javascript">
export default {props: {message: String}
}
</script>
2. 在父组件中使用子组件
然后,在父组件中,你可以像使用HTML元素一样使用这个子组件,并传递 props
。
<!-- ParentComponent.vue -->
<template><ChildComponent :message="parentMessage" />
</template><script>javascript">
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {parentMessage: 'Hello from parent!'}}
}
</script>
3. 使用 v-bind
传递 props
你可以使用 v-bind
指令(简写为冒号 :
)来动态传递数据作为 props
。
<ChildComponent :propA="valueA" :propB="valueB" />
4. 使用字面量值传递 props
你也可以直接传递字面量值作为 props
。
<ChildComponent :count="10" />
5. 使用计算属性传递 props
你可以使用计算属性的结果作为 props
。
<template><ChildComponent :filteredList="computedList" />
</template><script>javascript">
export default {data() {return {items: ['item1', 'item2', 'item3']}},computed: {computedList() {return this.items.filter(item => item.includes('2'));}}
}
</script>
6. 使用方法返回值传递 props
你可以使用方法的返回值作为 props
。
<template><ChildComponent :user="getUserName" />
</template><script>javascript">
export default {methods: {getUserName() {return 'Kimi';}}
}
</script>
7. 使用插槽插槽传递 props
有时候,你可能会通过插槽的内容传递 props
。
<template><ChildComponent><template v-slot="{ propA }"><div>{{ propA }}</div></template></ChildComponent>
</template>
在父组件中定义 props
的关键在于理解 props
是单向数据流,即它们只能从父组件流向子组件,而不能反过来。这有助于保持组件之间的数据隔离和组件的可重用性。
二. 类型检查和验证
Vue 3 支持对 props
进行类型检查和验证,确保数据的正确性。
javascript"><script>
export default {props: {// 基础类型检查propA: Number,// 对象类型检查propB: {type: Object,default: () => ({ x: 0, y: 0 })},// 带有验证函数的 proppropC: {type: String,validator: value => {return ['small', 'medium', 'large'].includes(value);}}}
}
</script>
三. 默认值
你可以为 props
提供默认值,以便在没有提供值时使用。
javascript"><script>
export default {props: {propA: {type: String,default: 'default value'}}
}
</script>
四. 非响应式 Props
props
是非响应式的,这意味着如果你更改了 props
的值,Vue 不会更新 DOM。如果你需要响应式数据,应该使用局部数据。
Emits
1. 基础用法
emits
选项用于定义组件可以触发的事件。在子组件中,你可以使用 this.$emit
来触发这些事件。
javascript">// 子组件
<script>
export default {emits: ['update'],methods: {updateValue() {this.$emit('update', 'new value');}}
}
</script>
在父组件中,你可以监听这些事件:
<!-- 父组件 -->
<template><ChildComponent @update="handleUpdate" />
</template><script>javascript">
export default {methods: {handleUpdate(value) {console.log(value); // 'new value'}}
}
</script>
2. 事件修饰符
Vue 3 支持事件修饰符,如 .stop
、.prevent
和 .once
,这些修饰符可以在监听事件时直接使用。
<!-- 父组件 -->
<template><ChildComponent @update.stop="handleUpdate" />
</template>
3. 事件参数
你可以在触发事件时传递参数,这些参数可以在父组件中接收。
javascript">// 子组件
<script>
export default {emits: ['custom-event'],methods: {triggerCustomEvent() {this.$emit('custom-event', { key: 'value' });}}
}
</script>
在父组件中:
<!-- 父组件 -->
<template><ChildComponent @custom-event="handleCustomEvent" />
</template><script>javascript">
export default {methods: {handleCustomEvent(payload) {console.log(payload); // { key: 'value' }}}
}
</script>
在 <script setup>
中使用 Props 和 Emits
Vue 3 引入了 <script setup>
语法糖,使得 props
和 emits
的声明更加简洁。
1. defineProps 和 defineEmits
javascript"><script setup>
import { defineProps, defineEmits } from 'vue';// 声明 props
const props = defineProps({propA: String,propB: Number
});// 声明 emits
const emit = defineEmits(['update', 'custom-event']);// 触发事件
function updateValue() {emit('update', 'new value');
}
</script>
2. withDefaults
javascript"><script setup>
import { withDefaults } from 'vue';// 声明并设置默认值
const props = withDefaults(defineProps<{propA?: string;propB?: number;
}>(), {propA: 'default string',propB: 100
});
</script>
3. 类型定义
<script setup lang="ts">
import { defineProps, defineEmits } from 'vue';// 使用 TypeScript 定义 props 和 emits 类型
const props = defineProps<{propA: string;propB?: number;
}>();const emit = defineEmits<{(e: 'update', value: string): void;(e: 'custom-event', payload: { key: string }): void;
}>();
</script>
通过这些知识点,你可以在 Vue 3 中灵活地使用 props
和 emits
来构建组件化的应用。