[Vue 3 从零到上线]-第三篇:网页的指挥官------指令系统 (v-if, v-for, v-bind, v-on)
一、 组件化的核心哲学:高内聚与低耦合
在计算机科学中,有两个非常重要的概念:
-
高内聚(High Cohesion):一个积木只做一件事情,并且把它做好。比如"搜索框"组件只负责输入和搜索逻辑。
-
低耦合(Low Coupling):积木与积木之间不要有太深的纠缠。换掉一个积木不应该导致整个房子垮塌。
为什么选择组件化?
-
可复用性:你的"登录按钮"可以在首页用,也可以在个人中心用。
-
可维护性:如果导航栏出了 Bug,你只需要去 Navbar.vue 里修,不需要在 2000 行的 App.vue 里大海捞针。
-
可读性:看到
<TaskHeader />、<TaskList />、<TaskFooter />,任何开发者都能一秒看懂你的页面结构。
二、 深度解析:<script setup> 与组件导出
在 Vue 3 + TS 中,由于我们使用了
1. 自动注册
在以前的 Vue 版本中,你导入一个组件后,还需要在 components 选项里声明它。 但在 <script setup> 中:
typescript
<script setup lang="ts">
import MyComponent from './MyComponent.vue'
// 只要 import 了,在 template 里就能直接当标签用
</script>
2. 组件命名规范
-
文件名:建议使用大驼峰(PascalCase),如 UserInfo.vue。
-
标签名:在模板中建议也使用大驼峰
<UserInfo />,这能让你一眼看出这是自定义组件,还是原生的 HTML 标签(如<div>)。
三、 插槽 (Slots):给积木留出定制空间
如果一个组件的内容是写死的,那它的复用性会很低。插槽就是组件上的"接口",允许父组件把不同的内容塞进去。
1. 匿名插槽:最简单的替换
HTML
<div class="card">
<slot></slot> </div>
<BaseCard>
<p>这是我塞进去的一段文字</p>
</BaseCard>
2. 具名插槽:精确定位
如果你的卡片有标题、内容和底部,你可以用名字来区分:
HTML
<div class="card">
<header><slot name="header"></slot></header>
<main><slot></slot></main>
<footer><slot name="footer"></slot></footer>
</div>
<BaseCard>
<template #header><h1>我的日记</h1></template>
<p>今天天气不错</p>
<template #footer><button>查看更多</button></template>
</BaseCard>
四、 TypeScript 在组件中的应用初探
虽然这一篇我们还没深入讲组件间的数据传递(Props),但 TS 已经在帮我们做组件的类型检查了。
当你在 VS Code 中使用 Volar 插件时:
-
如果你导入了一个不存在的组件,TS 会变红报错。
-
当你把鼠标悬停在
<MyButton />标签上,它会显示这个组件的文件定义路径。 -
它会检查你在组件标签上写的所有属性是否合法。
五、 实战演练复盘:如何重构你的代码
作为小白,最快提高水平的方法就是重构(Refactor)。我们将之前的任务清单项目按照功能拆解:
-
拆出列表项:
<script setup lang="ts"> // 这里只负责展示某一个任务的样式 </script> <template>TodoItem.vue<slot></slot> <button>删除</button></template> <style scoped> .item { display: flex; align-items: center; gap: 10px; padding: 5px; } </style> -
在主页面组装:
<script setup lang="ts"> import { ref } from 'vue' import TodoItem from './components/TodoItem.vue'App.vueconst list = ref(['学习组件', '练习插槽', '尝试重构'])
<template>
</script><TodoItem v-for="task in list" :key="task"> {{ task }} </TodoItem></template>
六、 给新手的架构建议:什么时候该拆?
刚学组件的小白容易走两个极端:
-
死活不拆:所有的东西都写在一起,最后代码乱成一团。
-
拆得太细:连一个 都要封成组件,导致寻找代码像走迷宫。
拆分的黄金法则:
-
重复性:这个 UI 结构在页面中出现了两次以上。
-
复杂度:某块代码逻辑(TS)加上布局(HTML)超过了 100 行。
-
独立性:这块功能逻辑非常清晰(比如一个上传头像的弹窗),可以独立测试。
🌟 下篇预告:数据的秘密通道
现在的积木虽然拼好了,但它们之间是孤立的。
父组件怎么把任务列表发给子组件展示?
子组件里的"删除"按钮被点击了,怎么告诉父组件去删掉数据?
在第五篇中,我们将学习组件通信的双剑合璧:Props(传进去) 与 Emits(发出来)。这是 Vue 3 + TS 开发中最重要的数据流动逻辑!