Loading

Vue 3 页面常见结构、生命周期与核心用法

Vue 3 页面结构、核心语法与生命周期

一、.vue 文件整体结构

Vue 3 页面通常使用 .vue 单文件组件。

一个 .vue 文件主要由三部分组成:

  1. <template>
  2. <!-- 页面结构 -->
  3. </template>
  4. <script setup lang="ts">
  5. // 页面逻辑
  6. </script>
  7. <style scoped>
  8. /* 页面样式 */
  9. </style>

二、<template>:页面结构

template 相当于 HTML 页面结构。

例如:

  1. <template>
  2. <div class="user-page">
  3. <h1>{{ username }}</h1>
  4. <button @click="handleSave">
  5. 保存
  6. </button>
  7. </div>
  8. </template>

这里主要负责:

  1. 展示页面
  2. 显示数据
  3. 绑定属性
  4. 绑定事件
  5. 条件显示
  6. 循环列表

例如:

显示变量

  1. <div>{{ username }}</div>

绑定属性

  1. <button :disabled="loading">
  2. 保存
  3. </button>

绑定点击事件

  1. <button @click="handleSave">
  2. 保存
  3. </button>

条件显示

  1. <div v-if="loading">
  2. 加载中
  3. </div>

循环

  1. <div
  2. v-for="item in list"
  3. :key="item.id"
  4. >
  5. {{ item.name }}
  6. </div>

三、<script setup>:页面逻辑区

Vue 3 项目现在通常使用:

  1. <script setup lang="ts">
  2. </script>

这里是整个页面的逻辑核心。

通常会放这些内容:

  1. <script setup>
  2. 1. import
  3. ↓
  4. 2. 响应式数据
  5. ↓
  6. 3. computed 计算属性
  7. ↓
  8. 4. 普通业务方法
  9. ↓
  10. 5. watch 数据监听
  11. ↓
  12. 6. 生命周期

一个典型结构:

  1. <script setup lang="ts">
  2. import {
  3. computed,
  4. onBeforeUnmount,
  5. onMounted,
  6. ref,
  7. watch
  8. } from 'vue'
  9. // 1. 响应式数据
  10. const loading = ref(false)
  11. const username = ref('')
  12. // 2. 计算属性
  13. const displayName = computed(() => {
  14. return username.value || '未登录'
  15. })
  16. // 3. 普通方法
  17. function loadData(): void {
  18. console.log('加载数据')
  19. }
  20. // 4. 数据监听
  21. watch(username, () => {
  22. console.log('username 改变')
  23. })
  24. // 5. 生命周期
  25. onMounted(() => {
  26. loadData()
  27. })
  28. onBeforeUnmount(() => {
  29. console.log('组件准备销毁')
  30. })
  31. </script>

后面的 ref、computed、watch、onMounted,其实全部都是围绕这个 <script setup> 逻辑区展开的。


四、import:引入需要使用的功能

Vue 不会自动提供所有功能。

需要什么,就从 Vue 中引入什么。

例如:

  1. import {
  2. computed,
  3. nextTick,
  4. onBeforeUnmount,
  5. onMounted,
  6. ref,
  7. watch
  8. } from 'vue'

分别表示:

  1. ref
  2. → 响应式数据
  3. computed
  4. → 计算属性
  5. watch
  6. → 监听数据变化
  7. nextTick
  8. → 等待 DOM 更新
  9. onMounted
  10. → 生命周期
  11. onBeforeUnmount
  12. → 生命周期

除了 Vue 本身,还可以引入其他模块:

  1. import { useRoute } from 'vue-router'
  2. import { ElMessage } from 'element-plus'

五、响应式数据:页面的数据从哪里来

Vue 页面通常需要保存一些状态。

例如:

  1. 用户名
  2. 加载状态
  3. 列表
  4. 当前任务
  5. 当前页码
  6. 弹窗是否打开

这些数据通常使用:

  1. ref()
  2. reactive()

来定义。


1. ref():最常用的响应式数据

例如:

  1. const loading = ref(false)
  2. const username = ref('')
  3. const count = ref(0)

表示创建三个响应式变量。

修改:

  1. loading.value = true
  2. username.value = '张三'
  3. count.value++

在 TypeScript 中需要:

  1. .value

但是在 template 中:

  1. <div>{{ username }}</div>

不需要:

  1. {{ username.value }}

Vue 会自动处理。

整个过程:

  1. const username = ref('')
  2. ↓
  3. 创建响应式变量
  4. ↓
  5. username.value = '张三'
  6. ↓
  7. Vue 发现数据变化
  8. ↓
  9. 自动更新 template

2. reactive():响应式对象

例如:

  1. const userInfo = reactive({
  2. name: '',
  3. age: 0,
  4. phone: ''
  5. })

修改时:

  1. userInfo.name = '张三'
  2. userInfo.age = 30

不需要 .value。

简单记:

  1. ref
  2. → 单个变量最常见
  3. reactive
  4. → 一整个对象

六、普通函数:页面业务逻辑

定义好数据以后,页面通常需要执行各种业务逻辑。

例如:

  1. 加载数据
  2. 保存
  3. 删除
  4. 提交表单
  5. 打开页面
  6. 关闭窗口
  7. 刷新列表

Vue 3 <script setup> 中直接写普通函数:

  1. function loadData(): void {
  2. console.log('加载数据')
  3. }
  4. function handleSave(): void {
  5. console.log('保存数据')
  6. }

template 可以直接调用:

  1. <button @click="handleSave">
  2. 保存
  3. </button>

执行关系:

  1. 用户点击按钮
  2. ↓
  3. @click
  4. ↓
  5. handleSave()
  6. ↓
  7. 执行 TypeScript 逻辑

Vue 2 经常看到:

  1. methods: {
  2. }

Vue 3 <script setup> 一般不需要这样写。

直接:

  1. function handleSave() {
  2. }

即可。


七、computed():根据已有数据计算新数据

有时候我们并不需要保存一个新的状态。

而是根据现有数据计算出来。

例如:

  1. const firstName = ref('龙')
  2. const lastName = ref('志煜')
  3. const fullName = computed(() => {
  4. return firstName.value + lastName.value
  5. })

这里:

  1. firstName
  2. lastName

是原始数据。

而:

  1. fullName

是计算出来的数据。

执行关系:

  1. firstName / lastName
  2. ↓
  3. computed
  4. ↓
  5. fullName

当:

  1. firstName.value = '陈'

发生变化时:

  1. computed 自动重新计算

不需要自己手动更新 fullName。


常见场景

例如按钮是否可以操作:

  1. const canStart = computed(() => {
  2. return snapshot.value.status === 'idle'
  3. })

例如从路由获取 ID:

  1. const automationId = computed(() => {
  2. return String(route.params.automationId)
  3. })

简单理解:

  1. computed
  2. =
  3. 根据现有数据
  4. 自动计算另一个结果

八、watch():监听数据变化后执行操作

watch() 和 computed() 很容易混淆。

watch() 的作用不是计算数据。

而是:

  1. 某个数据变化
  2. ↓
  3. 我要执行一段代码

例如:

  1. const username = ref('')
  2. watch(username, (newValue, oldValue) => {
  3. console.log('旧值:', oldValue)
  4. console.log('新值:', newValue)
  5. })

当:

  1. username.value = '张三'

执行:

  1. username 发生变化
  2. ↓
  3. watch 被触发
  4. ↓
  5. 执行回调函数

常见用途

例如:

  1. 路由 ID 变化
  2. ↓
  3. 重新加载数据

代码:

  1. watch(automationId, (newId) => {
  2. loadAutomation(newId)
  3. })

或者:

  1. 搜索关键词变化
  2. ↓
  3. 重新搜索

computed 和 watch 的区别

这是重点。

  1. computed
  2. ↓
  3. 我要得到一个新的“值”

例如:

  1. 价格 × 数量
  2. ↓
  3. 总价

而:

  1. watch
  2. ↓
  3. 某个值变化以后
  4. 我要“做一件事”

例如:

  1. automationId 改变
  2. ↓
  3. 重新调用接口

所以:

  1. computed = 算东西
  2. watch = 监听变化做事情

九、Vue 生命周期是什么

前面的:

  1. ref
  2. computed
  3. watch
  4. function

都是页面运行过程中的功能。

而生命周期描述的是:

一个 Vue 组件从创建,到显示,再到最终销毁的整个过程。

可以理解成:

  1. 组件开始创建
  2. ↓
  3. 组件挂载到页面
  4. ↓
  5. 用户正在使用
  6. ↓
  7. 数据不断变化
  8. ↓
  9. 组件离开页面
  10. ↓
  11. 组件被销毁

Vue 在这些关键阶段提供了一些生命周期方法。


十、onMounted():组件挂载完成

最常见生命周期之一。

  1. onMounted(() => {
  2. loadData()
  3. })

意思是:

  1. Vue 组件已经挂到页面
  2. ↓
  3. 执行这里的代码

常用于:

  1. 加载初始化数据
  2. 注册事件监听
  3. 创建 ResizeObserver
  4. 初始化第三方组件
  5. 获取 DOM
  6. 启动定时器

例如:

  1. onMounted(() => {
  2. window.addEventListener('resize', handleResize)
  3. })

十一、onBeforeUnmount():组件销毁前

组件准备被销毁之前执行。

例如:

  1. onBeforeUnmount(() => {
  2. window.removeEventListener('resize', handleResize)
  3. })

主要用途就是:

  1. 清理之前创建的资源

例如:

  1. removeEventListener
  2. clearInterval
  3. clearTimeout
  4. ResizeObserver.disconnect()
  5. 移除 IPC listener
  6. 关闭 WebSocket

最经典的组合:

  1. onMounted(() => {
  2. window.addEventListener('resize', handleResize)
  3. })
  4. onBeforeUnmount(() => {
  5. window.removeEventListener('resize', handleResize)
  6. })

可以直接记:

  1. onMounted
  2. ↓
  3. 创建
  4. onBeforeUnmount
  5. ↓
  6. 清理

十二、其他 Vue 生命周期

Vue 3 常见生命周期:

  1. 组件准备挂载
  2. ↓
  3. onBeforeMount
  4. ↓
  5. 组件挂载完成
  6. ↓
  7. onMounted
  8. ↓
  9. 组件正常使用
  10. 数据变化
  11. ↓
  12. onBeforeUpdate
  13. ↓
  14. DOM 更新
  15. ↓
  16. onUpdated
  17. ↓
  18. 组件准备销毁
  19. ↓
  20. onBeforeUnmount
  21. ↓
  22. 组件已经销毁
  23. ↓
  24. onUnmounted

对应:

生命周期 含义
onBeforeMount 挂载 DOM 前
onMounted DOM 挂载完成
onBeforeUpdate DOM 更新前
onUpdated DOM 更新完成
onBeforeUnmount 组件销毁前
onUnmounted 组件已经销毁

实际项目最常见的是:

  1. onMounted
  2. onBeforeUnmount

十三、nextTick():等待 Vue 更新 DOM

Vue 修改数据以后,不一定马上同步修改 DOM。

例如:

  1. loading.value = false

这时候 Vue 会安排 DOM 更新。

如果你需要:

  1. 修改数据
  2. ↓
  3. 等页面真的更新完
  4. ↓
  5. 再操作 DOM

就使用:

  1. await nextTick()

例如:

  1. message.value = '加载完成'
  2. await nextTick()
  3. console.log('页面已经更新完成')

常见场景:

  1. 修改列表后滚动到底部
  2. 打开弹窗后获取弹窗尺寸
  3. 元素显示后执行 focus
  4. 布局变化后重新计算位置

十四、template 和 script setup 是怎么连接起来的

现在把前面的东西连起来。

例如:

  1. <script setup lang="ts">
  2. import { computed, ref } from 'vue'
  3. const count = ref(0)
  4. const doubleCount = computed(() => {
  5. return count.value * 2
  6. })
  7. function add(): void {
  8. count.value++
  9. }
  10. </script>
  11. <template>
  12. <div>
  13. <div>数量:{{ count }}</div>
  14. <div>双倍:{{ doubleCount }}</div>
  15. <button @click="add">
  16. +1
  17. </button>
  18. </div>
  19. </template>

执行过程:

  1. <script setup>
  2. 创建 count
  3. ↓
  4. 创建 doubleCount
  5. ↓
  6. 创建 add()
  7. ↓
  8. template 开始显示
  9. ↓
  10. 用户点击按钮
  11. ↓
  12. @click="add"
  13. ↓
  14. add()
  15. ↓
  16. count.value++
  17. ↓
  18. count 改变
  19. ↓
  20. computed 自动重新计算 doubleCount
  21. ↓
  22. Vue 自动更新 template

这就是 Vue 最核心的数据驱动思想:

  1. 修改数据
  2. 而不是
  3. 手动修改 HTML

十五、Vue Router:页面路由

Vue 项目通常还会看到:

  1. import {
  2. useRoute,
  3. useRouter
  4. } from 'vue-router'

它们不是 Vue 生命周期。

而是路由功能。


useRoute()

用于:

  1. 读取当前页面路由信息

例如:

  1. const route = useRoute()
  2. const automationId = computed(() => {
  3. return String(route.params.automationId)
  4. })

假设地址:

  1. /workspace/1001

那么可能得到:

  1. automationId = 1001

useRouter()

用于主动跳转页面:

  1. const router = useRouter()
  2. router.push('/admin')

简单记:

  1. route
  2. → 当前在哪
  3. router
  4. → 我要去哪

十六、父子组件通信

Vue 页面往往不是一个巨大文件。

而是:

  1. 页面
  2. ↓
  3. 拆成多个组件

例如:

  1. WorkspacePage.vue
  2. ├── Toolbar.vue
  3. ├── BrowserPanel.vue
  4. └── LogPanel.vue

组件之间需要传递数据。


defineProps():父传子

子组件:

  1. const props = defineProps<{
  2. title: string
  3. count: number
  4. }>()

父组件:

  1. <UserCard
  2. title="用户信息"
  3. :count="10"
  4. />

执行关系:

  1. 父组件
  2. ↓
  3. props
  4. ↓
  5. 子组件

defineEmits():子通知父

子组件:

  1. const emit = defineEmits<{
  2. save: [id: string]
  3. }>()
  4. function handleSave(): void {
  5. emit('save', '1001')
  6. }

父组件:

  1. <UserCard @save="handleSave" />

执行关系:

  1. 子组件
  2. ↓
  3. emit
  4. ↓
  5. 父组件

所以:

  1. 父 → 子
  2. props
  3. 子 → 父
  4. emit

十七、一个完整 Vue 3 页面怎么看

以后看到:

  1. <script setup lang="ts">
  2. import {
  3. computed,
  4. nextTick,
  5. onBeforeUnmount,
  6. onMounted,
  7. ref,
  8. watch
  9. } from 'vue'
  10. import { useRoute } from 'vue-router'

不要把它们看成一堆陌生方法。

应该分类看:

  1. Vue 页面
  2. │
  3. ├── 数据
  4. │ └── ref
  5. │
  6. ├── 数据计算
  7. │ └── computed
  8. │
  9. ├── 数据监听
  10. │ └── watch
  11. │
  12. ├── DOM 更新辅助
  13. │ └── nextTick
  14. │
  15. ├── 生命周期
  16. │ ├── onMounted
  17. │ └── onBeforeUnmount
  18. │
  19. └── 路由
  20. └── useRoute

十八、典型页面执行流程

一个普通 Vue 3 页面,可以理解成:

  1. 打开页面
  2. ↓
  3. 执行 <script setup>
  4. ↓
  5. 创建 ref 数据
  6. ↓
  7. 创建 computed
  8. ↓
  9. 注册 watch
  10. ↓
  11. 定义 function
  12. ↓
  13. 注册生命周期
  14. ↓
  15. 渲染 template
  16. ↓
  17. DOM 挂载完成
  18. ↓
  19. onMounted()
  20. ↓
  21. 页面正常运行
  22. │
  23. ├── 用户点击
  24. │ ↓
  25. │ function
  26. │
  27. ├── ref 数据变化
  28. │ ↓
  29. │ Vue 自动更新页面
  30. │
  31. ├── computed 依赖变化
  32. │ ↓
  33. │ 自动重新计算
  34. │
  35. └── watch 监听的数据变化
  36. ↓
  37. 执行 watch 回调
  38. 用户离开组件
  39. ↓
  40. onBeforeUnmount()
  41. ↓
  42. 清理资源
  43. ↓
  44. 组件销毁

十九、最核心的几个概念

刚开始看 Vue 3,先掌握下面这些就够了:

  1. template
  2. → 页面结构
  3. script setup
  4. → 页面逻辑
  5. ref
  6. → 保存响应式数据
  7. function
  8. → 执行业务逻辑
  9. computed
  10. → 根据已有数据计算新数据
  11. watch
  12. → 监听数据变化然后做事情
  13. onMounted
  14. → 组件挂载完成后执行
  15. onBeforeUnmount
  16. → 组件销毁前清理资源
  17. nextTick
  18. → 等待 DOM 更新完成

最终关系:

  1. .vue
  2. │
  3. ├── template
  4. │ ↓
  5. │ 展示数据、触发事件
  6. │
  7. ├── script setup
  8. │ │
  9. │ ├── ref
  10. │ │ └── 页面数据
  11. │ │
  12. │ ├── computed
  13. │ │ └── 计算数据
  14. │ │
  15. │ ├── function
  16. │ │ └── 业务逻辑
  17. │ │
  18. │ ├── watch
  19. │ │ └── 监听变化
  20. │ │
  21. │ └── lifecycle
  22. │ ├── onMounted
  23. │ └── onBeforeUnmount
  24. │
  25. └── style
  26. ↓
  27. 页面样式

理解这张关系图以后,再去看 Vue 3 页面代码,就不会觉得 ref、computed、watch、onMounted 是突然冒出来的一堆函数了。

posted @ 2026-09-22 13:07  LungGiyo  阅读(10)  评论(0)    收藏  举报