前言
最近接到了一个需求,隔壁嵌入式部门希望我们用前端解析渲染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, () => {
// 首先置位true
setFlag(true)
// 如果出现不满足,则置位false
dependList.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('数据')