Vue 3全屏水印需用Canvas+MutationObserver实现:Canvas按设备像素比绘制文字转Base64背景图,fixed定位覆盖全屏且pointer-events:none,MutationObserver监听并自动恢复,支持响应式文本、暗色模式适配及组合式Hook封装。

Vue 3 项目配置全屏水印,关键不是加个 div 就完事,而是要兼顾防删除、自适应、低干扰和暗色模式兼容。纯 CSS 方案容易被开发者工具删掉,真正有效的方案得靠 Canvas + MutationObserver + 响应式注入。
用 Canvas 动态生成水印图
避免使用静态图片或纯文字 DOM 节点,改用 Canvas 绘制文字并转为 Base64 背景图:
- 创建 canvas 元素,按设备像素比(window.devicePixelRatio)缩放画布尺寸,防止高清屏模糊
- 设置字体、颜色、透明度、旋转角度(常见 -15° ~ -30°),用 ctx.fillText() 绘制文本
- 调用 canvas.toDataURL('image/png') 得到 base64 字符串,作为背景图源
- 将该 base64 图设为固定定位 div 的 background-image,配合 background-repeat: repeat
注入到 body 并防手动删除
水印容器必须挂载在 document.body 最顶层,且具备自动恢复能力:
- 用 position: fixed; top: 0; left: 0; width: 100%; height: 100% 覆盖全屏
- 设置 z-index: 9999 和 pointer-events: none,确保不拦截页面交互
- 用 MutationObserver 监听 body 子节点变动,一旦发现水印容器被移除,立即重建并 append 回去
- 避免 reload 页面——粗暴刷新影响体验,实时重建更专业
支持动态内容与主题适配
水印内容常含用户信息(如工号、姓名),且需适配深色/浅色模式:
立即学习“前端免费学习笔记(深入)”;
- 把水印文本设为响应式 prop(例如 text: computed(() => userInfo.name)),配合 watchEffect 自动重绘
- 监听 html 元素的 class 变化(如是否含 dark),动态切换水印颜色:浅色模式用 rgba(0,0,0,0.12),深色模式用 rgba(255,255,255,0.1)
- 字体大小、间距、旋转角度全部参数化,便于统一管理或运行时调整
推荐封装方式:组合式 Hook
不建议全局挂载或每个页面手动引入,用 useWatermark() Hook 更工程化:
- 接收 text、rotate、gap、color 等配置项
- 内部自动处理 canvas 渲染、DOM 注入、resize 响应、MutationObserver 监听
- 暴露 setWatermark() 和 clear() 方法,便于登录后动态加载、登出后清除
- 在 main.ts 或权限守卫中统一调用,例如:useWatermark().setWatermark({ text: userStore.fullName })


















