• 【vue3】一些关于hooks的使用经验


    前言

    最近接到了一个需求,隔壁嵌入式部门希望我们用前端解析渲染Kconfig表单。这篇文章用来记录一下本次使用hook + pinia + vue3的经验

    hooks

    hooks的概念最早是在 React 中听到的,虽然早些时间也写过一点react,但也只是照葫芦画瓢,并不得要领。比如我一直觉得所谓的hook就是像react一样,使用以下语法

    // react hook 写法
    const [value, setValue] = useValue();
    
    // vue2 普通写法
    data: {
    	value
    },
    method: {
    	setValue(newVal) {
    		...
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    可以看见,其实原始的写法与hook的写法差距是蛮大的。
    原始是在data里创建变量,至于变量的更新,自己在method里定义函数即可。
    而hook的写法是通过 useXXX() 创建变量和变量更新的函数。

    那么hook的写法,到底有什么好处呢?

    逻辑复用、可插拔

    export function useCounter() {
      const count = ref(0);
      
      function increment() {
        count.value++;
      }
      
      function decrement() {
        count.value--;
      }
      
      return {
        count,
        increment,
        decrement
      };
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    上述示例中,useCounter 函数用于创建一个计数器逻辑,包含了一个 count 变量和两个操作函数 incrementdecrement。可以在多个组件中使用 useCounter 函数,实现逻辑的复用。

    如果是原始的方式,我们就必须在每个页面写 counterincrementdecrement 是一件繁琐的事情。当然,我们也可以抽离,但抽离到单独的文件中去引用时,又会有作用域的问题,导致每个页面使用的 counter 变量是同一个变量,会出现新的问题。

    于是不得不再提到一个实用的场景: flag 标志位 控制显示与隐藏。

    // hook.ts
    export function useFlag(initVal: boolean) {
      const flag = ref(initVal);
      
      function setFlag(newVal: boolean) {
        flag.value = newVal
      }
      
      return {
        flag,
        setFlag
      };
    }
    
    // 页面中使用
    const { flag, setFlag } = useFlag(true);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在上述代码中,最后在页面使用了 hook ,每个页面都可以使用这个 hook 且作用域不同,不会相互影响。

    更易抽离,逻辑更清晰

    上面提到了 useFlag 的 hook ,此时有一个新需求,当每个组件的显隐都需要进行一些相同的逻辑判断控制显隐,此时怎么办?
    我们可以创建一个新的 hook

    import { useFlag } from '@/hooks/useFlag'
    import { handleDepends_on } from '@/utils/util';
    
    
    export const useDepend = (data) => {
      const { result } = useStore('result');
      const { flag, setFlag } = useFlag(true);
    
      const dependList = handleDepends_on(data.depends_on);
      watch(result, () => {
        // 首先置位true
        setFlag(true)
        // 如果出现不满足,则置位false
        dependList.map(item => {
          if (!result.value[item]) setFlag(false)
        })
      }, { immediate: true, deep: true })
    
      return {
        flag
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    pinia 中的 result 变量变化时,会触发 watch 监听函数。如果 flag 改变,页面里的 flag 也会同步,并更新视图。

    因此只需要在每个需要逻辑判断的页面输入两行,即可完成判断逻辑的复用~

    import { useDepend } from '@/hook/useDepend';
    const { flag } = useDepend('数据')
    
    • 1
    • 2

    在这里插入图片描述

  • 相关阅读:
    Seata-TCC模式
    Linux | 进程终止与进程等待
    HTML表单标签
    SpringCloud第二篇:Feign远程调用
    Spring Security :二【原理解析、会话管理、RBAC中集成认证和授权、JWT】
    脂肪 、肥胖与健康
    20 【rem适配布局】
    linux驱动开发学习001:概述
    基于PHP+html的学生课外活动成果统计系统
    MD5加密算法
  • 原文地址:https://blog.csdn.net/MinfCONS/article/details/132762148