v-watermark自定义指令
# 自定义指令v-watermark
# 封装
const globalCanvas = null;
const globalWaterMark = null;
// watermark 样式
let style = `
display: block;
overflow: hidden;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-repeat: repeat;
pointer-events: none;`;
const getDataUrl = ({
font,
fillStyle,
textAlign,
textBaseline,
text,
rotate = -20,
}) => {
font = font || "16px normal";
fillStyle = fillStyle || "rgba(180, 180, 180, 0.2)";
text = text || "";
const canvas = globalCanvas || document.createElement("canvas");
const ctx = canvas.getContext("2d"); // 获取画布上下文
ctx.rotate((rotate * Math.PI) / 180);
ctx.font = font;
ctx.fillStyle = fillStyle;
ctx.textAlign = textAlign || "left";
ctx.textBaseline = textBaseline || "middle";
ctx.fillText(text, canvas.width / 10, canvas.height / 2);
return canvas.toDataURL("image/png", 1); // 第二个参数为质量
};
const setWaterMark = (el, binding) => {
const parentElement = el.parentElement;
// 获取对应的 canvas 画布相关的 base64 url
const url = getDataUrl(binding);
// 创建 waterMark 父元素
const waterMark = globalWaterMark || document.createElement("div");
waterMark.className = "water-mark"; // 方便自定义展示结果
style = `${style}background-image: url(${url});`;
waterMark.setAttribute("style", style);
// 将对应图片的父容器作为定位元素
parentElement.setAttribute("style", "position: relative;");
// 将图片元素移动到 waterMark 中
parentElement.appendChild(waterMark);
};
// 监听 DOM 变化
const createObserver = (el, binding) => {
const waterMarkEl = el.parentElement.querySelector(".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();
// 重新添加水印,dom监听
init(el, { value: binding });
} else if (
type === "attributes" &&
target === waterMarkEl &&
currStyle !== style
) {
waterMarkEl.setAttribute("style", style);
}
}
});
observer.observe(el.parentElement, {
childList: true,
attributes: true,
subtree: true,
});
};
// 初始化
const init = (el, binding) => {
// 设置水印
setWaterMark(el, binding.value);
// 启动监控
createObserver(el, binding.value);
};
// 定义指令配置项
const directives = {
inserted(el, binding) {
init(el, binding);
},
};
export default {
name: "watermark",
directives,
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# 使用
# 1、引入
main.js
import waterMark from './directives/waterMark.js'
Vue.directive('watermark', waterMark.directives)
1
2
3
2
3
# 2、使用
<div id="app" v-watermark="{ text: '绝密资料,请勿外传' }">
<router-view />
</div>
1
2
3
2
3
// 禁止打开控制台
const prohibitOpenConsole = () => {
// 阻止f12调试、window ctr + shift + i 、 mac option + command + i
document.addEventListener('keydown', (e) => {
if (e.key === 'F12' || (e.ctrlKey && e.shiftKey && e.key === 'i') || (e.metaKey && e.altKey && e.key === 'i')) {
e.preventDefault()
// IE
e.returnValue = false
}
})
// 阻止菜单右键
document.addEventListener('contextmenu', (e) => {
e.preventDefault()
e.returnValue = false
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
最近更新时间: 2023/07/17 13:56:35
- 01
- 2023/07/17 13:57:35
- 02
- 2023/07/17 09:24:52
- 03
- 2023/07/14 16:02:42