-
编写了一个用途是处理class样式的hook,用于为所有的css类增加一个前缀
-
代码大概如下,返回computed的本意是响应属性的变化
- 本来想要的用法是这样,最终想要在config.prefix和props.disabled发生变化的时候,自动重新计算computed
但是,上面这种写法,在props.disabled变化的时候压根不会响应。不光如此,想让他响应起来,可能要费点劲。
写vue3的时候,需要额外考虑这个对象是否响应,是否是Ref,增加了很多心智负担
这里有一个最小复现的demo,如下:
父组件:
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld :disabled="disabled" />
</template>
<script>
import HelloWorldVue from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld: HelloWorldVue,
},
data() {
return {
disabled: false,
}
},
mounted() {
setInterval(() => {
this.disabled = !this.disabled;
}, 1000);
}
};
</script>
子组件:
<template>
<div :class="className">Hello World!</div>
<div :class="classNameReactive">Hello World Reactive!</div>
<div :class="classNameRef">Hello World Ref!</div>
<div :class="classNameComputed">Hello World Computed!</div>
</template>
<script setup>
import { reactive, computed, ref } from "vue";
import { useClassName, useClassNameRef } from "./useClassName";
const props = defineProps({
disabled: Boolean,
});
const className = useClassName({
"hello-world-disabled": props.disabled,
});
const classNameReactive = useClassName(reactive({
"hello-world-disabled": props.disabled,
}));
const refClassItem = ref({
disabled: props.disabled
});
const classNameRef = useClassNameRef(refClassItem);
const computedClassItem = computed(() => {
return { "hello-world-disabled": props.disabled }
})
const classNameComputed = useClassNameRef(computedClassItem);
</script>
useClassName.js:
import { computed, unref } from 'vue';
export function useClassName(cls) {
return computed(() => {
return Object.keys(cls).reduce((list, key) => {
const value = cls[key];
if (value) {
return [...list, key];
}
return list;
}, [])
});
}
export function useClassNameRef(cls) {
return computed(() => {
const unrefCls = unref(cls)
return Object.keys(unrefCls).reduce((list, key) => {
const value = unrefCls[key];
if (value) {
return [...list, key];
}
return list;
}, [])
});
}
最后,发现了一个看起来不那么蠢的写法
通过传递方法将依赖收集延迟到computed中进行
如图,用的时候传递方法
谁还有更合理的写法,大家交流交流