feat: 支持设置多重水印,增加清除所有水印方法. close #2610 (#3084)

* perf(watermark): 消除水印hook类型问题

* feat: 支持设置多重水印,增加清除所有水印方法

* chore: 应该让用户自己来进行水印清除
This commit is contained in:
invalid w 2023-09-28 11:05:53 +08:00 committed by GitHub
parent c0c3116193
commit 64b812802f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 31 deletions

View File

@ -3,15 +3,24 @@ import { useRafThrottle } from '/@/utils/domUtils';
import { addResizeListener, removeResizeListener } from '/@/utils/event';
import { isDef } from '/@/utils/is';
const domSymbol = Symbol('watermark-dom');
const sourceMap = new WeakMap<HTMLElement, {}>();
const watermarkSymbol = 'watermark-dom';
type UseWatermarkRes = {
setWatermark: (str: string) => void;
clear: () => void;
clearAll: () => void;
};
const sourceMap = new Map<Symbol, Omit<UseWatermarkRes, 'clearAll'>>();
export function useWatermark(
appendEl: Ref<HTMLElement | null> = ref(document.body) as Ref<HTMLElement>,
) {
): UseWatermarkRes {
const domSymbol = Symbol(watermarkSymbol);
const appendElRaw = unref(appendEl);
if (appendElRaw && sourceMap.has(appendElRaw)) {
return sourceMap.get(appendElRaw);
if (appendElRaw && sourceMap.has(domSymbol)) {
const { setWatermark, clear } = sourceMap.get(domSymbol) as UseWatermarkRes;
return { setWatermark, clear, clearAll };
}
const func = useRafThrottle(function () {
const el = unref(appendEl);
@ -19,13 +28,13 @@ export function useWatermark(
const { clientHeight: height, clientWidth: width } = el;
updateWatermark({ height, width });
});
const id = domSymbol.toString();
const watermarkEl = shallowRef<HTMLElement>();
const clear = () => {
const domId = unref(watermarkEl);
watermarkEl.value = undefined;
const el = unref(appendEl);
sourceMap.delete(domSymbol);
if (!el) return;
domId && el.removeChild(domId);
removeResizeListener(el, func);
@ -70,25 +79,23 @@ export function useWatermark(
}
const createWatermark = (str: string) => {
if (unref(watermarkEl)) {
if (unref(watermarkEl) && sourceMap.has(domSymbol)) {
updateWatermark({ str });
return id;
return;
}
const div = document.createElement('div');
watermarkEl.value = div;
div.id = id;
div.style.pointerEvents = 'none';
div.style.top = '0px';
div.style.left = '0px';
div.style.position = 'absolute';
div.style.zIndex = '100000';
const el = unref(appendEl);
if (!el) return id;
if (!el) return;
const { clientHeight: height, clientWidth: width } = el;
updateWatermark({ str, width, height });
el.appendChild(div);
sourceMap.set(el, { setWatermark, clear });
return id;
sourceMap.set(domSymbol, { setWatermark, clear });
};
function setWatermark(str: string) {
@ -102,5 +109,11 @@ export function useWatermark(
}
}
return { setWatermark, clear };
return { setWatermark, clear, clearAll };
}
function clearAll() {
Array.from(sourceMap.values()).forEach((item) => {
item.clear();
});
}

View File

@ -1,33 +1,30 @@
<template>
<PageWrapper title="水印示例">
<CollapseContainer class="w-full h-32 bg-white rounded-md" title="Global WaterMark">
<a-button type="primary" class="mr-2" @click="setWatermark('WaterMark Info')">
Create
<a-button type="primary" class="mr-2" @click="setWatermark('WaterMark Info1')">
Create Watermark1
</a-button>
<a-button color="error" class="mr-2" @click="clear"> Clear </a-button>
<a-button type="primary" class="mr-2" @click="setWatermark2('WaterMark Info2')">
Create Watermark2
</a-button>
<a-button color="error" class="mr-2" @click="clear"> Clear Watermark1 </a-button>
<a-button color="error" class="mr-2" @click="clearAll"> ClearAll </a-button>
<a-button color="warning" class="mr-2" @click="setWatermark('WaterMark Info New')">
Reset
Update Watermark1
</a-button>
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
<script lang="ts" setup>
import { onUnmounted } from 'vue';
import { CollapseContainer } from '/@/components/Container/index';
import { useWatermark } from '/@/hooks/web/useWatermark';
import { PageWrapper } from '/@/components/Page';
import { type Nullable } from '@vben/types';
export default defineComponent({
components: { CollapseContainer, PageWrapper },
setup() {
const areaRef = ref<Nullable<HTMLElement>>(null);
const { setWatermark, clear } = useWatermark();
return {
setWatermark,
clear,
areaRef,
};
},
const { setWatermark, clear, clearAll } = useWatermark();
const { setWatermark: setWatermark2 } = useWatermark();
onUnmounted(() => {
clearAll();
});
</script>