函数式调用的写法
一般都是use的函数式调用的用法,这里记录一下结合TS的案例:
判断是否点击指定元素外的区域
可用于下拉框点击外部后收起的逻辑判断。
/* 功能:传入一个DOM对象,判断是否点击除本身以外的其他dom上 */
import { Ref, ref, onMounted, onUnmounted } from "vue";
interface Result {
isClickOutside: Ref<boolean>;
}
const useClickOutside = (DOM: Ref<null | HTMLElement>): Result => {
const isClickOutside = ref(false); // 是否点击到外部DOM
const hander = (e: MouseEvent) => {
// MouseEvent为ts内置类型
// 直接写DOM.value.contains,ts会报错可能为null,所以要多个DOM.value判断
// contains判断一个标签是否包含另一个标签,e.target不一定每次点击的都是Dom,ts提示可能是null,所以要断言一下
if (DOM.value && DOM.value.contains(e.target as HTMLElement)) {
isClickOutside.value = false;
} else {
isClickOutside.value = true;
}
};
onMounted(() => {
document.addEventListener("click", hander); // document上加click监听事件
});
onUnmounted(() => {
document.removeEventListener("click", hander);
});
return { isClickOutside };
};
export default useClickOutside;
使用:
import useClickOutside from "@/hooks/useClickOutside";
setup() {
let dropdownDom = ref<null | HTMLElement>(null); // 默认给个null,当标签挂载后会自动换成dom。以value取值。
let { isClickOutside } = useClickOutside(dropdownDom); // 获取是否点到外面的dom
}
创建一个全局dom
可用于制作全局提示的实现逻辑
/* 功能:临时创建一个dom,挂载在body上,组件销毁时也要顺带销毁
用于使用vue3传送门指定的dom */
import { onUnmounted } from "vue";
const useDOMCreate = (nodeId: string): void => {
const node = document.createElement("div");
node.id = nodeId;
document.body.appendChild(node);
onUnmounted(() => {
document.body.removeChild(node);
});
};
export default useDOMCreate;
使用:
import useDOMCreate from "@/hooks/useDOMCreate"; // 引入创建临时dom的组件
setup() {
useDOMCreate("back");
return {};
}
类minxins的写法
有点像vue2那个minxins的意思。举个简单例子(这次使用script setup的写法)
import { watch, ref } from "vue";
// 是否被勾选
export const selected = ref([]);
export const selectedData = ref([]);
watch(
selected ,
(val) => {
// 做一些逻辑,例如把selectedData 变量里的数据改变了一下
},
{
immediate: true,
}
);
使用:
<script setup>
import { selected, selectedData } from "./dynamic";
// selected可以用于模板的双向绑定,然后拿到处理好后的selectedData 数据
</script>
未完待续…