当前位置: 首页 > news >正文

【Vue】——生命周期、ref属性、hooks

Vue 与 TypeScript 核心开发指南:从 Ref 到生命周期与 Hooks

在现代 Vue 开发中,尤其是 Vue 3,TypeScript 的引入极大地提升了代码的健壮性、可维护性和开发体验。本文将系统性地梳理几个至关重要的核心概念,帮助您构建更强大的 Vue 应用。

一、标签的 ref 属性

ref 用于获取对模板中 DOM 元素或子组件实例的直接引用。

  • Vue 2 (Options API): 在模板中定义 ref,然后通过 this.$refs 对象访问。
    <template><input ref="usernameInput" type="text"><MyComponent ref="childComponent" /></template><script>export default {mounted() {// 访问 DOM 元素this.$refs.usernameInput.focus();// 访问子组件实例this.$refs.childComponent.someMethod();}}</script>
  • Vue 3 (Composition API): 使用 ref 函数(注意与 ref 属性同名)创建一个响应式引用,并通过同名变量访问。
    <template><input ref="usernameInput" type="text"><MyComponent ref="childComponentRef" /></template><script setup lang="ts">import { ref, onMounted } from 'vue';import MyComponent from './MyComponent.vue';// 创建一个 ref 来持有引用,初始值为 null// 必须使用泛型或类型断言来指定引用类型,否则 TS 无法推断const usernameInput = ref<HTMLInputElement | null>(null);const childComponentRef = ref<InstanceType<typeof MyComponent> | null>(null);onMounted(() => {// 访问 DOM 元素usernameInput.value?.focus();// 访问子组件实例childComponentRef.value?.someMethod();});</script>

**要点:** 在 Vue 3 的 `<script setup>` 中,模板 `ref` 的变量名必须与之声明时的变量名完全一致,才能实现自动绑定。

怎么避免其它vue文件与app.vue唯一标签(例如id)重复

如果id重复会优先一app.vue为主

使用ref作为标签

这样你点谁就会显示谁,就自动隔离开了

2、局部标签

data-v-......:局部样式 通过scope定义

基本上都会加上这个标签,这样其它.vue文件就引用不到本文件的样式了

3.组件标签和html标签:

把ref加到组件标签上,打印他就会返回这个组件的实例对象,但是数据受到了保护,看不到他的数据。

通过defineexpose,再交出去defineExpose(..)就能在导入的组件文件中看到这个实例化对象

小结:

二、回顾 TS 中的接口、泛型与自定义类型

在 Vue + TS 开发中,清晰的定义类型是类型安全的基础。

  1. 接口 (Interface): 定义对象的形状,主要用于定义 Props、响应式数据、发射事件 的结构。

export:抛出

import:引入

@是跟文件路径

自定义类型

    // 定义一个用户对象的结构interface User {id: number;name: string;email?: string; // 可选属性}// 用于 Propsinterface Props {user: User;isVisible: boolean;}// 用于响应式数据const userData = reactive<User>({ id: 1, name: 'Alice' });
  1. 泛型 (Generics): 提高代码的复用性和类型安全性。Vue 的许多函数都是泛型函数。
    import { ref, computed } from 'vue';// 用泛型指定 ref 的内部值类型const count = ref<number>(0);// 用泛型指定 computed 的返回类型const doubleCount = computed<number>(() => count.value * 2);// 自定义泛型函数function identity<T>(arg: T): T {return arg;}const result = identity<string>("hello"); // result 的类型为 string
  1. 自定义类型 (Type Aliases): 与接口类似,常用于定义联合类型、元组等。
    // 联合类型type Status = 'idle' | 'loading' | 'success' | 'error';// 定义 Props 的另一种方式type Props = {user: User;status: Status;};// 工具类型:从已有类型中派生出新类型type UserProfile = Pick<User, 'id' | 'name'>; // 只包含 id 和 nametype UserWithoutId = Omit<User, 'id'>; // 排除 id

reactive可以直接传泛型

加?是可选参数

三、props 的使用

Props 是父组件向子组件传递数据的方式。结合 TS 后,可以进行静态类型检查。

  • Vue 3 + <script setup> + TS (推荐): 使用 defineProps 宏,编译器会自动推导类型。

接收自定义对象用:

第二个测试:

3、接收数据最好不要只接收

要限制类型

4、withdefaults设置默认值

?限制必要性

    <!-- ChildComponent.vue --><script setup lang="ts">// 基于类型声明interface Props {title: string;count?: number;user: { id: number; name: string };}const props = defineProps<Props>(); // 无需导入 defineProps// 或者使用运行时声明,但类型支持较弱// const props = defineProps({ title: String, count: { type: Number, default: 0 } });</script><template><h1>{{ title }}</h1><p>{{ user.name }}</p></template>

**默认值:** 使用 `withDefaults` 编译器宏。

宏函数(withDefaults、defineexpose)不用import

    interface Props { count?: number; }const props = withDefaults(defineProps<Props>(), { count: 0 });
  • Vue 2 / 不使用 <script setup>:
    import { PropType } from 'vue';export default {props: {title: String,count: { type: Number, default: 0 },user: { type: Object as PropType<{ id: number; name: string }>, required: true }}}

四、对生命周期的理解

生命周期钩子函数是 Vue 组件在创建、更新、销毁过程中的关键时间点调用的函数。开发者可以在这些节点注入自定义代码,以执行初始化、副作用清理、性能优化等操作。理解它们的调用时机和顺序是构建正确、高效 Vue 应用的关键。

五、Vue 2 的生命周期

Vue 2 的生命周期基于 Options API,主要钩子如下):

小知识:{  挂载对应卸载(销毁)}

beforeCreate -> created -> beforeMount -> mounted -> beforeUpdate -> updated -> beforeDestroy -> destroyed

代码示例

debugger:停止生命周期           

创建、挂载、销毁只会执行一次,更新可以执行多次

v-if="isshow"或者v-show(show是不展示数据。if是没有数据),点击quick edit销毁

拓展

1.运行方式

无论是vue2还是3或者是react查看运行方式可以去看package.json的scripts

2、关闭语法检查加上黄色的字

  • beforeCreate: 实例初始化后,数据观测和 event/watcher 配置之前。
  • created: 实例创建完成。数据观测、计算属性、方法已配置,但 DOM 未挂载。常用于异步获取初始数据。
  • beforeMount: 挂载开始之前被调用,相关的 render 函数首次被调用。
  • mounted: 实例被挂载到 DOM 后调用。可以安全地操作 DOM 或访问 $refs
  • beforeUpdate: 数据更新时,虚拟 DOM 重新渲染和打补丁之前调用。
  • updated: 数据更改导致的虚拟 DOM 重新渲染和打补丁之后调用。避免在此钩子中更改状态,可能导致无限更新。
  • beforeDestroy / destroyed: 实例销毁前后调用。用于清理定时器、取消事件监听、取消网络请求等副作用。

六、Vue 3 的生命周期

Vue 3 的生命周期与 Vue 2 类似,但为了与 Composition API 保持一致,名称有所变化(加上on,并且驼峰命名),并引入了 setup 函数作为所有组合式 API 的入口。

  • Options API (Vue 3): 钩子名前面的 beforeDestroy 和 destroyed 改为 beforeUnmount 和 unmounted,行为更语义化。其他钩子名保持不变。
  • Composition API (在 setup 中): 通过导入 onX 函数来注册生命周期钩子。
    <script setup lang="ts">import { onMounted, onUpdated, onUnmounted } from 'vue';onMounted(() => {console.log('组件已挂载!');});onUpdated(() => {console.log('组件已更新!');});onUnmounted(() => {console.log('组件已卸载!清理工作在此进行。');});</script>
**Composition API 生命周期钩子映射:**
*   `beforeCreate` -> `setup()` 本身
*   `created` -> `setup()` 本身
*   `beforeMount` -> `onBeforeMount`
*   `mounted` -> `onMounted`
*   `beforeUpdate` -> `onBeforeUpdate`
*   `updated` -> `onUpdated`
*   `beforeUnmount` -> `onBeforeUnmount`
*   `unmounted` -> `onUnmounted`

二、每一个组件都有自己的生命周期,哪父与子的生命周期顺序是怎样的?

子挂载

父挂载

结果:子先执行,父(app.vue)在最后执行,因为程序是从上往下执行的

小结:

七、自定义 Hooks

小知识:export default 后面只能跟值

跟函数不能起名


自定义 Hooks 是 Vue 3 Composition API 的精髓。它不是一个内置 API,而是一种利用 Vue 的组合式函数来抽取和重用状态逻辑的模式。

核心思想: 将可复用的业务逻辑(包括状态、计算属性、方法、生命周期钩子)封装到一个独立的函数中,该函数返回需要在组件中使用的数据和方法。

示例:封装一个获取鼠标位置的自定义 Hook

// hooks/useMouse.ts
import { ref, onMounted, onUnmounted } from 'vue';export function useMouse() {const x = ref(0);const y = ref(0);function update(event: MouseEvent) {x.value = event.pageX;y.value = event.pageY;}onMounted(() => window.addEventListener('mousemove', update));onUnmounted(() => window.removeEventListener('mousemove', update));// 返回响应式数据,供组件使用return { x, y };
}

在组件中使用:

<!-- MyComponent.vue -->
<script setup lang="ts">
import { useMouse } from './hooks/useMouse';const { x, y } = useMouse();
</script><template><p>Mouse position is at: {{ x }}, {{ y }}</p>
</template>

优势:

  1. 逻辑复用: 彻底解决了 Vue 2 Mixins 带来的命名冲突和来源不清晰的问题。
  2. 代码组织: 将复杂的组件逻辑按功能点拆分到不同的 Hooks 中,代码更清晰、更易维护。
  3. 类型推导: 完全支持 TypeScript,提供完美的类型推导。

案例

一、环境准备

1、通过这个网址可以随机得到一张狗图片

2、下载axios

3、代码

css

script

template

使用await命令,将异步结果等待返回之后再执行后面的代码


使用hooks修改

1.创建一个hooks文件夹,再创建对应的ts文件

2,把对应的部分剪切到一个函数中,记得要return需要的数据(可以是对象,基本类型,数据等等)

在hooks中也可以使用其它函数如(构造函数,计算属性)

hooks正凸显了组合式api

总结

概念核心要点Vue 3 最佳实践
ref获取 DOM/组件引用,Vue 3 需结合泛型定义类型const el = ref<HTMLInputElement | null>(null)
TS 类型使用 interface 定义结构,泛型 增强函数灵活性用 interface 定义 Props 和复杂对象
props父传子的数据流,TS 强化类型安全<script setup> 中使用 defineProps<MyProps>()
生命周期组件生命周期的关键节点,用于执行特定任务Composition API 使用 onMountedonUnmounted 等
自定义 Hooks逻辑复用的终极方案,替代 Mixins封装 useXxx 函数,返回响应式数据和方法

掌握这些核心概念,意味着您已经能够利用 Vue 3 和 TypeScript 构建类型安全、逻辑清晰且易于维护的大型应用了。实践是掌握它们的最佳方式,请务必在项目中尝试使用它们。

http://www.dtcms.com/a/461839.html

相关文章:

  • 网站服务器如何维护小米商城wordpress主题
  • 寻梦数据空间 | 架构篇:从概念到落地的技术实践与突破性创新
  • PySide6 文本编辑器(QPlainTextEdit)实现查找对话功能(匹配完整单词,区分大小写)——重构版本
  • golang面经——GMP相关
  • 谷歌英文网站简单的网站php开发教程
  • 免费一键自助建站官网域名及对应网站
  • AI编程Cursor最强竞争对手来了,CodeX三种操作系统喂饭级安装教程!
  • Spring Cloud Alibaba 最新五大核心组件
  • 融乐Mini1.9.3 | 支持在线播放,本地播放,内置两条线路,免费畅听全网音乐
  • 车行网站源码微信公众平台营销
  • 客户端加密 和 服务端加密:端到端安全的真正含义
  • 88-python电网可视化项目-8-1
  • 做网站要自己租服务器吗wordpress打开速度优化
  • 要看网站是多少建设一个网站需要哪些费用
  • 物联网时代下无锡漫途科技无线多参数遥测终端助力饮水安全监测
  • 公司网站建设款计什么科目wordpress jquery版本
  • 麒麟系统如何设置.sh文件的图标
  • 3D GPR切片图
  • 深圳建设网站制作公司怎样制作一个网页
  • 腾讯云手机适用于哪些人群
  • 云南技术网站建设销售编程代码入门教学
  • 【PalladiumZ2 使用专栏 5 -- 模拟电路是否可以仿真?】
  • 公司网站文化活动备案上海企业建站方案
  • AI智能体开发实战(开源版)
  • 手动添加 SSH 私钥到 ssh-agent 以解决Permission denied (publickey) 错误
  • 用网站建设费用wordpress网站后台
  • 大模型前世今生(八):大模型的预训练
  • Tiff编码解码器封装
  • Android 性能优化 — Profiler 使用指南
  • DynamoDB 到 Redshift Zero-ETL 集成:完整实施指南