vite+vue3+ts项目添加防止删除水印
以指令的方式为模块区域添加 水印
- 添加指水印指令
import type { App } from 'vue';
import watermark from './waterMark';
export default function installDirective(app: App) {
app.directive(watermark.name, watermark.directives);
}
- 指令实体代码
const globalCanvas = document.createElement('canvas');
const globalWaterMark = document.createElement('div');
const getDataUrl = (binding: any) => {
const rotate = -20;
const canvas = globalCanvas || document.createElement('canvas');
const ctx = <CanvasRenderingContext2D>canvas.getContext('2d');
canvas.width = 390;
canvas.height = 180;
ctx?.rotate((rotate * Math.PI) / 180);
ctx.font = binding.font || '12px Vedana';
ctx.fillStyle = binding.fillStyle || 'rgba(200, 200, 200, 0.30)';
ctx.textBaseline = 'middle';
ctx?.fillText(binding.text || '默认水印文字', canvas.width / 10, canvas.height / 2);
return canvas.toDataURL('image/png');
};
let style = `
display: block;
overflow: hidden;
position: absolute;
left: 0px;
top: 0px;
z-index: 100000;
font-size: 12px;
background-repeat: repeat;
background-position: center;
pointer-events: none;`;
const directives: any = {
mounted(el: HTMLElement, binding: any) {
init(el, binding.value);
},
};
const init = (el: HTMLElement, binding: any = {}) => {
setWaterMark(el, binding);
createObserver(el, binding);
};
const setWaterMark = (el: HTMLElement, binding: any) => {
const { parentElement } = el;
const { width, height } = parentElement!.getBoundingClientRect();
const url = getDataUrl(binding);
const waterMark = globalWaterMark || document.createElement('div');
waterMark.className = `pdp-water-mark`;
style = `${style}background-image: url(${url});width:${width}px; height:${height}px`;
waterMark.setAttribute('style', style);
let currStyle = parentElement?.getAttribute('style') ? parentElement?.getAttribute('style') : '';
currStyle = currStyle?.includes('position: relative')
? currStyle
: currStyle + 'position: relative;';
parentElement?.setAttribute('style', currStyle);
parentElement?.appendChild(waterMark);
};
const createObserver = (el: any, binding: any) => {
const waterMarkEl = el.parentElement?.querySelector('.pdp-water-mark');
const observer = new MutationObserver((mutationsList) => {
if (mutationsList.length) {
const { removedNodes, type, target } = mutationsList[0];
const currStyle = waterMarkEl?.getAttribute('style');
if (removedNodes[0] === waterMarkEl) {
observer.disconnect();
init(el, binding);
} else if (type === 'attributes' && target === waterMarkEl && currStyle !== style) {
waterMarkEl.setAttribute('style', style);
}
}
});
observer.observe(el.parentElement, {
childList: true,
attributes: true,
subtree: true,
});
};
export default {
name: 'watermark',
directives,
};
- 在项目入口文件引入指令并注册
import { createApp } from 'vue';
import { setupElementPlus } from '@/styles/index';
import { setupRouter } from './router';
import { setupStore } from './store/index';
import App from './App.vue';
import '@/styles/font/iconfont.css';
import permisson from './plugins/permission';
import XGantt from '@xpyjs/gantt';
import '@xpyjs/gantt/dist/index.css';
import directives from '@/directives';
async function bootstrap() {
const app = createApp(App);
setupStore(app);
setupRouter(app);
setupElementPlus(app);
app.use(permisson).use(XGantt).use(directives);
app.mount('#app');
}
bootstrap();
- 在需要加水印的dom上使用指令 v-watermark=“watermarkObj”
<el-container class="container">
<aside-menu />
<el-main class="main">
<header-menu />
<el-container
class="content"
:style="{
height: `${
screenFullState ? '100%' : isShowHeadMenu ? 'calc(100% - 113px)' : 'calc(100% - 64px)'
}`,
overflowY: 'auto',
}"
>
<router-view v-slot="{ Component }" v-watermark="watermarkObj">
<transition name="fade-transform" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</el-container>
</el-main>
</el-container>
<script lang="ts" setup>
import { useStore as useBaseStore } from '../store/base';
const store = useStore();
const wartermarkText = computed(() => {
let info = store?.state?.user;
return `${info.username}${info.phone}`;
});
let watermarkObj = reactive({
text: wartermarkText.value,
});
</script>
- 水印效果图