前言

日常开发时有些业务场景功能很复杂,如果将所有代码都写在一个vue组件中,那个vue文件的代码量可能就几千行了,维护极其困难。这时我们就需要将其拆分为多个组件,拆完组件后就需要在不同组件间共享数据和业务逻辑。有的小伙伴会选择将数据和业务逻辑都放到pinia中,这样虽然可以解决问题。但是如果将所有的复杂的业务都放在pinia中,那么pinia就会变得很乱。

将数据和业务逻辑都封装到hooks

这时你还有另外一个选择,使用Composition API将数据和业务逻辑都抽取到hooks中。state状态的定义和更新以及具体的业务逻辑全部由hooks内部维护,组件只负责使用hooks暴露出的state状态和方法。

下面是我们封装的hooks

export const useStore = () => {
const count = ref(0); const doubleCount = computed(() => {
return count.value * 2;
}); function increment() {
count.value = count.value + 1;
} function decrement() {
count.value = count.value - 1;
} return {
count,
doubleCount,
increment,
decrement,
};
};

组件只需要使用hooks中暴露出的状态countdoubleCount,以及方法incrementdecrement,无需关注具体的内部逻辑是如何实现的。

上面的封装其实是有问题的,如果我们将组件拆为两个,分别为CountValue.vue(显示count的值)和CountBtn.vue(修改count变量值)。

CountValue.vue组件代码如下:

<template>
<p>count的值是{{ count }}</p>
<p>doubleCount的值是{{ doubleCount }}</p>
</template> <script setup lang="ts">
import { useStore } from "./store"; const { count, doubleCount } = useStore();
</script>

CountBtn.vue组件代码如下:

<template>
<button @click="decrement">count--</button>
<button @click="increment">count++</button>
</template> <script setup lang="ts">
import { useStore } from "./store"; const { decrement, increment } = useStore();
</script>

由于我们的count变量是在useStore函数中定义的,所以每调用一次useStore函数都会重新定义一个count变量。在我们这里CountValueCountBtn组件都在setup中调用了useStore函数,通过useStore函数拿到的就不是同一个count变量。这样就会导致我们在CountBtn中修改了count变量的值,但是CountValue组件中显示的count变量的值一直没变。

多个组件同时调用hooks如何共享同一份state状态

要解决上面的问题其实很简单,问题的原因是因为每次调用useStore函数都会生成一个新的count变量。那我们就不将count变量的定义写在useStore函数中,只需要将count变量的定义写在useStore函数的外面就可以了。

下面是优化后的hooks

import { computed, ref } from "vue";

// 将count的定义放在外面
let count;
export const useStore = () => {
if (!count) {
count = ref(0);
} const doubleCount = computed(() => {
return count.value * 2;
}); function increment() {
count.value = count.value + 1;
} function decrement() {
count.value = count.value - 1;
} return {
count,
doubleCount,
increment,
decrement,
};
};

我们将count变量定义放在了useStore的外面,并且只有第一次调用useStorecount的值为空才会执行count = ref(0)。后面再次调用useStore时由于count已经被ref赋值为一个对象了,所以就不会再次走if逻辑。这样CountValueCountBtn组件中调用useStore拿到的count变量都是我们在useStore函数外面定义的了。

那么这里的计算属性doubleCount为什么不放在useStore外面定义也可以呢?因为计算属性doubleCount的值是由count变量计算得来的,所以我们只需要保证每次调用useStore时访问的count变量是同一个,那么doubleCount计算属性的值就是相同的。当然你也可以将计算属性doubleCount的定义也放在useStore外面。

总结

这篇文章介绍了在多个组件中需要复用状态和业务逻辑的情况时,我们可以不将这些状态和业务逻辑写到pinia中,而是使用Composition API将状态和业务逻辑封装成一个hooks。为了多个组件同时调用hooks时能够共用同一个state状态,我们需要将定义的ref变量写在useStore函数外面。

如果我的文章对你有点帮助,欢迎关注公众号:【欧阳码农】,文章在公众号首发。你的支持就是我创作的最大动力,感谢感谢!

有了Composition API后,有些场景或许你不需要pinia了的更多相关文章

  1. Windows Composition API 指南 - 认识 Composition API

    微软在 Windows 10中 面向通用 Windows 应用 (Universal Windows Apps, UWA) 新引入了一套用于用户界面合成的 API:Composition API.Co ...

  2. 蒲公英 &#183; JELLY技术周刊 Vol.21 -- 技术周刊 &#183; React Hooks vs Vue 3 + Composition API

    蒲公英 · JELLY技术周刊 Vol.21 选 React 还是 Vue,每个人心中都会有自己的答案,有很多理由去 pick 心水的框架,但是当我们扪心自问,我们真的可以公正的来评价这两者之间的差异 ...

  3. Vue3:不常用的Composition API && Fragment、Teleport、Suspense && 与Vue2对比的一些变化

    1 # 一.Vue3不常用的Composition API 2 # 1.shallowReactive与shallowRef 3 .shallowReactive: 只处理对象最外层属性的响应式(浅响 ...

  4. WEB API系列(一):WEB API的适用场景、第一个实例

    在我前一篇博客中已经给各位简单介绍了HTTP协议与RestFul API的关系,以及一些基本的HTTP协议知识,在这些知识的铺垫下,今天,我们一起来讨论一下WEB API的适用场景,然后写我们第一个W ...

  5. WPF 使用 Composition API 做高性能渲染

    在 WPF 中很多小伙伴都会遇到渲染性能的问题,虽然 WPF 的渲染可以甩浏览器渲染几条街,但是还是支持不了游戏级的渲染.在 WPF 使用的 DX 只是优化等级为 9 和 DX 9 差不多的性能,微软 ...

  6. Vue 3.0 Composition API - 中文翻译

    Composition API 发布转载请附原文链接 https://www.cnblogs.com/zgh-blog/articles/composition_api.html 这两天初步了解了下 ...

  7. Composition API

    介绍 Composition API的主要思想是,我们将它们定义为从新的 setup 函数返回的JavaScript变量,而不是将组件的功能(例如state.method.computed等)定义为对 ...

  8. Vue3全家桶升级指南一composition API

    1.setup() vue3中的composition API中最重要的就是setup方法了,相当于组件的入口,所有的composition API都必须放到setup()中的使用. setup是在组 ...

  9. 好久没发文了,一篇Vue3的Composition API使用奉上

    Composition API Composition API是Vue3中推荐的组件代码书写方式,相较于传统的Options API来说,它能让业务逻辑处理和后期代码维护变的更加简单. 首先我们来看O ...

  10. mixin和composition api

    1. 这两个都是实现组件逻辑复用的法宝 2. composition api是vue3的,  composition api的出现就是解决mixins的不足之处的 一. mixin 回顾下mixin, ...

随机推荐

  1. Javascript Ajax总结——FormData类型

    XMLHttpRequest1级只是把已有的XHR对象的实现细节描述出来.XMLHttpRequest2级进一步发展了XHR.FormData类型FormData类型,为序列化表单以及创建以表单格式相 ...

  2. 探索 Linux Namespace:Docker 隔离的神奇背后

    在 深入理解 Docker 核心原理:Namespace.Cgroups 和 Rootfs 一文中我们分析了 Docker 是由三大核心技术实现的. 今天就一起分析 Docker 三大核心技术之一的 ...

  3. Huggy Lingo: 利用机器学习改进 Hugging Face Hub 上的语言元数据

    太长不看版: Hub 上有不少数据集没有语言元数据,我们用机器学习来检测其语言,并使用 librarian-bots 自动向这些数据集提 PR 以添加其语言元数据. Hugging Face Hub ...

  4. 首次引入大模型!Bert-vits2-Extra中文特化版40秒素材复刻巫师3叶奈法

    Bert-vits2项目又更新了,更新了一个新的分支:中文特化,所谓中文特化,即针对中文音色的特殊优化版本,纯中文底模效果百尺竿头更进一步,同时首次引入了大模型,使用国产IDEA-CCNL/Erlan ...

  5. Liquid 常用语法记录

    一.什么是 Liquid Liquid 是一款专为特定需求而打造的模板引擎. Liquid 中有两种类型的标记:Output 和 Tag. Output 通常用来显示文本 {{ 两个花括号 }} Ta ...

  6. 【Tinyui】极简跨平台桌面端小工具开发框架

    导航 Github Gitee 开发指南 用户手册 说明 在产品或项目工作中,可能会遇到需要给非开发人员或者客户提供简易的PC小工具,这些小工具通常用户交互比较简单:功能也不复杂:同时需要支持多平台以 ...

  7. PowerDotNet平台化软件架构设计与实现系列(17):PCRM个人用户管理平台

    个人用户管理是业务系统中非常基础且重要的一个公共服务系统,我们写的绝大多数应用都和个人用户或会员有关,用户(会员)数据安全无小事,必须有一个完备的用户管理平台系统. 因为不同公司的主业务不同,个人用户 ...

  8. flutter中去除导航栏与状态栏

    方法一 SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom]); // ...

  9. Prometheus配置Basic Auth进行安全防护,实现登录控制

    本文分享自华为云社区<Prometheus配置Basic Auth进行安全防护,实现登录控制>,作者:可以交个朋友. 一.Prometheus Basic Auth 使用背景 在日常pro ...

  10. FQS:一种神奇的数仓查询优化技术

    本文分享自华为云社区<根据执行计划优化SQL[绽放吧!GaussDB(DWS)云原生数仓]>,作者:西岭雪山. 引言 如果您刚接触DWS那一定会好奇想要知道"REMOTE_FQS ...