有了Composition API后,有些场景或许你不需要pinia了
前言
日常开发时有些业务场景功能很复杂,如果将所有代码都写在一个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中暴露出的状态count和doubleCount,以及方法increment和decrement,无需关注具体的内部逻辑是如何实现的。
上面的封装其实是有问题的,如果我们将组件拆为两个,分别为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变量。在我们这里CountValue和CountBtn组件都在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的外面,并且只有第一次调用useStore时count的值为空才会执行count = ref(0)。后面再次调用useStore时由于count已经被ref赋值为一个对象了,所以就不会再次走if逻辑。这样CountValue和CountBtn组件中调用useStore拿到的count变量都是我们在useStore函数外面定义的了。
那么这里的计算属性doubleCount为什么不放在useStore外面定义也可以呢?因为计算属性doubleCount的值是由count变量计算得来的,所以我们只需要保证每次调用useStore时访问的count变量是同一个,那么doubleCount计算属性的值就是相同的。当然你也可以将计算属性doubleCount的定义也放在useStore外面。
总结
这篇文章介绍了在多个组件中需要复用状态和业务逻辑的情况时,我们可以不将这些状态和业务逻辑写到pinia中,而是使用Composition API将状态和业务逻辑封装成一个hooks。为了多个组件同时调用hooks时能够共用同一个state状态,我们需要将定义的ref变量写在useStore函数外面。
如果我的文章对你有点帮助,欢迎关注公众号:【欧阳码农】,文章在公众号首发。你的支持就是我创作的最大动力,感谢感谢!
有了Composition API后,有些场景或许你不需要pinia了的更多相关文章
- Windows Composition API 指南 - 认识 Composition API
微软在 Windows 10中 面向通用 Windows 应用 (Universal Windows Apps, UWA) 新引入了一套用于用户界面合成的 API:Composition API.Co ...
- 蒲公英 · JELLY技术周刊 Vol.21 -- 技术周刊 · React Hooks vs Vue 3 + Composition API
蒲公英 · JELLY技术周刊 Vol.21 选 React 还是 Vue,每个人心中都会有自己的答案,有很多理由去 pick 心水的框架,但是当我们扪心自问,我们真的可以公正的来评价这两者之间的差异 ...
- Vue3:不常用的Composition API && Fragment、Teleport、Suspense && 与Vue2对比的一些变化
1 # 一.Vue3不常用的Composition API 2 # 1.shallowReactive与shallowRef 3 .shallowReactive: 只处理对象最外层属性的响应式(浅响 ...
- WEB API系列(一):WEB API的适用场景、第一个实例
在我前一篇博客中已经给各位简单介绍了HTTP协议与RestFul API的关系,以及一些基本的HTTP协议知识,在这些知识的铺垫下,今天,我们一起来讨论一下WEB API的适用场景,然后写我们第一个W ...
- WPF 使用 Composition API 做高性能渲染
在 WPF 中很多小伙伴都会遇到渲染性能的问题,虽然 WPF 的渲染可以甩浏览器渲染几条街,但是还是支持不了游戏级的渲染.在 WPF 使用的 DX 只是优化等级为 9 和 DX 9 差不多的性能,微软 ...
- Vue 3.0 Composition API - 中文翻译
Composition API 发布转载请附原文链接 https://www.cnblogs.com/zgh-blog/articles/composition_api.html 这两天初步了解了下 ...
- Composition API
介绍 Composition API的主要思想是,我们将它们定义为从新的 setup 函数返回的JavaScript变量,而不是将组件的功能(例如state.method.computed等)定义为对 ...
- Vue3全家桶升级指南一composition API
1.setup() vue3中的composition API中最重要的就是setup方法了,相当于组件的入口,所有的composition API都必须放到setup()中的使用. setup是在组 ...
- 好久没发文了,一篇Vue3的Composition API使用奉上
Composition API Composition API是Vue3中推荐的组件代码书写方式,相较于传统的Options API来说,它能让业务逻辑处理和后期代码维护变的更加简单. 首先我们来看O ...
- mixin和composition api
1. 这两个都是实现组件逻辑复用的法宝 2. composition api是vue3的, composition api的出现就是解决mixins的不足之处的 一. mixin 回顾下mixin, ...
随机推荐
- 国家专用加密数据传输之rsa,3des加密方法-rasor3desc
title: 国家专用加密数据传输之rsa,3des加密方法 date: 2021-12-20 13:08:21.646 updated: 2022-03-10 16:00:58.65 url: ht ...
- vuepress借助jenkins和svn实现文档自动化更新部署
前言 有个需求,需要将放在SVN的用vuepress写的文档进行自动化更新和部署,每次有人在本地将写好的md文件更新到svn时候,由jenkins实现自动打包来实现自动更新的功能. docker安装j ...
- Unicode编码:打破语言壁垒,实现无缝交流
Unicode编码是一种用于表示文本字符的编码系统,它旨在解决不同字符集之间相互兼容的问题,使各种语言和文化得以在数字世界中无缝交流.本文将从多个方面介绍Unicode编码的概念.原理及其在现实中的应 ...
- CSS 基础 1 - Block & Inline
CSS 基础 1 - Block & Inline display: inline/block/inline-block/none/flex/grid; block block 元素独占一行, ...
- MongoDB系列:C#、Java驱动连接MongoDB以及封装(C#的MongoDBHelper,Java的MongoDBUtil)
一.C#驱动连接MongoDB 1.创建项目 执行命令:dotnet new console -n MongoDbDriverDemo 2.添加依赖包 执行命令:dotnet add package ...
- 自定义Graph Component:1.1-JiebaTokenizer具体实现
JiebaTokenizer类继承自Tokenizer类,而Tokenizer类又继承自GraphComponent类,GraphComponent类继承自ABC类(抽象基类).本文使用<使 ...
- 一起玩转玩转LiteOS组件:Opus
摘要:Opus编码器是一个开源的有损声音编码格式,适用于网络实时声音传输,标准格式为RFC 6716,相对于其他编码格式来说,保真性更好. 本文分享自华为云社区<LiteOS组件尝鲜-玩转Opu ...
- XEngine:深度学习模型推理优化
摘要:从显存优化,计算优化两个方面来分析一下如何进行深度学习模型推理优化. 本文分享自华为云社区<XEngine-深度学习推理优化>,作者: ross.xw. 前言 深度学习模型的开发周期 ...
- Docker 启动失败 (code=exited, status=1/FAILURE)错误解决办法
ob for docker.service failed because the control process exited with error code. See "systemctl ...
- mit6.s081 lab2: system calls
1.system call tracing(moderate) 要求:创建一个系统调用来实现跟踪特性,它采用一个参数来指定跟踪哪一个系统调用,例如:跟踪fork系统调用,程序调用trace(1< ...