首页 > 其他分享 >有了Composition API后,有些场景或许你不需要pinia了

有了Composition API后,有些场景或许你不需要pinia了

时间:2024-01-23 15:14:40浏览次数:34  
标签:count hooks value API pinia 组件 useStore Composition doubleCount

前言

日常开发时有些业务场景功能很复杂,如果将所有代码都写在一个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函数外面。

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

标签:count,hooks,value,API,pinia,组件,useStore,Composition,doubleCount
From: https://www.cnblogs.com/heavenYJJ/p/17982518

相关文章

  • .NET 6 ASP.NET Core API 项目依赖注入一个全局对象,确保全局只实例化一次,调用的都是此
    在.NET6中,实现全局单例服务的方法是通过内置在ASP.NETCore中的依赖注入(DI)容器来完成的。DI容器负责创建和管理服务的实例,包括控制它们的生命周期。对于单例服务,DI容器将确保在应用程序的整个生命周期内只创建服务的一个实例,并且所有对该服务的请求都会返回这个单一的实例。以下......
  • 【OpenVINO】基于 OpenVINO C# API 部署 RT-DETR 模型
     RT-DETR是在DETR模型基础上进行改进的,一种基于DETR架构的实时端到端检测器,它通过使用一系列新的技术和算法,实现了更高效的训练和推理,在前文我们发表了《基于OpenVINO™PythonAPI部署RT-DETR模型|开发者实战》和《基于OpenVINO™C++API部署RT-DETR模型|开发......
  • 既是API调试平台也是自动化测试工具?Apipost
    Apipost提供可视化的API自动化测试功能,使用Apipost研发人员可以设计、调试接口,测试人员可以基于同一数据源进行测试,Apipost接口自动化功能在上次更新中进行了逻辑调整,带来更好的交互操作、更多的控制器选择,同时新增同步接口模式选择、测试数据选择功能。添加接口使用Apipost,研发......
  • 想在IDEA中调试API?试试这款,堪比postman
    Postman是大家最常用的API调试工具,那么有没有一种方法可以不用手动写入接口到Postman,即可进行接口调试操作?今天给大家推荐一款IDEA插件:ApipostHelper,写完代码就可以调试接口并一键生成接口文档!而且还可以根据已有的方法帮助您快速生成url和params。更重要的是他完全免费!Apipost......
  • 想在IDEA中调试API?试试这款,堪比postman
    Postman是大家最常用的API调试工具,那么有没有一种方法可以不用手动写入接口到Postman,即可进行接口调试操作?今天给大家推荐一款IDEA插件:ApipostHelper,写完代码就可以调试接口并一键生成接口文档!而且还可以根据已有的方法帮助您快速生成url和params。更重要的是他完全免费!Apipos......
  • 若依框架解读(微服务版)——2.模块间的调用逻辑(ruoyi-api模块)(OpenFeign)(@innerAuth)
    模块之间的关系我们可以了解到一共有这么多服务,我们先启动这三个服务其中rouyi–api模块是远程调用也就是提取出来的openfeign的接口ruoyi–commom是通用工具模块其他几个都是独立的服务ruoyi-api模块api模块当中有几个提取出来的OpenFeign的接口分别为文件,日志,用户服务......
  • Asp.net Webapi 的 Post 方法不能把参数加到 URL 中?试试这样写
    Restful风格的api虽然规范了四个方法(Get、Post、Put、Delete)用于数据的查询、增加、修改和删除,但在实际应用中,还是会有很多公司只使用了Get和Post两个方法,查询数据使用Get方法,其它业务操作使用Post方法(为什么会有情况,以后可以写一篇文章讨论一下_),但是Post方法一般......
  • 【解决方案】如何使用 Http API 代替 OpenFeign 进行远程服务调用
    目录前言一、何为OpenFeign1.1@FeignClient注解1.2注意事项二、常见的HttpAPI2.1Apache2.2Okhttp2.3Hutool三、RestTemplate3.1详解.execute()四、文章小结前言看到标题大家可能会有点疑惑吧:OpenFeign不是挺好用的吗?尤其是微服务之间的远程调用,平时用的也挺习惯的,为啥要替换呢......
  • 状态管理pinia
    状态管理持久化//网页端APIlocalStorage.setItem()localStorage.getItem()//小程序端的APIwx.setStorageSync()wx.getStorageSync()//兼容多端APIuni.setStorageSync()uni.getStorageSync()  这个步骤完成之后我们就可以实现持久化点击保存按钮就可以看到......
  • 【OpenVINO】基于 OpenVINO C++ API 部署 RT-DETR 模型
     RT-DETR是在DETR模型基础上进行改进的,一种基于DETR架构的实时端到端检测器,它通过使用一系列新的技术和算法,实现了更高效的训练和推理,在前文我们发表了《基于OpenVINO™PythonAPI部署RT-DETR模型|开发者实战》,在该文章中,我们基于OpenVINO™PythonAPI向大家展示......