vue-23(创建用于逻辑提取的可重用组合组件)

创建用于逻辑提取的可重用组合组件

可重用的组合式是 Vue 组合式 API 的基石,它使你能够在多个组件中提取和重用有状态逻辑。这有助于编写更清晰的代码,减少冗余,并提高可维护性。通过将特定功能封装到组合式中,你可以轻松地共享和管理复杂的逻辑,使你的 Vue 应用更具可扩展性和组织性。本课程将深入探讨创建有效且可重用组合式的原则和技术。

理解组合式

从本质上讲,组合式是一个封装并返回可在多个组件中使用的有状态逻辑的函数。它利用组合式 API 的特性,如 refreactive 和生命周期钩子来管理状态和副作用。主要目标是将从组件中提取的复杂逻辑转化为可重用的单元,从而推广 DRY(不要重复自己)原则。

可重用的原则

要创建真正可重用的组合组件,请考虑这些原则:

  • 单一职责原则: 每个可组合项应专注于一个特定且明确定义的任务。避免创建处理多个不相关功能的"上帝"可组合项。
  • 配置选项: 允许组件通过选项或参数来配置可组合组件的行为。这使得可组合组件更能适应不同的使用场景。
  • 清晰的 API: 为可组合组件定义一个清晰简洁的 API,使其他开发者易于理解和使用。
  • 可测试性: 确保该组合件能够独立于其他部分轻松进行测试。这有助于保持其质量并防止回归问题。
  • 解耦: Composables 应与特定组件或应用逻辑解耦。它们应设计得尽可能通用。

基本示例:useMouse

让我们从一个简单的例子开始:一个跟踪鼠标位置的组合式组件。

// composables/useMouse.js
import { ref, onMounted, onUnmounted } from 'vue';export function useMouse() {const x = ref(0);const y = ref(0);function update(event) {x.value = event.pageX;y.value = event.pageY;}onMounted(() => {window.addEventListener('mousemove', update);});onUnmounted(() => {window.removeEventListener('mousemove', update);});return { x, y };
}

解释:

  • ref: 为 x 和 y 坐标创建响应式引用。
  • update: 一个根据鼠标事件更新 x 和 y 坐标的函数。
  • onMounted: 组件挂载时注册 mousemove 事件监听器。
  • onUnmounted: 组件卸载时移除事件监听器以防止内存泄漏。
  • return: 返回一个包含响应式 x 和 y 坐标的对象,可在组件模板中使用。

在组件中使用:

<template><p>Mouse position: x={{ x }}, y={{ y }}</p>
</template><script>
import { useMouse } from '../composables/useMouse';export default {setup() {const { x, y } = useMouse();return { x, y };}
};
</script>

高级组合式:逻辑提取

现在,让我们探索更复杂的场景,其中可组合组件可以显著提高代码的组织性和可重用性。

示例:useFetch

在 Web 应用程序中,从 API 获取数据是一项常见任务。让我们创建一个 useFetch 可组合组件来处理这个任务。

// composables/useFetch.js
import { ref, reactive, toRefs } from 'vue';export function useFetch(url) {const data = ref(null);const error = ref(null);const loading = ref(false);const state = reactive({data,error,loading})const fetchData = async () => {loading.value = true;try {const response = await fetch(url);if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}data.value = await response.json();} catch (err) {error.value = err;} finally {loading.value = false;}};fetchData(); // Immediately fetch data when the composable is usedreturn {...toRefs(state),fetchData // Expose the fetchData function to allow manual re-fetching};
}

解释:

  • data , error , loading :用于存储获取的数据、发生的任何错误以及加载状态的响应式引用。
  • fetchData: 一个异步函数,从给定 URL 获取数据,处理错误,并更新响应式引用。
  • toRefs: 将响应式对象 state 转换为 ref 对象,允许在组件中进行解构。
  • 当可组合函数被使用时,fetchData 函数会立即被调用,启动数据获取过程。
  • fetchData 函数也会被返回,允许组件在需要时手动触发重新获取数据。

在组件中使用:

<template><div v-if="loading">Loading...</div><div v-else-if="error">{{ error.message }}</div><div v-else><h1>{{ data.title }}</h1><p>{{ data.body }}</p><button @click="fetchData">Refresh</button></div>
</template><script>
import { useFetch } from '../composables/useFetch';export default {setup() {const { data, error, loading, fetchData } = useFetch('https://jsonplaceholder.typicode.com/posts/1');return { data, error, loading, fetchData };}
};
</script>

示例:useLocalStorage

另一个常见需求是在本地存储中持久化数据。让我们创建一个 useLocalStorage 组合式。

// composables/useLocalStorage.js
import { ref, watch, onMounted } from 'vue';export function useLocalStorage(key, defaultValue = null) {const storedValue = ref(defaultValue);onMounted(() => {// Initialize from localStorage on mountconst item = localStorage.getItem(key);if (item) {try {storedValue.value = JSON.parse(item);} catch (error) {console.error("Error parsing stored value:", error);// If parsing fails, leave it as default or handle as needed}}});watch(storedValue,(newValue) => {localStorage.setItem(key, JSON.stringify(newValue));},{ deep: true } // Watch for changes in nested objects/arrays);return storedValue;
}

解释:

  • storedValue: 一个反应式引用,用于存储本地存储中的值。
  • onMounted: 在组件挂载时从本地存储中获取值,并初始化 storedValue
  • watch: 监听 storedValue 的变化并相应地更新本地存储。deep: true 选项确保可以检测到嵌套对象或数组的更改。
  • 包含错误处理,以便在存储的值不是有效 JSON 的情况下优雅地处理。

在组件中使用:

<template><div><input v-model="name" placeholder="Enter your name"><p>Hello, {{ name }}!</p></div>
</template><script>
import { useLocalStorage } from '../composables/useLocalStorage';export default {setup() {const name = useLocalStorage('name', '');return { name };}
};
</script>

处理配置选项

为了让可组合项更加灵活,你可以将配置选项作为参数传递。例如,让我们修改 useFetch 可组合项,使其接受一个选项对象。

// composables/useFetch.js
import { ref, reactive, toRefs } from 'vue';export function useFetch(url, options = {}) {const data = ref(null);const error = ref(null);const loading = ref(false);const state = reactive({data,error,loading})const fetchData = async () => {loading.value = true;try {const response = await fetch(url, options); // Pass options to fetchif (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}data.value = await response.json();} catch (err) {error.value = err;} finally {loading.value = false;}};fetchData();return {...toRefs(state),fetchData};
}

在组件中使用:

<template><div v-if="loading">Loading...</div><div v-else-if="error">{{ error.message }}</div><div v-else><h1>{{ data.title }}</h1><p>{{ data.body }}</p></div>
</template><script>
import { useFetch } from '../composables/useFetch';export default {setup() {const options = {headers: {'Authorization': 'Bearer my-token'}};const { data, error, loading } = useFetch('https://jsonplaceholder.typicode.com/posts/1', options);return { data, error, loading };}
};
</script>

在这个示例中,useFetch 组合函数现在接受一个直接传递给 fetch 函数的 options 对象,允许你配置请求头、方法和其他请求参数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86528.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86528.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据透视表学习笔记

学习视频&#xff1a;Excel数据透视表大全&#xff0c;3小时从小白到大神&#xff01;_哔哩哔哩_bilibili 合并行标签 初始数据透视表 不显示分类汇总 以大纲形式显示 在组的底部显示所有分类汇总 以表格形式显示 合并单元格-右键-数据透视表选项 选中-合并并剧中排列带…

吃透 Golang 基础:测试

文章目录 go test测试函数随机测试测试一个命令白盒测试外部测试包 测试覆盖率基准测试剖析示例函数 go test go test命令是一个按照一定的约定和组织来测试代码的程序。在包目录内&#xff0c;所有以xxx_test.go为后缀名的源文件在执行go build时不会被构建为包的一部分&#…

酒店服务配置无门槛优惠券

1.查看酒店绑定的是那个仓库&#xff1b; 凯里亚德酒店(深圳北站壹城中心店)&#xff0c;绑定的是“龙华民治仓&#xff08;睿嘀购” 2.“门店列表”选择“龙华民治仓&#xff08;睿嘀购””中的“绑定场所” 3.通过酒店名字查找绑定的商品模板&#xff1b; 凯里亚德酒店(深圳…

IoT创新应用场景,赋能海外市场拓展

在数字化浪潮席卷全球的当下&#xff0c;物联网&#xff08;Internet of Things, IoT&#xff09;正以革命性的力量重塑产业生态。这项通过传感器、通信技术及智能算法实现设备互联的技术&#xff0c;不仅推动全球从“万物互联”迈向“万物智联”&#xff0c;更成为赋能企业开拓…

Idea中Docker打包流程记录

1. maven项目&#xff0c;先打package 2.添加Dockerfile 3.执行打包命令 注意最后的路径 . docker buildx build -t xxx-app:版本号 -f Dockerfile . 4.下载文件 docker save -o xxx-app-版本号.tar xxx-app:版本号 5.加载镜像 docker load -i xxx-app-版本号.tar 6.编…

硬件工程师笔试面试高频考点-电阻

目录 1.1 电阻选型时一般从哪几个方面进行考虑? 1.2上拉下拉电阻的作用 1.3 PTC热敏电阻作为电源电路保险丝的工作原理 1.4 如果阻抗不匹配&#xff0c;有哪些后果 1.5 电阻、电容和电感0402、0603和0805封装的含义 1.6 电阻、电容和电感的封装大小与什么参数有关 1.7 …

小程序入门:小程序 API 的三大分类

在小程序开发中&#xff0c;API&#xff08;Application Programming Interface&#xff09;起着至关重要的作用&#xff0c;它为开发者提供了丰富的功能和能力&#xff0c;使我们能够创建出功能强大、用户体验良好的小程序。小程序 API 大致可分为以下三大分类&#xff1a;事件…

算法第55天|冗余连接、冗余连接II

冗余连接 题目 思路与解法 #include <iostream> #include <vector> using namespace std; int n; // 节点数量 vector<int> father(1001, 0); // 按照节点大小范围定义数组// 并查集初始化 void init() {for (int i 0; i < n; i) {father[i] i;} } //…

Docker单独部署grafana

Docker单独部署grafana 环境说明 操作前提&#xff1a; 先去搭建PC端的MySQL和虚拟机 自行找参考 Linux部署docker参考文章&#xff1a; 02-Docker安装_docker安装包下载-CSDN博客 本文参考文章&#xff1a; 运维小记 说明&#xff1a; 本文的操作均以搭建好的PC端的MySQL和虚…

【数据分析,相关性分析】Matlab代码#数学建模#创新算法

【数据分析&#xff0c;相关性分析】118-matlab代码 #数学建模#创新算法 相关性分析及绘图 基于最大互信息系数的特征筛选 最大互信息系数 皮尔逊相关系数 spearman相关系数 kendall秩相关系数 请自带预算时间与需求以便高效沟通&#xff0c;回复超快&#xff0c;可以加急…

浅谈C++ 中泛型编程(模版编程)

C 是一种强大且灵活的编程语言&#xff0c;支持多种编程范式&#xff0c;使得开发者能够选择最适合特定问题的解决方案。在实际开发中&#xff0c;面向对象编程、泛型编程、函数式编程和元编程是最常用的几种范式。 今天主要与大家一起来介绍和学习泛型编程&#xff08;即模版…

iOS开发中的KVO以及原理

KVO概述 KVO(Key-Value-Observing)是iOS开发中一种观察者模式实现&#xff0c;允许对象监听另一个对象属性的变化。当被观察属性的值发生变化时&#xff0c;观察者会收到通知。KVO基于NSKeyValueObserving协议实现&#xff0c;是Foundation框架的核心功能之一。 1.KVO的基本使…

雷卯针对灵眸科技EASY Orin-nano RK3516 开发板防雷防静电方案

一、应用场景 1. 人脸检测 2. 人脸识别 3. 安全帽检测 4. 人员检测 5. OCR文字识别 6. 人头检测 7. 表情神态识别 8. 人体骨骼点识别 9. 火焰检测 10. 人脸姿态估计 11. 人手检测 12. 车辆检测 13. 二维码识别 二、 功能概述 1 CPU&#xff1a;八核64位ARM v8处…

中国双非高校经费TOP榜数据分析

当我们习惯性仰望985、211这些“国家队”时&#xff0c;一批地方重点支持的高校正悄悄发力&#xff0c;手握重金&#xff0c;展现出不逊于名校的“钞能力”。特别是“双非”大学中的佼佼者&#xff0c;它们的年度经费预算&#xff0c;足以让许多普通院校望尘莫及。 今天就带大…

C++ Lambda表达式详解:从入门到精通

Lambda表达式是C11引入的最重要特性之一&#xff0c;它彻底改变了我们在C中编写函数对象的方式。本文将带你全面掌握Lambda表达式的使用技巧&#xff01; 1. 什么是Lambda表达式&#xff1f; Lambda表达式是C11引入的一种匿名函数对象&#xff0c;它允许我们在需要函数的地方…

实体类id字段选择Integer还是Long?

Java实体类ID类型选择&#xff1a;Integer vs Long 深度解析与最佳实践 在Java实体类设计中&#xff0c;ID字段的类型选择看似简单&#xff0c;却直接影响系统扩展性、性能和数据一致性。本文将深入探讨Integer和Long两种主键类型的差异&#xff0c;并通过实际案例展示如何做出…

变现与自我提升:加法与乘法的智慧抉择

在当今这个快速发展的时代&#xff0c;无论是追求财富的变现&#xff0c;还是致力于个人能力的提升&#xff0c;我们都会面临一个关键问题&#xff1a;是分类分步地逐步实现&#xff0c;还是将多种要素混合在一起&#xff1f;是简单地做加法&#xff0c;还是复杂的乘法运算&…

鸿蒙 SideBarContainer 开发攻略:侧边栏交互设计与多端适配

一、引言&#xff1a;侧边栏布局的核心组件 在鸿蒙应用开发中&#xff0c;SideBarContainer 作为构建高效交互界面的核心组件&#xff0c;为开发者提供了灵活的侧边栏布局解决方案。该组件通过标准化的接口设计&#xff0c;实现了侧边栏与内容区的协同展示&#xff0c;适用于文…

Windows系统克隆硬盘后显示容量与实际容量严重不符如何处理?

在 Windows 系统中&#xff0c;克隆硬盘后出现硬盘显示容量与实际容量不符的问题&#xff0c;通常与分区布局、文件系统未正确调整或克隆工具设置有关。以下是可能的原因及对应的处理方案。 1. 问题原因分析 1.1 分区未正确调整 现象&#xff1a; 克隆后硬盘的总容量未正确显…

EXCEL数据报表

客单价成交金额*成交客户数 —— 提取年份 YEAR() 视图-窗口-新建窗口&#xff0c;就能将excel的一个子表格单拎出来成为独立窗口&#xff0c;方便对比查看 数据报表的单元格尽量都用公式来填补&#xff0c;链接到源表上去。这样当源表有新数据更新进来后&#xff0c;报表也…