如何学习Vue设计模式

embedded/2025/1/11 6:01:16/

如何学习Vue设计模式

Vue 设计模式是 Vue.js 框架中用于解决常见问题的可复用解决方案。这些模式帮助开发者更有效地组织和管理代码,提升代码的可维护性、可扩展性和可读性。以下是一些常见的 Vue 设计模式

1. 数据存储模式

可组合函数:用于创建可共享的数据存储,包含全局状态、单例导出部分或全部状态用于访问和修改状态的方法

<script setup lang="ts">
import { reactive, toRefs, readonly } from 'vue';
import { themes } from './utils';// 1. 在模块作用域中创建全局状态,在每次使用此可组合函数时共享
const state = reactive({darkMode: false,sidebarCollapsed: false,// 2. 此主题值对该可组合函数保持私有theme: 'nord',
});export default () => {// 2. 仅暴露部分状态// 使用 toRefs 允许我们共享单个值const { darkMode, sidebarCollapsed } = toRefs(state);// 3. 修改我们的基础状态const changeTheme = (newTheme) => {if (themes.includes(newTheme)) {// 仅在它是一个有效主题时更新state.theme = newTheme;}};return {// 2. 只返回部分状态darkMode,sidebarCollapsed,// 2. 仅暴露状态的只读版本theme: readonly(state.theme),// 3. 我们返回一个修改基础状态的方法changeTheme,};
};
</script>

2. 轻量级可组合函数

将反应式管理与核心业务逻辑分离,使用纯 JavaScript 或 TypeScript 实现业务逻辑,并在其上添加一层轻量级的反应式。

<script setup lang="ts">import { ref, watch } from 'vue';import { convertToFahrenheit } from './temperatureConversion';export function useTemperatureConverter(celsiusRef: Ref<number>) {const fahrenheit = ref(0);watch(celsiusRef, (newCelsius) => {// 实际逻辑包含在一个纯函数中fahrenheit.value = convertToFahrenheit(newCelsius);});return { fahrenheit };}
</script>

3. 谦逊组件模式

谦逊组件的设计理念是简单,专注于展示和用户输入,将业务逻辑放在其他地方,遵循“属性向下,事件向上”的原则,确保数据流清晰、可预测,使其易于重用、测试和维护。

<template><div class="max-w-sm rounded overflow-hidden shadow-lg"><img class="w-full" :src="userData.image" alt="User Image" /><div class="px-6 py-4"><div class="font-bold text-xl mb-2">{{ userData.name }}</div><p class="text-gray-700 text-base">{{ userData.bio }}</p></div><div class="px-6 pt-4 pb-2"><button@click="emitEditProfile"class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Edit Profile</button></div></div>
</template><script setup>
defineProps({userData: Object,
});const emitEditProfile = () => {emit('edit-profile');
};
</script>

4. 提取条件逻辑

为了简化包含多个条件分支的模板,我们将每个分支的内容提取到单独的组件中。这可以提高代码的可读性和可维护性。

<!-- 之前 --><template><div v-if="condition"><!-- 真实条件下的大量代码 --></div><div v-else><!-- 假设条件下的大量代码 --></div>
</template><!-- 之后 --><template><TrueConditionComponent v-if="condition" /><FalseConditionComponent v-else />
</template>

5. 提取可组合函数

将逻辑提取到可组合函数中,即使是单次使用的场景也是如此。可组合函数可以简化组件,使其更容易理解和维护。

它们还有助于添加相关方法和状态,例如撤销和重做功能。这有助于我们将逻辑与 UI 分开。

<script setup lang="ts">
import { ref, watch } from 'vue';export function useExampleLogic(initialValue: number) {const count = ref(initialValue);const increment = () => {count.value++;};const decrement = () => {count.value--;};watch(count, (newValue, oldValue) => {console.log(`Count changed from ${oldValue} to ${newValue}`);});return { count, increment, decrement };
}
</script>

<template><div class="flex flex-col items-center justify-center"><button@click="decrement"class="bg-blue-500 text-white p-2 rounded">Decrement</button><p class="text-lg my-4">Count: {{ count }}</p><button@click="increment"class="bg-green-500 text-white p-2 rounded">Increment</button></div>
</template><script setup lang="ts">
import { useExampleLogic } from './useExampleLogic';const { count, increment, decrement } = useExampleLogic(0);
</script>

6. 列表组件模式

组件中的大型列表会导致模板混乱和难以管理。解决方案是将 v-for 循环逻辑抽象到一个子组件中。

这可以简化父组件,并将迭代逻辑封装在专门的列表组件中,保持整洁。

<!-- 之前:在父组件中直接使用 v-for --><template><div v-for="item in list" :key="item.id"><!-- 每个项目的代码 --></div>
</template><!-- 之后:将 v-for 抽象到子组件中 --><template><NewComponentList :list="list" />
</template>

7. 保留对象模式

将整个对象传递给组件,而不是单个属性,可以简化组件并使其更具未来可扩展性。

然而,这种方法可能会造成对对象结构的依赖,因此不太适合通用组件。

<!-- 使用整个对象 --><template><CustomerDisplay :customer="activeCustomer" />
</template><!-- CustomerDisplay.vue --><template><div><p>Name: {{ customer.name }}</p><p>Age: {{ customer.age }}</p><p>Address: {{ customer.address }}</p></div>
</template>

8. 控制器组件

Vue 中的控制器组件弥合了 UI(谦逊组件)和业务逻辑(可组合函数)之间的差距。

它们管理状态和交互,协调应用程序的整体行为。

<!-- TaskController.vue -->
<script setup>
import useTasks from './composables/useTasks';// 可组合函数包含业务逻辑
const { tasks, addTask, removeTask } = useTasks();
</script><template><!-- 谦逊组件提供 UI --><TaskInput @add-task="addTask" /><TaskList :tasks="tasks" @remove-task="removeTask" />
</template>

9. 策略模式

策略模式非常适合处理 Vue 应用程序中复杂的条件逻辑。它允许根据运行时条件在不同组件之间动态切换,从而提高代码的可读性和灵活性。在 Vue 的路由系统中,使用策略模式处理不同的导航行为,例如重定向、别名等。

<template><component :is="currentComponent" />
</template><script setup>
import { computed } from 'vue';
import ComponentOne from './ComponentOne.vue';
import ComponentTwo from './ComponentTwo.vue';
import ComponentThree from './ComponentThree.vue';const props = defineProps({conditionType: String,
});const currentComponent = computed(() => {switch (props.conditionType) {case 'one':return ComponentOne;case 'two':return ComponentTwo;case 'three':return ComponentThree;default:return DefaultComponent;}
});
</script>

10. 隐藏组件模式

隐藏组件模式涉及根据组件的使用方式,将复杂组件拆分成更小、更专注的组件。

如果不同的属性集是独占地一起使用的,则表明可以将组件进行拆分。

<!-- 重构之前 --><template><!-- 实际上是一个“图表”组件 --><DataDisplay:chart-data="data":chart-options="chartOptions"/><!-- 实际上是一个“表格”组件 --><DataDisplay:table-data="data":table-settings="tableSettings"/>
</template><!-- 重构之后 --><template><Chart :data="data" :options="chartOptions" /><table :data="data" :settings="tableSettings" />
</template>

11. 内部交易模式

内部交易模式解决了 Vue 中父组件和子组件过度耦合的问题。通过在必要时将子组件内联到父组件中,我们可以进行简化。

这个过程可以使组件结构更加连贯,减少碎片化。

<!-- ParentComponent.vue --><template><div><!-- 这个组件使用来自父组件的所有内容。它起什么作用呢? --><ChildComponent:user-name="userName":email-address="emailAddress":phone-number="phoneNumber"@user-update="(val) => $emit('user-update', val)"@email-update="(val) => $emit('email-update', val)"@phone-update="(val) => $emit('phone-update', val)"/></div>
</template><script setup>
defineProps({userName: String,emailAddress: String,phoneNumber: String,
});defineEmits(['user-update', 'email-update', 'phone-update']);
</script>

12. 长组件模式

什么算作“过长”的组件?

当它变得难以理解时。

长组件原则鼓励创建自文档化、命名清晰的组件,提高代码质量和可理解性。

<!-- 之前:一个冗长且复杂的组件 -->
<template><div><!-- 大量 HTML 和逻辑 --></div>
</template><!-- 之后:分解成更小的组件,名称告诉你代码的作用。 -->
<template><ComponentPartOne /><ComponentPartTwo />
</template>

http://www.ppmy.cn/embedded/152923.html

相关文章

HAMi + prometheus-k8s + grafana实现vgpu虚拟化监控

最近长沙跑了半个多月&#xff0c;跟甲方客户对了下项目指标&#xff0c;许久没更新 回来后继续研究如何实现 grafana实现HAMi vgpu虚拟化监控&#xff0c;毕竟合同里写了需要体现gpu资源限制和算力共享以及体现算力卡资源共享监控 先说下为啥要用HAMi吧&#xff0c; 一个重要原…

MySQL8 主从同步 在 Windows 本地 MySQL 和 WSL 上安装的 MySQL 做主从同步

在 Windows 本地 MySQL 和 WSL(Windows Subsystem for Linux)上安装的 MySQL 做主从同步,步骤主要分为几个部分:安装和配置 MySQL、设置主从同步、配置网络和防火墙等。以下是步骤的详细说明: 1. 在 Windows 和 WSL 中安装 MySQL 首先,确保 Windows 和 WSL 中的 MySQL …

Vue3 中如何根据路由动态生成侧边菜单

在 Vue3 的项目开发&#xff0c;尤其是后台管理系统这类复杂应用场景中&#xff0c;侧边菜单扮演着举足轻重的角色&#xff0c;它是用户快速导航至各个功能模块的得力助手。而根据路由动态生成侧边菜单&#xff0c;则为系统的灵活性和可扩展性增添了强大动力。接下来&#xff0…

数据集-目标检测系列- 石榴 检测数据集 pomegranate >> DataBall

数据集-目标检测系列- 石榴 检测数据集 pomegranate >> DataBall DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(fre…

【计算机网络】什么是网关(Gateway)?

网上冲浪多了&#xff0c;你可以听到过网关&#xff08;Gateway&#xff09;这个词&#xff0c;但是却不太清楚网关&#xff08;Gateway&#xff09;到底是干什么的、负责网络当中的什么任务&#xff0c;本篇文字将会为你介绍网关&#xff08;Gateway&#xff09;的作用&#x…

[大模型]本地离线运行openwebui+ollama容器化部署

本地离线运行Openweb-ui ollama容器化部署 说明安装internet操作内网操作问题线程启动错误最终命令总结说明 最近公司有一个在内网部署一个离线大模型的需求,网络是离线状态,服务器有A100GPU,一开始是想折腾开源chatGML4大模型,因为使用过gml3,所以想着部署gml4应该不难。…

Git 的引用规格(refspec)语法

目录 引用规格语法格式常见用法强制 -f 和 的区别git fetch origin remote-branch:local-branch 和 git push origin local-branch:remote-branch 区别 引用规格语法格式 格式如下&#xff1a;[]<src>:<dst> 常见用法 # fetch git fetch origin <remote-bra…

功能篇:mybatis中批量插入

在 MyBatis 中进行批量插入&#xff0c;可以通过几种不同的方式来实现。以下是两种常见的方法&#xff1a; ### 1. 使用 foreach 标签 MyBatis 提供了 <foreach> 元素来遍历集合&#xff08;如 List、Set 等&#xff09;&#xff0c;这可以用来构建动态 SQL 语句&#xf…