vue实现水印组件
Vue 水印组件实现方法
基于 Canvas 绘制水印
通过 Canvas 动态生成水印背景图,可自定义文本、颜色、透明度等参数。
<template>
<div class="watermark-container" ref="watermarkRef"></div>
</template>
<script>
export default {
props: {
text: { type: String, default: 'Watermark' },
fontSize: { type: Number, default: 16 },
color: { type: String, default: 'rgba(0, 0, 0, 0.1)' },
angle: { type: Number, default: -20 }
},
mounted() {
this.generateWatermark()
},
methods: {
generateWatermark() {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = 200
canvas.height = 150
ctx.font = `${this.fontSize}px Arial`
ctx.fillStyle = this.color
ctx.rotate(Math.PI / 180 * this.angle)
ctx.fillText(this.text, 10, 80)
const watermarkUrl = canvas.toDataURL('image/png')
this.$refs.watermarkRef.style.backgroundImage = `url(${watermarkUrl})`
}
}
}
</script>
<style>
.watermark-container {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
pointer-events: none;
background-repeat: repeat;
z-index: 9999;
}
</style>
使用 SVG 实现水印
SVG 方案更适合需要矢量缩放的水印场景,支持更复杂的图形和样式。
<template>
<div class="svg-watermark" v-html="watermarkSvg"></div>
</template>
<script>
export default {
props: {
text: { type: String, default: 'Confidential' },
opacity: { type: Number, default: 0.2 }
},
computed: {
watermarkSvg() {
return `
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<text x="50%" y="50%"
fill="gray"
opacity="${this.opacity}"
font-family="Arial"
font-size="20"
transform="rotate(-30 100 100)"
text-anchor="middle">
${this.text}
</text>
</svg>
`
}
}
}
</script>
<style>
.svg-watermark {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 9999;
}
</style>
防删除水印方案
通过 MutationObserver 监控 DOM 变化,防止水印被意外删除。
export default {
// ...其他代码同Canvas方案
mounted() {
this.generateWatermark()
this.setupObserver()
},
methods: {
setupObserver() {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (!document.body.contains(this.$refs.watermarkRef)) {
document.body.appendChild(this.$refs.watermarkRef)
}
})
})
observer.observe(document.body, {
childList: true,
subtree: true
})
}
}
}
全局指令实现方案
创建 Vue 指令实现水印功能,可在任意元素上使用。
const watermarkDirective = {
inserted(el, binding) {
const { text, color = 'rgba(0,0,0,0.1)' } = binding.value
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = 200
canvas.height = 100
ctx.font = '16px Arial'
ctx.fillStyle = color
ctx.rotate(-0.3)
ctx.fillText(text, 10, 70)
el.style.backgroundImage = `url(${canvas.toDataURL()})`
el.style.backgroundRepeat = 'repeat'
}
}
// 全局注册
Vue.directive('watermark', watermarkDirective)
// 使用方式
// <div v-watermark="{ text: 'Secret', color: 'rgba(255,0,0,0.2)' }"></div>
响应式水印调整
监听窗口变化自动调整水印密度和大小。
export default {
// ...其他代码
data() {
return {
resizeObserver: null
}
},
mounted() {
this.generateWatermark()
this.setupResizeObserver()
},
beforeDestroy() {
this.resizeObserver.disconnect()
},
methods: {
setupResizeObserver() {
this.resizeObserver = new ResizeObserver(() => {
this.generateWatermark()
})
this.resizeObserver.observe(this.$refs.watermarkRef)
}
}
}
以上方案可根据实际需求选择或组合使用,Canvas 方案适合简单文本水印,SVG 方案支持更复杂的图形,指令方式提供更好的复用性,防删除方案增强安全性。







