文章目录

Vue 组件:单文件组件与组合式 API

发布于 2026-04-13 00:20:48 · 浏览 23 次 · 评论 0 条

Vue 组件:单文件组件与组合式 API

Vue 3 引入的组合式 API(Composition API)配合单文件组件(SFC),极大地提升了代码的逻辑复用性和类型推导能力。本指南将详细介绍如何从零开始构建一个结构清晰、逻辑严密的 Vue 组件。


理解单文件组件结构

单文件组件(.vue 文件)将一个组件的逻辑、模板和样式封装在同一个文件中。

  1. 新建一个后缀为 .vue 的文件,例如 UserProfile.vue
  2. 编写基础的文件结构,包含三个顶层标签:
<template>
  <!-- HTML 模板区域 -->
</template>

<script setup>
  <!-- JavaScript 逻辑区域 -->
</script>

<style scoped>
  /* CSS 样式区域 */
</style>

<script setup> 是一个编译时宏,使得组合式 API 的使用更加简洁。在 style 标签上添加 scoped 属性,可以确保 CSS 样式仅作用于当前组件。


定义响应式数据

在组合式 API 中,我们需要显式地创建响应式状态。ref 用于基本类型,reactive 用于对象类型。

  1. 导入 refreactive 函数。
  2. 声明变量 userName 存储字符串,userInfo 存储对象。
<script setup>
import { ref, reactive } from 'vue';

// 使用 ref 定义基本类型响应式数据
const userName = ref('张三');

// 使用 reactive 定义对象类型响应式数据
const userInfo = reactive({
  age: 25,
  email: 'zhangsan@example.com'
});
</script>

<script> 中修改 ref 的值需要通过 .value 属性,而在 <template> 中会自动解包,无需使用 .value


实现计算属性

计算属性用于基于响应式数据衍生出新的状态,具有缓存特性。

  1. 导入 computed 函数。
  2. 创建一个计算属性 description,自动拼接用户信息。
<script setup>
import { ref, reactive, computed } from 'vue';

// ... 前面的响应式数据定义 ...

// 定义计算属性
const description = computed(() => {
  return `${userName.value} 今年 ${userInfo.age} 岁`;
});
</script>

若要计算带有折扣的价格,可以使用数学公式表达逻辑。假设原价为 $P$,折扣率为 $d$,最终价格为 $F = P \times (1 - d)$。

const price = ref(100);
const discount = ref(0.1); // 10% 折扣

const finalPrice = computed(() => {
  return price.value * (1 - discount.value);
});

编写方法与事件处理

组件内的交互逻辑通过方法实现。

  1. 定义 updateAge 函数来修改年龄。
  2. 定义 resetInfo 函数来重置数据。
<script setup>
// ... 导入和定义 ...

const updateAge = () => {
  userInfo.age += 1;
};

const resetInfo = () => {
  userName.value = '匿名';
  userInfo.age = 0;
};
</script>

在模板中,使用 @ 符号(v-on 的简写)绑定事件:

<template>
  <div>
    <p>姓名: {{ userName }}</p>
    <p>简介: {{ description }}</p>
    <button @click="updateAge">增加年龄</button>
    <button @click="resetInfo">重置信息</button>
  </div>
</template>

组件通信:Props 与 Emits

组件间通信通过 Props 接收数据,通过 Emits 触发事件。

  1. 定义 props,接收父组件传递的初始数据。
  2. 定义 emits,声明可触发的事件列表。
<script setup>
// 使用 defineProps 定义接收的属性
const props = defineProps({
  initialTitle: {
    type: String,
    default: '默认标题'
  }
});

// 使用 defineEmits 定义可触发的事件
const emit = defineEmits(['submit-form']);

const handleSubmit = () => {
  // 触发事件,并传递数据给父组件
  emit('submit-form', { user: userName.value, age: userInfo.age });
};
</script>

在模板中使用 props

<template>
  <h1>{{ initialTitle }}</h1>
  <button @click="handleSubmit">提交表单</button>
</template>

生命周期钩子

组合式 API 提供了 onMountedonUpdated 等生命周期钩子函数。

  1. 导入所需的生命周期函数。
  2. 调用钩子函数并在回调中执行逻辑。
<script setup>
import { onMounted, onUnmounted } from 'vue';

onMounted(() => {
  console.log('组件已挂载到 DOM');
});

onUnmounted(() => {
  console.log('组件即将卸载');
});
</script>

以下是组件生命周期的执行流程示意图,清晰展示了从创建到销毁的各个阶段:

graph LR A["创建组件实例"] --> B["Setup"] B --> C["Created: beforeCreate & created"] C --> D["Mounted: onBeforeMount & onMounted"] D --> E["更新状态: State Changed"] E --> F["Updated: onBeforeUpdate & onUpdated"] F --> E D --> G["卸载组件: onBeforeUnmount & onUnmounted"] G --> H["销毁实例"]

响应式 API 对比

为了更好地选择合适的 API,下表列出了 refreactive 的主要区别:

特性 ref reactive
适用数据 基本类型、对象、数组 对象、数组
访问/修改方式 脚本中需 .value,模板自动解包 直接访问属性
解构响应性 失去响应性(需 toRefs 失去响应性(需 toRefs
重新赋值 支持 value = xxx 替换整个对象 不支持直接替换,需修改属性

样式处理

<style> 标签中,可以使用 CSS 变量或 Scoped 样式来管理组件外观。

  1. 编写 scoped 样式,确保样式隔离。
  2. 使用 v-bind 将 CSS 变量与 JavaScript 动态绑定。
<script setup>
const themeColor = ref('blue');
</script>

<template>
  <div class="box">彩色盒子</div>
  <button @click="themeColor = 'red'">变红</button>
</template>

<style scoped>
.box {
  /* 使用 v-bind 绑定 JS 变量 */
  background-color: v-bind('themeColor');
  padding: 20px;
  color: white;
}
</style>

通过以上步骤,你已经掌握了使用 Vue 3 单文件组件和组合式 API 构建完整功能组件的核心流程。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文