• 有了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中暴露出的状态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的定义放在外面
    const count = ref(0);
    const doubleCount = computed(() => {
      return count.value * 2;
    });
    
    export const useStore = () => {
      function increment() {
        count.value = count.value + 1;
      }
    
      function decrement() {
        count.value = count.value - 1;
      }
    
      return {
        count,
        doubleCount,
        increment,
        decrement,
      };
    };
    

    我们将count变量定义放在了useStore函数的外面,这样CountValueCountBtn组件中调用useStore拿到的count变量都是我们在useStore函数外面定义的count变量。

    总结

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

    关注公众号:【前端欧阳】,解锁我更多vue干货文章,并且可以免费向我咨询vue相关问题。
    qrcode

  • 相关阅读:
    小表join顺序和广播问题
    【匠心之作】三道题带你简单复习C++和Java
    RNN在图像压缩领域的应用-Variable rate image compression with recurrent neural networks
    【软考软件评测师】软件测试基础知识
    day03_python基础
    数据库开发-MySQL基础DQL和多表设计
    4.力扣c++刷题-->删除有序数组中的重复项 II
    函数指针作业题目
    【有奖提问】向图灵奖得主、贝叶斯网络之父 Judea Pearl 提问啦
    【电子实验2】简单电子门铃
  • 原文地址:https://www.cnblogs.com/heavenYJJ/p/17982518