基于Vue3水印组件封装:防篡改守护!

news/2024/11/20 1:38:10/文章来源:https://www.cnblogs.com/zhangapple/p/18197240

基于Vue 3的全新水印通用组件。这款组件不仅功能强大,而且易于集成,能够轻松为您的网页或应用添加自定义水印,有效防止内容被篡改或盗用。

在线查看效果: 原文可查看效果地址

一,编写watermark组件

<template><div ref="watermarkContainerRef" class="watermark-container"><!--  插槽--><slot></slot></div>
</template><script setup>
import { ref, onMounted, watchEffect, onUnmounted, computed } from "vue";
// 使用 defineProps 定义一个组件的 props,这些 props 描述了组件从父组件接收的属性
const props = defineProps({// 文本内容,类型为字符串,必须提供,默认值为'张苹果博客'text: {type: String,required: true,default: '张苹果博客'},// 字体大小,类型为数字,默认值为10fontSize: {type: Number,default: 10,},// 间距,类型为数字,默认值为1gap: {type: Number,default: 1,},// 颜色,类型为字符串,默认值为'rgba(82,75,75,0.58)'color: {type: String,default: 'rgba(82,75,75,0.58)',}
});// 定义一个用于绘制水印的函数,这里可以封装一下单独引入。
// 它是一个计算属性,意味着它的值会根据其依赖的 props 的变化而自动重新计算
const waterMarkBg = (props) => {return computed(() => {// 创建一个新的 canvas 元素const canvas = document.createElement("canvas");// 获取设备的像素比,如果未定义则默认为1const devicePixelRatio = window.devicePixelRatio || 1;// 根据像素比计算字体大小const fontSize = props.fontSize * devicePixelRatio;// 设置字体样式const font = fontSize + "px serif";// 获取 canvas 的 2D 渲染上下文const ctx = canvas.getContext("2d");// 设置字体ctx.font = font;// 测量文本的宽度const { width } = ctx.measureText(props.text);// 计算 canvas 的大小,至少为 60,并根据文本宽度和间距因子进行调整const canvasSize = Math.max(60, width) * props.gap + devicePixelRatio;// 设置 canvas 的宽高canvas.width = canvasSize;canvas.height = canvasSize;// 将 canvas 的原点移动到中心ctx.translate(canvas.width / 2, canvas.height / 2);// 旋转 canvas 45 度ctx.rotate((Math.PI / 180) * -45);// 设置填充颜色ctx.fillStyle = props.color;// 设置文本对齐方式和基线ctx.textAlign = "center";ctx.textBaseline = "middle";// 再次设置字体ctx.font = font;// 在 canvas 上填充文本ctx.fillText(props.text, 0, 0);// 返回一个对象,包含 base64 编码的图片数据、canvas 的大小和样式尺寸return {base64: canvas.toDataURL(),size: canvasSize,styleSize: canvasSize / devicePixelRatio};});
};// 用于存储 MutationObserver 的变量
let ob;
// 用于存储水印 div 的变量
let div;
// 调用 waterMarkBg 函数获取水印相关的计算属性
const bg = waterMarkBg(props);
// 创建一个 ref 用于存储水印容器的 DOM 引用
const watermarkContainerRef = ref('');
// 创建一个 ref 用于标记水印是否需要重新生成
const flag = ref(0);// 在组件挂载后执行
onMounted(() => {// 创建一个新的 MutationObserver,用于监听水印容器的变化ob = new MutationObserver((records) => {// 遍历所有的变化记录for (const record of records) {// 遍历所有被移除的节点for (const dom of record.removedNodes) {// 如果被移除的节点是水印 div,则更新 flag 的值并返回if (dom === div) {flag.value++;return;}}// 如果变化的节点就是水印 div,则更新 flag 的值并返回if (record.target === div) {flag.value++;return;}}});// 包括子节点的变化、属性的变化以及子树的变化ob.observe(watermarkContainerRef.value,{childList:true,attributes:true,subtree:true});
})//卸载
onUnmounted(()=>{ob && ob.disconnect();div=null;
})// 生成水印
watchEffect(() => {// 触发 watchEffect 的重新执行flag.value;// 如果水印容器没有值,则直接返回,不执行后续操作if (!watermarkContainerRef.value) {return;}// 如果之前已经存在水印 div,则先移除它if (div) {div.remove();}// 创建一个新的 div 元素用于作为水印的容器div = document.createElement('div');// 从计算属性 bg 中获取 base64 编码的图片数据和样式尺寸const { base64, styleSize } = bg.value;// 设置 div 的背景图片为水印图片的 base64 编码div.style.backgroundImage = `url(${base64})`;// 设置背景图片的尺寸div.style.backgroundSize = `${styleSize}px ${styleSize}px`;// 设置背景图片重复显示div.style.backgroundRepeat = "repeat";// 设置水印 div 的 z-index 为 9999,以确保它显示在大多数其他元素之上div.style.zIndex = 9999;// 设置水印 div 不响应鼠标事件,如点击、悬停等div.style.pointerEvents = "none";// 设置水印 div 的位置为绝对定位div.style.position = "absolute";// 使用 inset 属性设置 div 占据整个父容器的空间div.style.inset = "0";// 将水印 div 添加到水印容器中watermarkContainerRef.value.appendChild(div);
});</script><style scoped>
.watermark-container{position: relative;
}</style>

二,在页面中引入使用

<template><div><n-grid><n-gi style="margin: 15px"   span="6 1025:2  "  v-for="(item,index) in 4" :key="index">
<!--       引入 Watermark--><Watermark :gap="gap" :text="text" :fontSize="fontSize" :color="color"><n-cardv-motion-pop-visible-oncetitle="标题"hoverable>这是内容 <br>这是内容 <br>这是内容 <br>这是内容 <br>这是内容 <br>这是内容 <br></n-card></Watermark></n-gi></n-grid></div>
</template><script setup>
import Watermark from '../components/Watermark.vue'
import {ref} from "vue";
const text=ref('张苹果博客');
const gap=ref(1);
const fontSize=ref('10');
const color=ref('');
</script><style scoped></style>

三,效果图

水印效果图

更多信息请访问:张苹果博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/707622.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在线Base64转文件、文件转Base64工具

在线Base64转换神器,一键实现Base64编码与文件互转!支持图片、文档等各类文件,快速准确,安全无服务器存储。拖拽上传,轻松编码解码,提升开发效率。跨平台兼容,移动端友好,让数据转换再无障碍。在线Base64转文件、文件转Base64工具

怎样统一、高效地实现百台以上的机台设备文件导出?

许多高端制造企业的运转都以机台为基础,如光学仪器制造及研究,晶圆制造,医学设备等,而大型的高端制造业不仅配备机台设备,同时数量也会非常客观,会达到上百台,当企业扩充规模,设立分公司和厂区时,机台设备甚至可达上千台,此时,对于企业而言,机台设备文件导出就会变…

Docker 部署Nacos

1、创建Nacos目录 mkdir /home/docker/nacos2、创建Nacos日志目录 mkdir /home/docker/nacos/logs3、创建Nacos配置目录 mkdir /home/docker/nacos/conf4、创建数据库 /** Copyright 1999-2018 Alibaba Group Holding Ltd.** Licensed under the Apache License, Version 2.0 (…

Python数据分析与挖掘实战(1-3章)

非原创,仅个人关于《Python数据分析与挖掘实战》的学习笔记第一章 基础 略 第二章 数据分析简介 基本概念 元组、列表、字典、集合 函数式编程:map()函数:定义一个函数,然后用map()逐一应用到map列表中的每个元素。map(lambda x+2:a) reduce()函数:用于递归计算。reduce(l…

ASP.NET Core Web中使用AutoMapper进行对象映射

前言 在日常开发中,我们常常需要将一个对象映射到另一个对象,这个过程中可能需要编写大量的重复性代码,如果每次都手动编写,不仅会影响开发效率,而且当项目越来越复杂、庞大的时候还容易出现错误。为了解决这个问题,对象映射库就随之而出了,这些库可以自动完成对象之间的…

Socket层

【一】什么是socketSocket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面 对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。所以,我们无需深…

金融系统数据同步方案哪家最强,了解一下!

金融系统数据同步是金融行业信息化和数据化发展的关键组成部分,它对于保障数据安全、提升系统性能和满足日益增长的数据时效性要求至关重要。以下是一些金融系统中数据同步的关键应用场景和需求:1、多数据中心操作:金融机构通常在多个数据中心运行,需要确保数据在这些中心之…

Dapr 与 .NET Aspire 结合使用获得无与伦比的本地开发体验

Dapr 提供了一组构建块,用于抽象分布式系统中常用的概念。这包括服务、缓存、工作流、复原能力、机密管理等之间的安全同步和异步通信。不必自己实现这些功能,可以消除样板,降低复杂性,并允许您专注于开发业务功能。在您的时间有限并且您只想进行实验的情况下,在Dapr初始设…

网络架构和网络通信

【一】常见的网络架构模式 【1】CS模型C是英文单词“Client”的首字母,即客户端的意思 C/S就是“Client/Server”的缩写,即“客户端/服务器”模式。例如:拼多多APP、PC上的有道云笔记等等【2】BS模型B是英文单词“Browser”的首字母,即浏览器的意思; S是英文单词“Server”…

记录仪测评 记录仪测评设置4k结果1080

设置4K 实际效果1080不到记录仪测评设置4k结果1080 https://baijiahao.baidu.com/builder/preview/s?id=1799258600924107729 LOK00018.AVI音频编码信息ID : 1格式 : PCM格式参数设置, Endianness : Little格式参数设置, Sign : Signed编解码器ID : 1编解码器ID/Hint : Micros…

mpdf增加字体并进行使用

1、先将字体复制到目录:\vendor\mpdf\mpdf\ttfonts2、再修改文件\vendor\mpdf\mpdf\src\Config\FontVariables.php,对照已经添加的simsun,simkai,simhei,fangzhenweibei,fangzhenheiti等字体进行增加即可。3、再在需要设置字体的文字加上font-family:fangzhenweibei;样式…

初识上位机(下):C#读写PLC数据块数据

作为一个工业自动化领域的程序员,不懂点PLC和上位机,貌似有点说不过去。这里我用两篇小文带你快速进入上位机开发领域。上一篇,我们搭建了一个PLC的模拟仿真环境,本篇我们使用C#开发一个简单的PLC数据读取和写入的应用程序。大家好,我是Edison。 作为一个工业自动化领域的…