前言
最近接到了一个需求,隔壁嵌入式部门希望我们用前端解析渲染Kconfig表单。这篇文章用来记录一下本次使用hook + pinia + vue3
的经验
hooks
hooks的概念最早是在 React 中听到的,虽然早些时间也写过一点react,但也只是照葫芦画瓢,并不得要领。比如我一直觉得所谓的hook
就是像react一样,使用以下语法
// react hook 写法
const [value, setValue] = useValue();// vue2 普通写法
data: {value
},
method: {setValue(newVal) {...}
}
可以看见,其实原始的写法与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};
}
上述示例中,useCounter
函数用于创建一个计数器逻辑,包含了一个 count
变量和两个操作函数 increment
和 decrement
。可以在多个组件中使用 useCounter
函数,实现逻辑的复用。
如果是原始的方式,我们就必须在每个页面写 counter
、increment
、decrement
是一件繁琐的事情。当然,我们也可以抽离,但抽离到单独的文件中去引用时,又会有作用域的问题,导致每个页面使用的 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);
在上述代码中,最后在页面使用了 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, () => {// 首先置位truesetFlag(true)// 如果出现不满足,则置位falsedependList.map(item => {if (!result.value[item]) setFlag(false)})}, { immediate: true, deep: true })return {flag}
}
当 pinia
中的 result
变量变化时,会触发 watch 监听函数。如果 flag
改变,页面里的 flag
也会同步,并更新视图。
因此只需要在每个需要逻辑判断的页面输入两行,即可完成判断逻辑的复用~
import { useDepend } from '@/hook/useDepend';
const { flag } = useDepend('数据')