当前位置:首页 > VUE

vue实现水印组件

2026-01-15 04:51:51VUE

Vue 水印组件的实现方法

使用Canvas绘制水印

在Vue组件中通过Canvas动态生成水印图案,将其作为背景添加到目标元素上。

<template>
  <div ref="watermarkContainer" class="watermark-container"></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.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.translate(canvas.width / 2, canvas.height / 2)
      ctx.rotate((this.angle * Math.PI) / 180)
      ctx.fillText(this.text, 0, 0)

      const dataURL = canvas.toDataURL()
      this.$refs.watermarkContainer.style.backgroundImage = `url(${dataURL})`
      this.$refs.watermarkContainer.style.backgroundRepeat = 'repeat'
    }
  }
}
</script>

<style>
.watermark-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 9999;
}
</style>

使用SVG实现水印

SVG方案更轻量且支持矢量缩放,适合需要清晰显示的场景。

<template>
  <div 
    class="svg-watermark"
    :style="{
      'background-image': `url('data:image/svg+xml;utf8,${svgWatermark}')`
    }"
  ></div>
</template>

<script>
export default {
  props: {
    text: { type: String, default: 'Confidential' },
    opacity: { type: Number, default: 0.1 }
  },
  computed: {
    svgWatermark() {
      return encodeURIComponent(
        `<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100">
          <text x="50%" y="50%" 
            font-family="Arial" 
            font-size="16" 
            fill-opacity="${this.opacity}" 
            fill="#000" 
            text-anchor="middle" 
            dominant-baseline="middle" 
            transform="rotate(-20 100 50)">
            ${this.text}
          </text>
        </svg>`
      )
    }
  }
}
</script>

防止水印被删除

通过MutationObserver监测DOM变化,当水印被移除时自动重新添加。

mounted() {
  this.generateWatermark()
  this.setupObserver()
},
methods: {
  setupObserver() {
    const targetNode = this.$refs.watermarkContainer.parentElement
    const config = { childList: true, subtree: true }
    const callback = (mutationsList) => {
      for(const mutation of mutationsList) {
        if (!document.body.contains(this.$refs.watermarkContainer)) {
          document.body.appendChild(this.$refs.watermarkContainer)
        }
      }
    }
    this.observer = new MutationObserver(callback)
    this.observer.observe(targetNode, config)
  },
  beforeDestroy() {
    this.observer?.disconnect()
  }
}

响应式水印方案

结合CSS变量和Vue响应式特性,实现动态调整水印参数。

<template>
  <div 
    :style="{
      '--watermark-content': `'${text}'`,
      '--watermark-color': color,
      '--watermark-opacity': opacity,
      '--watermark-size': `${fontSize}px`
    }"
    class="css-watermark"
  ></div>
</template>

<style>
.css-watermark {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    -45deg,
    transparent,
    transparent 25px,
    rgba(0, 0, 0, var(--watermark-opacity)) 25px,
    rgba(0, 0, 0, var(--watermark-opacity)) 50px
  );
}

.css-watermark::after {
  content: var(--watermark-content);
  position: absolute;
  font-size: var(--watermark-size);
  color: var(--watermark-color);
  opacity: var(--watermark-opacity);
  transform: rotate(-20deg);
}
</style>

服务端生成水印

对于敏感内容,建议结合后端服务生成带水印的图片。

vue实现水印组件

async getProtectedImage(url) {
  const response = await axios.get('/api/watermark', {
    params: {
      imageUrl: url,
      text: this.watermarkText
    },
    responseType: 'blob'
  })
  return URL.createObjectURL(response.data)
}

以上方案可根据实际需求选择或组合使用,Canvas方案适合复杂水印效果,SVG方案性能更优,CSS方案最简单但功能有限。为防止用户篡改,建议配合MutationObserver和防调试策略。

标签: 水印组件
分享给朋友:

相关文章

vue实现下拉刷新组件

vue实现下拉刷新组件

Vue 下拉刷新组件实现 核心思路 通过监听 touch 事件计算滑动距离,结合 CSS 过渡动画实现下拉效果,触发刷新回调。 基础实现步骤 监听 touch 事件 在组件 mounted 阶段绑定…

如何缓存react组件

如何缓存react组件

缓存React组件的方法 React.memo 使用React.memo对函数组件进行浅比较缓存,避免不必要的重新渲染。适用于props不变的场景。 const MemoizedComponen…

vue实现递归组件

vue实现递归组件

递归组件的实现方法 在Vue中实现递归组件主要依靠组件调用自身的能力。以下是几种常见的实现方式: 使用组件name属性 通过组件的name属性实现递归调用是最简单的方式: <template…

vue实现盖章组件

vue实现盖章组件

实现Vue盖章组件的步骤 组件结构设计 创建一个Vue组件,包含画布元素和必要的控制按钮。画布用于显示盖章效果,按钮用于触发盖章操作。组件需要接收图片和盖章位置等参数。 <template&g…

vue 实现弹窗组件

vue 实现弹窗组件

Vue 弹窗组件实现 基础弹窗组件结构 创建一个名为Modal.vue的文件,定义弹窗的基础结构和样式: <template> <div class="modal-mask"…

vue 实现通用组件

vue 实现通用组件

Vue 实现通用组件的方法 封装可复用的组件 将通用功能抽象为独立组件,通过props接收外部数据,通过events与父组件通信。例如封装按钮、输入框、弹窗等基础组件。 使用插槽增强灵活性 通过默认…