当前位置:首页 > VUE

vue实现水印组件

2026-01-08 17:02:23VUE

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变化,动态更新水印:

vue实现水印组件

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()}")`
    }
  }
}

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

相关文章

vue穿梭框组件实现

vue穿梭框组件实现

实现 Vue 穿梭框组件的基本思路 穿梭框(Transfer)组件通常用于在两个列表之间移动数据项。核心功能包括左侧列表、右侧列表、移动按钮(左移、右移、全选等)以及数据项的渲染与交互。 基础结构设…

vue实现穿梭框树组件

vue实现穿梭框树组件

Vue 穿梭框树组件实现 穿梭框树组件通常结合了树形结构和穿梭框功能,允许用户在左右两栏之间移动树节点数据。以下是基于 Vue 的实现方案: 核心功能设计 数据结构 树形数据通常采用嵌套结构,例如:…

uniapp组件写法

uniapp组件写法

Uniapp 组件的基本写法 Uniapp 的组件写法与 Vue 类似,支持单文件组件(.vue 文件)。一个基本的组件通常包含三个部分:<template>、<script>…

vue实现广告组件

vue实现广告组件

vue实现广告组件的方法 使用动态组件实现 在Vue中可以通过动态组件的方式加载广告组件,根据不同的条件展示不同的广告内容。动态组件使用<component :is="currentCompon…

vue实现折叠组件

vue实现折叠组件

实现折叠组件的基本思路 在Vue中实现折叠组件通常需要利用动态绑定和条件渲染。核心是通过控制一个布尔值状态来决定内容是否显示,并添加过渡动画提升用户体验。 基础实现方法 使用v-show或v-if控…

react组件如何通讯

react组件如何通讯

React 组件通讯方式 React 组件间的通讯方式主要包括以下几种方法,适用于不同场景下的数据传递和状态管理需求。 父子组件通讯(Props 传递) 父组件通过 props 向子组件传递数据或回…