vue实现水印组件
Vue 水印组件实现
基础水印组件实现
创建一个基础水印组件,通过 props 接收文本、颜色、大小等参数:
<template>
<div class="watermark-container">
<slot></slot>
<div class="watermark" :style="watermarkStyle"></div>
</div>
</template>
<script>
export default {
props: {
text: {
type: String,
default: 'Watermark'
},
color: {
type: String,
default: 'rgba(0, 0, 0, 0.1)'
},
fontSize: {
type: Number,
default: 16
},
rotate: {
type: Number,
default: -30
}
},
computed: {
watermarkStyle() {
return {
backgroundImage: `url("${this.generateWatermark()}")`,
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
pointerEvents: 'none',
zIndex: 9999
}
}
},
methods: {
generateWatermark() {
const canvas = document.createElement('canvas')
canvas.width = 200
canvas.height = 150
const ctx = canvas.getContext('2d')
ctx.font = `${this.fontSize}px Arial`
ctx.fillStyle = this.color
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.translate(100, 75)
ctx.rotate((Math.PI / 180) * this.rotate)
ctx.fillText(this.text, 0, 0)
return canvas.toDataURL()
}
}
}
</script>
<style scoped>
.watermark-container {
position: relative;
}
</style>
防止水印被删除
添加MutationObserver监听DOM变化,防止水印被删除:
mounted() {
this.observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.removedNodes.forEach((node) => {
if (node === this.$el.querySelector('.watermark')) {
this.$el.appendChild(this.createWatermark())
}
})
})
})
this.observer.observe(this.$el, {
childList: true
})
},
beforeDestroy() {
this.observer.disconnect()
},
methods: {
createWatermark() {
const watermark = document.createElement('div')
watermark.className = 'watermark'
watermark.style = this.watermarkStyle
return watermark
}
}
多行水印实现
修改generateWatermark方法支持多行水印:
generateWatermark() {
const canvas = document.createElement('canvas')
canvas.width = 400
canvas.height = 300
const ctx = canvas.getContext('2d')
ctx.font = `${this.fontSize}px Arial`
ctx.fillStyle = this.color
ctx.textAlign = 'center'
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
ctx.save()
ctx.translate(i * 150, j * 100)
ctx.rotate((Math.PI / 180) * this.rotate)
ctx.fillText(this.text, 0, 0)
ctx.restore()
}
}
return canvas.toDataURL()
}
使用示例
在父组件中使用水印组件:
<template>
<Watermark text="Confidential" color="rgba(0, 0, 0, 0.2)" :fontSize="20">
<div class="content">
<!-- 你的内容 -->
</div>
</Watermark>
</template>
<script>
import Watermark from './Watermark.vue'
export default {
components: {
Watermark
}
}
</script>
动态更新水印
添加watch监听props变化,动态更新水印:
watch: {
text() {
this.updateWatermark()
},
color() {
this.updateWatermark()
},
fontSize() {
this.updateWatermark()
},
rotate() {
this.updateWatermark()
}
},
methods: {
updateWatermark() {
const watermark = this.$el.querySelector('.watermark')
if (watermark) {
watermark.style.backgroundImage = `url("${this.generateWatermark()}")`
}
}
}






