前端与后端 / 技术笔记

Vue 与组件实践

从响应式数据开始,理解 Vue 组件如何拆分页面、传递信息并组织交互逻辑。

内容章节
6 节
阅读重点
响应式与通信
示例语言
Vue / TypeScript

第一次写 Vue 页面时,最直观的感觉通常是:修改一个变量,页面自己就变了。

HTML 示例

markup

<script setup lang="ts">import { ref } from "vue";
const count = ref(0);</script>
<template>    <button @click="count++">{{ count }}</button></template>

真正值得理解的是数据、组件和界面之间建立的协作关系。

Vue 让我们用数据描述界面,再把变化自动同步到页面。

1. Vue 的响应式到底在做什么

普通 JavaScript 变量改变以后,浏览器并不知道应该更新哪一段 HTML。Vue 会把需要追踪的数据包装成响应式对象。

TypeScript 示例

typescript

const price = ref(399);const amount = ref(2);

模板读取它们时,Vue 会记住这段界面依赖了哪些数据。以后 priceamount 改变,对应的界面就会重新计算。

文本示意

text

模板读取数据Vue 记录依赖数据发生变化更新相关界面

Vue 会建立一张“谁依赖谁”的关系表,并在依赖变化时触发对应更新。

2. 单文件组件如何组织页面

Vue 的 .vue 文件通常把一块界面的逻辑、模板和样式放在一起。

HTML 示例

markup

<script setup lang="ts">defineProps<{ title: string }>();</script>
<template>    <article class="project-card">{{ title }}</article></template>
<style scoped>.project-card { padding: 16px; }</style>

这种组织方式让同一个组件的三种职责保持靠近。页面仍然按照业务区域拆分,例如导航、项目列表和详情弹窗。

独立职责决定组件边界,代码行数只适合作为辅助判断。

3. Props 与事件怎样流动

父组件通过 Props 把数据传给子组件,子组件通过事件把用户动作告诉父组件。

HTML 示例

markup

<ProjectCard    :project="project"    @select="selectedProject = project"/>

可以把它理解成:

文本示意

text

父组件↓ Props子组件↑ Event父组件

子组件不应该悄悄修改父组件的数据。单向流动能让问题更容易追踪:数据从哪里来,动作又通知了谁。

4. computed 和 watch 怎么选

computed 用来得到一个可以从现有状态计算出的值。

TypeScript 示例

typescript

const total = computed(() => price.value * amount.value);

watch 用来在数据变化后执行额外动作,例如保存草稿或调用接口。

TypeScript 示例

typescript

watch(keyword, async (value) => {    results.value = await searchProjects(value);});

判断方法很简单:如果需要的是一个结果,用 computed;如果需要和外部系统同步,再用 watch

5. Composition API 如何拆逻辑

当组件越来越大,可以把同一件事相关的状态和方法提取到组合函数中。

TypeScript 示例

typescript

export function useProjectSearch() {    const keyword = ref("");    const results = ref<Project[]>([]);
    async function search() {        results.value = await searchProjects(keyword.value);    }
    return { keyword, results, search };}

组合函数给一组相关逻辑提供清楚的名字。页面组件负责组织界面,组合函数负责一项可复用的能力。

6. 一个组件从数据到交互的完整过程

一张可点击的项目卡片,可以拆成下面这条链路:

文本示意

text

父组件准备项目数据通过 Props 传给 ProjectCard模板根据数据生成界面用户点击卡片子组件触发 select 事件父组件更新选中状态Vue 更新详情区域

理解这条链路以后,遇到界面没有更新时,就可以依次检查数据是否响应式、Props 是否传入、事件是否触发,以及状态是否真的改变。