Umi微前端水印踩坑以及解决方案

news2024/11/17 23:55:56

最近公司需要在管理后台加一个水印方案~ 项目用的umi方案,以为就是改一个配置的问题,后来发现坑点还蛮多~ 希望此稳定能帮助到用umi 的你们.

一. 先来说说心路历程

坑点1

umi的水印适配只能在layout中进行配置,也就是路由配置中layout为false的页面无法配置水印,比如说登录页~
在这里插入图片描述

坑点2

就算只对layout配置也会有问题,如下是配置与效果
请添加图片描述
可以看到头部区域,菜单区域以及空白区域适配不到.
请添加图片描述

坑点3

既然配置不好处理,而umi用的是react的ant组件,那是不是可以用ant的水印组件Watermark去包裹根组件达到效果呢?
想法是好的. 实际情况是umi的app.tsx只是一个配置文件,它并没有暴露根组件,也就是说我们只能用原生js拿到根节点~ 但就算拿到根节点,你又如何去适配Watermark组件呢? 原生与jsx如何进行写法上的兼容?
请添加图片描述

坑点4

因为以上诸多不便,我不得不尝试寻找其它可替代方案. 比如去github上寻找原生相关的水印方案库~ 反复查找下锁定了一个start比较多的开源水印库:watermark-dom
这个库的优点是简单易用,对水印有保护策略的加持; 缺点是最新版本更新与2019年,对ts的兼容性不是很好,水印内容只能文本不能是图片,且适配不是很好,不能随着内容变化而变化,还会出现滚动条等问题~
所以这个库我们只能作为备选方案…

心路总结

基于以上心路,最后决定还是回到坑点3,尝试手动适配

二. 核心解决思路

  1. 通过react18的createRoot,render出水印组件对应的dom
  2. 通过MutationObserver监听dom的变化,并在异步回调中做处理
  3. 拿到水印dom之后将其append到masteroot根节点之中
  4. 存储水印文案,判断是否变化.
  5. 变化了的话重复1步骤render创建水印,删除旧的水印,append新的水印dom
  6. 最后通过observer.disconnect()注销监听

三. 实现代码

如下是我的最终调试代码,在app.tsx文件中调用即可

import { Watermark } from 'antd';
import { createRoot } from 'react-dom/client';
let oldval: string = '';
const creatWatermark = (content: string) => {
  console.log(oldval, content);
  if (oldval && oldval === content) return;
  const opt = {
    content: content,
    fontColor: 'red',
    fontStyle: 'normal',
    fontSize: 23,
    gapX: [30, 30],
    rotate: 10,
  };
  oldval = content;
  // 选择需要观察变动的节点
  const targetNode = document.createElement('div');
  // 解析AST&挂载(是异步,所以后续需要监听节点变化再做处理)
  createRoot(targetNode).render(<Watermark {...opt} />);
  // 观察器的配置(需要观察什么变动, childList只能向下观察到一级, subtree可多级 )
  const config = { childList: true, subtree: true };
  // 当观察到变动时执行的回调函数
  const callback = (
    mutationsList: MutationRecord[],
    observer: MutationObserver,
  ) => {
    for (let mutation of mutationsList) {
      if (mutation.type === 'childList') {
        const rootMaster = document.getElementById(
          'root-master',
        ) as HTMLElement;
        const newDom = targetNode?.childNodes[0]?.childNodes[0] as HTMLElement;
        if (newDom) {
          document.getElementById('watermark')?.remove();
          newDom.id = 'watermark';
          rootMaster.appendChild(newDom);
          observer.disconnect(); // 注销
        }
      }
    }
  };
  // 创建一个观察器实例并传入回调函数 MutationObserver的回调是微任务
  const observer = new MutationObserver(callback);
  // 以上述配置开始观察目标节点
  observer.observe(targetNode, config);
  // 方案二: 用动画帧刷新也可以(弃用)
  // const getFormRefLoop = () => {
  //   window.requestAnimationFrame(() => {
  //     const rootMaster = document.getElementById('root-master') as HTMLElement;
  //     const w = root?.childNodes[0]?.childNodes[0] as HTMLElement;
  //     if (rootMaster && w) {
  //       const old = document.getElementById('root');
  //       if (old) old.remove();
  //       w.id = 'root';
  //       rootMaster.appendChild(w);
  //     } else {
  //       getFormRefLoop();
  //     }
  //   });
  // };
  // getFormRefLoop();
};

export default creatWatermark;

小结

demo地址
原创不易,转载请注明来源. 如果对你有帮助,收藏关注加点赞哦😝 当然如果大家有更好的解决方案,欢迎评论哦

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SCS【27】单细胞转录组之识别标记基因 (scran)

桓峰基因公众号推出单细胞生信分析教程并配有视频在线教程&#xff0c;目前整理出来的相关教程目录如下&#xff1a; Topic 6. 克隆进化之 Canopy Topic 7. 克隆进化之 Cardelino Topic 8. 克隆进化之 RobustClone SCS【1】今天开启单细胞之旅&#xff0c;述说单细胞测序的前世…

规则引擎架构-基于easy-rules

目录 概念理解实例和编码抽象出2条规则简单的规则引擎事实1的处理事实2的处理 easy-rules 规则的抽象和执行事实描述规则的抽象默认的规则 动态代理执行规则和动作规则的执行&#xff1a;org.jeasy.rules.core.DefaultRulesEngine#doFirepublic class RuleProxy implements Inv…

Java上进了,JDK21 要来了,并发编程再也不是噩梦了

更丝滑的并发编程模式 如果说之前的 JDK17你还觉得没必要折腾&#xff0c;那 JDK21确实有必要关注一下了。因为 JDK21 引入了一种新型的并发编程模式。 当前 Java 中的多线程并发编程绝对是另我们都非常头疼的一部分&#xff0c;感觉就是学起来难啃&#xff0c;用起来难用。但…

基础篇010.3 STM32驱动RC522 RFID模块之三:STM32软件模拟SPI驱动RC522

目录 1. 实验硬件及原理图 2. 利用STM32CubeMX创建MDK工程 2.1 STM32CubeMX工程创建 2.2 配置调试方式 2.3 配置时钟电路 2.4 配置时钟 2.5 配置GPIO 2.6 配置串口 2.7 项目配置 3. MDK工程驱动代码调试 3.1 按键、LED程序 3.2 SPI软件模拟程序 3.3 RC522驱动程序…

Unity制作二次元卡通渲染角色材质——1、资源分析

Unity制作二次元材质角色 回到目录 大家好&#xff0c;我是阿赵。 开始制作二次元角色材质之前&#xff0c;我觉得应该是先分析一下&#xff0c;我手上拿到的这个角色模型资源&#xff0c;总共有哪些信息是我们能用的。 所以这篇文章我不会分享具体的Shader&#xff0c;但我感觉…

基于RT-Thread快速上手SD NAND 虚拟文件系统

SD NAND 也称之为贴片式TF卡&#xff0c;贴片式SD卡&#xff0c;采用标准的SDIO接口&#xff0c;兼容SPI接口。下图所示为CS 新一代CS SD NAND NP1GCR01-AOW 大小为128M&#xff0c;对比128M的SD卡&#xff0c;可以看到贴片SD卡尺寸更小&#xff0c;不要SD卡座&#xff0c;占…

STM32杂乱笔记

问题都比较的基础和低级&#xff0c;仅记录一下。 问题一&#xff1a;stm32的某个.c文件中无法调用另一个.c中的指定变量&#xff0c;怎么解决&#xff1f; 以g_ADC_sample_vaule.Iu 为例&#xff0c;它是 drive_adc_info.c 里面的变量&#xff0c;想要在system_time_sequenc…

5.4 二叉树的性质和存储结构

博主简介&#xff1a;一个爱打游戏的计算机专业学生博主主页&#xff1a; 夏驰和徐策所属专栏&#xff1a;算法设计与分析 5.4.1 二叉树的性质 二叉树是一种特殊的树结构&#xff0c;它具有一些重要的性质&#xff1a; 1. 每个节点最多有两个子节点&#xff1a;二叉树的每个…

JavaScript:setInterval() 用法详解

文章目录 1 基本语法2 参数说明3 使用示例4 停止 setInterval() 方法 1 基本语法 setInterval() 是 JavaScript 中的一个内置函数&#xff0c;它用于在指定的间隔时间内重复执行一段代码&#xff0c;实现周期性操作。该函数的语法如下&#xff1a; setInterval(function, mil…

线程(Linux系统实现)

目录 1. 线程概述 2.主线程和子线程 3.创建线程 线程函数 创建线程示例 4.线程退出 线程退出的原理主要包括以下两个方面&#xff1a; 5.线程回收 回收子线程数据 6.线程分离 7.线程取消 8.线程 ID 比较 1. 线程概述 线程是轻量级的进程&#xff08;LWP&#xff…

【Java多线程进阶】常见的锁策略

前言 众所周知&#xff0c;拳击运动员是要分等级&#xff08;轻量级、重量级等等&#xff09;来参加比赛的&#xff0c;在 Java 多线程中 锁&#xff08;synchronized&#xff09; 也会根据锁的竞争程度来升级为相关“高等级”锁&#xff0c;为了更好的理解 synchronized 加锁机…

微信小程序node+vue医院挂号预约系统fun17

从而实现管理员后端&#xff1b;首页、个人中心、用户管理、专家管理、科室类型管理、职称类型管理、医院挂号管理、挂号信息管理、留言板管理、系统管理&#xff0c;专家后端&#xff1b;首页、个人中心、医院挂号管理、挂号信息管理、系统管理&#xff0c;用户前端&#xff1…

【Linux】网络基础+UDP网络套接字编程

只做自己喜欢做的事情&#xff0c;不被社会和时代裹挟着前进&#xff0c;是一件很奢侈的事。 文章目录 一、 网络基础1.局域网和广域网2.协议初识和网络协议分层&#xff08;TCP/IP四层模型&#xff09;3.MAC地址和IP地址&#xff08;子网掩码&#xff0c;路由表&#xff0c;I…

美国金融科技公司SoFi的增长难以持久,股价也将下跌

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 公司介绍 SoFi Technologies(SoFi)是一家来自美国的知名金融科技公司&#xff0c;自2011年成立以来&#xff0c;已成为领先的个人理财在线平台。SoFi为年轻的高收入客户提供多样化的产品和服务&#xff0c;包括学生和汽车贷…

如何在 Python 中使用断点调试

入门教程、案例源码、学习资料、读者群 请访问&#xff1a; python666.cn 实际上没人能一次就写出完美的代码&#xff0c;除了我。但是世界上只有一个我。 林纳斯托瓦兹&#xff08;Linux 之父&#xff09; 大家好&#xff0c;欢迎来到 Crossin的编程教室 &#xff01; 上面这段…

【CSS3系列】第二章 · CSS3 新增盒模型和背景属性

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

大数据:数据表操作,分区表,分桶表,修改表,array,map, struct

大数据&#xff1a;数据表操作&#xff0c;分区表 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&a…

【能量算子】评估 EEG 中的瞬时能量:非负、频率加权能量算子(PythonMatlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

五种方法提升Midjourney的出图品质

本文基于B站UP主琥珀川Eric的《五种方法提升Midjourney出图品质》制作在此感谢大神的分享。 本文全面介绍以上五种提升Midjourney出图品质的方法&#xff0c;简单实用&#xff0c;马上就可以用上。Lets go&#xff01;&#xff01;&#xff01; 方法一 使用相机参数创建逼真的图…

windows系统编译的Qt程序转到国产化麒麟linux中编译

团队自研股票软件&#xff0c;关威信共总号&#xff1a;QStockView&#xff0c;下载 1.1 windows系统编译的Qt程序转到国产化麒麟linux中编译 &#xff08;1&#xff09;把Vs工程项目文件导入到Linux中 首先把vs的工程拷贝到linux里面&#xff08;可以用虚拟机的共享文件夹…