文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue3 实现网页背景水印功能的示例代码

2022-11-13 14:28

关注

经常有一些公司和组织出于系统文件或信息安全保密的需要,需要在系统网页上增加带有个人标识(系统账号或个人信息)的水印,可以简单防止截图外传

首先我们来看这样一个水印功能的实现思路,通常是在我们原有的网页上附上一个 DIV 层,将它设置绝对定位铺满整个窗口,然后 z-index 值尽量往大了设,保证让水印层处于当前网页所有元素的上面,又不影响当前网页的操作。

水印上的字体有两种方式添加:

处于性能方面考虑,第二种方式最优。我们来看具体怎么实现?

作为一块独立的功能,我们在 Vue3 中常用 hooks 来实现,通过分析我们概括出实现水印需要的几个功能函数和对外接口:

对外接口

核心功能函数

export function useWatermark(
  appendEl: Ref<HTMLElement | null> = ref(document.body) as Ref<HTMLElement>
) {
   // 绘制文字背景图
  function createBase64() {}

  // 绘制水印层
  const createWatermark = () => {};

  // 页面随窗口调整更新水印
  function updateWatermark(){}

  // 对外提供的设置水印方法
  function setWatermark() {}

  // 清除水印
  const clear = () => {};

  return { setWatermark, clear };
}

有了代码框架,就只需要实现函数和接口的内部实现了,另外还要考虑传参,来实现代码复用的灵活度和接口参数的可配置。

我们从具体的功能函数开始:

绘制文字背景图

这里的参数 str 就是要添加的水印文字,attr 为文字样式的属性,我们定义了属性的类型为 attr,它包含文字的字体和大小以及颜色等值

function createBase64(str: string, attr?: attr) {
    const can = document.createElement("canvas");
    const width = 200;
    const height = 140;
    Object.assign(can, { width, height });

    const cans = can.getContext("2d");
    if (cans) {
      cans.rotate((-20 * Math.PI) / 120);
      cans.font = attr?.font ?? "12px Reggae One";
      cans.fillStyle = attr?.fillStyle ?? "rgba(0, 0, 0, 0.12)";
      cans.textAlign = "left";
      cans.textBaseline = "middle";
      cans.fillText(str, width / 20, height);
    }
    return can.toDataURL("image/png");
  }
type attr = {
  font?: string;
  fillStyle?: string;
};

绘制水印层

这个函数的主要逻辑是先判断如果已经绘制了水印层,直接调用更新水印方法,如果还没有,先动态创建一个 DIV 层,设置绝对定位,铺满当前整个浏览器窗口。

const id = domSymbol.toString();
const watermarkEl = shallowRef<HTMLElement>();
const createWatermark = (str: string, attr?: attr) => {
    if (unref(watermarkEl)) {
      updateWatermark({ str, attr });
      return id;
    }
    const div = document.createElement("div");
    watermarkEl.value = div;
    div.id = id;
    div.style.pointerEvents = "none";
    div.style.top = "0px";
    div.style.left = "0px";
    div.style.position = "absolute";
    div.style.zIndex = "100000";
    const el = unref(appendEl);
    if (!el) return id;
    const { clientHeight: height, clientWidth: width } = el;
    updateWatermark({ str, width, height, attr });
    el.appendChild(div);
    return id;
  };

更新水印

因为更新水印方法主要是根据当前窗口高度和宽度来的更新水印背景的设置,利用一张 Base64 格式的图片平铺即可。

function updateWatermark(
    options: {
      width?: number;
      height?: number;
      str?: string;
      attr?: attr;
    } = {}
  ) {
    const el = unref(watermarkEl);
    if (!el) return;
    if (options.width !== "undefined") {
      el.style.width = `${options.width}px`;
    }
    if (ioptions.height !== "undefined") {
      el.style.height = `${options.height}px`;
    }
    if (options.str !== "undefined") {
      el.style.background = `url(${createBase64(
        options.str,
        options.attr
      )}) left top repeat`;
    }
  }

到此,我们实现了主要的三个功能函数,下面就是两个对外接口:

设置水印

这里的主要点是考虑设置页面resize监听,来及时更新水印的位置。还要考虑 Vue 的生命周期,当我们卸载页面的时候要进行清除水印。

function setWatermark(str: string, attr?: attr) {
    createWatermark(str, attr);
    addResizeListener(document.documentElement, func);
    const instance = getCurrentInstance();
    if (instance) {
      onBeforeUnmount(() => {
        clear();
      });
    }
  }

  const func = throttle(function () {
    const el = unref(appendEl);
    if (!el) return;
    const { clientHeight: height, clientWidth: width } = el;
    updateWatermark({ height, width });
  });

清除水印

清除水印的时候顺便移除窗口大小监听函数

  const clear = () => {
    const domId = unref(watermarkEl);
    watermarkEl.value = undefined;
    const el = unref(appendEl);
    if (!el) return;
    domId && el.removeChild(domId);
    removeResizeListener(el, func);
  };

水印功能 hooks 的使用

import { useWatermark } from "/@/hooks/watermark";
const { setWatermark, clear } = useWatermark();
onMounted(() => {
  nextTick(() => {
    setWatermark(watermarkText.value);
  });
});

onBeforeUnmount(() => {
  clear();
});

至此,Vue3 版的网页水印功能实现全部完成。这里水印的字体大小、颜色和排布参考了企业微信的背景水印,使得看起来不那么突兀。

到此这篇关于Vue3 实现网页背景水印功能的文章就介绍到这了,更多相关vue网页水印内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯