组件系统
Props、插槽与异步组件。
组件系统
这一课你将能做到
- 把页面拆分成可复用的组件
- 用
props向子组件传数据 - 用
emits让子组件向父组件发消息 - 用
slots实现内容分发 - 用
provide/inject跨层级传数据
为什么要学
组件是 Vue 的「积木」。一个页面由无数小组件拼成:按钮、卡片、表单、弹窗。不会组件化,代码会越写越乱,改一处崩三处。
人话:组件就像乐高积木。每块积木(组件)有自己的形状(props)和接口(emits),你可以把它们拼成城堡(页面),也能拆下来重复用。
先建立图像
<!-- UserCard.vue -->
<script setup>
defineProps({ name: String, age: Number })
</script>
<template>
<div class="card">
<h3>{{ name }}</h3>
<p>{{ age }} 岁</p>
</div>
</template>
<!-- App.vue -->
<script setup>
import UserCard from './components/UserCard.vue'
</script>
<template>
<UserCard name="张三" :age="25" />
<UserCard name="李四" :age="30" />
</template>
跟着做
步骤 1:创建并使用组件
在 src/components/ 下新建 HelloWorld.vue:
<script setup>
const props = defineProps({ msg: String })
</script>
<template>
<p>{{ props.msg }}</p>
</template>
在 App.vue 中引入使用:
<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<HelloWorld msg="你好" />
</template>
步骤 2:props 传数据
<script setup>
// 数组语法(简单)
defineProps(['title', 'count'])
// 对象语法(推荐,可校验)
const props = defineProps({
title: { type: String, required: true },
count: { type: Number, default: 0 },
items: { type: Array, default: () => [] }
})
</script>
props 是单向数据流:父传子,子不能改。
步骤 3:emits 子传父
<!-- Child.vue -->
<script setup>
const emit = defineEmits(['add', 'remove'])
function handleClick() {
emit('add', 1)
}
</script>
<template>
<button @click="handleClick">通知父组件</button>
</template>
<!-- Parent.vue -->
<script setup>
function onAdd(n) { console.log('收到', n) }
</script>
<template>
<Child @add="onAdd" />
</template>
步骤 4:slots 插槽
<!-- Card.vue -->
<template>
<div class="card">
<div class="header"><slot name="header">默认标题</slot></div>
<div class="body"><slot>默认内容</slot></div>
</div>
</template>