NWatermark 水印
覆盖在页面内容上的防泄露水印层:文字与图片两种水印、单元格网格无限平铺、旋转角度与间距可调、深浅主题自动换色;支持局部覆盖(默认)与 fixed 全屏两种形态,水印层不拦截内容的任何交互。
平台兼容性
| App(ANDROID) | App(IOS) | App(HARMONY) | WEB | 微信小程序 |
|---|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ | ✓ |
- 绘制通道分端:Web 端画布元素直取上下文,小程序端组件作用域选择器取节点,App 端异步上下文载体。
- 图片水印支持本地与网络路径;Web 与小程序端使用网络图片时受跨域限制(图片服务需允许跨域,小程序端需配置 downloadFile 合法域名);加载失败会发
error事件并回退到文字水印(text 为空时不绘制)。 - 全屏水印层为 fixed 定位,覆盖整个窗口且不影响页面任何交互。
基本使用
html
<template>
<n-watermark text="内部资料" :width="140" :height="70" :gap-x="80" :gap-y="80">
<view class="content">
<text>被水印覆盖的页面内容</text>
</view>
</n-watermark>
</template>
图片水印(logo 等按比例适配单元格,不变形):
html
<n-watermark image="/static/logo.png" :width="100" :height="100" :gap-x="120" :gap-y="120" :rotate="0" />
全屏水印(覆盖整个窗口,页面内容仍在插槽内正常交互):
html
<template>
<n-watermark text="机密文件" full-screen :z-index="99">
<view class="page-content">...</view>
</n-watermark>
</template>
深浅主题自动换色(切换主题即重绘):
html
<n-watermark text="内部资料" color="rgba(0,0,0,0.15)" dark-color="rgba(255,255,255,0.15)" />
属性变化即时重绘:
html
<template>
<n-watermark :text="text" :rotate="rotate" />
</template>
<script setup lang="uts">
const text = ref("内部资料");
const rotate = ref(-22);
// 改 text / rotate 等 props 即自动重绘
</script>
强制刷新(窗口尺寸变化后个别端未触发观察时的兜底):
html
<script setup lang="uts">
const wmRef = ref<NWatermarkComponentPublicInstance | null>(null);
function redraw() {
wmRef.value!.refresh();
}
</script>
API
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| text | string | "" | 水印文本内容;image 为空时生效,与 image 同传时图片优先 |
| image | string | "" | 水印图片路径(本地 / 网络),非空时优先于 text;加载失败发 error 并回退文字水印 |
| fontSize | number | 15 | 水印字号 px |
| fontWeight | string | "normal" | 字重,CSS 值(normal / bold / 300 等) |
| fontFamily | string | "sans-serif" | 水印字体族 |
| color | string | "rgba(0,0,0,0.15)" | 浅色主题文字水印颜色 |
| darkColor | string | "rgba(255,255,255,0.15)" | 深色主题文字水印颜色,主题切换自动重绘 |
| opacity | number | 1 | 水印层整体透明度 0~1 |
| rotate | number | -22 | 水印单元旋转角度(度) |
| width | number | 120 | 单元格宽 px:文字居中其内、图片按比例适配其内 |
| height | number | 64 | 单元格高 px |
| gapX | number | 100 | 相邻单元格水平间距 px |
| gapY | number | 100 | 相邻单元格垂直间距 px |
| zIndex | number | 9 | 水印层层级;默认盖在内容之上,需垫底传低值如 -1 |
| fullScreen | boolean | false | 全屏水印:true 时 fixed 覆盖整个窗口,false 时仅覆盖组件容器 |
| customClass | string | "" | 根节点类名(类须定义在使用方样式域) |
| customStyle | string | "" | 根节点行内样式,拼接在内部默认值之后可覆盖 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
| error | message: string |
水印图片加载失败或画布通道失败时触发 |
插槽
| 插槽 | 说明 |
|---|---|
| default | 被水印覆盖的页面内容;内容保持全部交互能力(水印层不拦截点击) |
实例方法
(通过 ref 直调)
| 方法 | 参数 | 返回 | 说明 |
|---|---|---|---|
| refresh | — | void | 强制重绘水印;容器尺寸自动观察之外的兜底入口 |
实现说明(参考做法 vs 本库做法)
| 机制 | 参考做法 | 本库做法 | 分歧理由 |
|---|---|---|---|
| 包裹形态 | 两源均为插槽承载内容 + 水印层覆盖 | 同参考:插槽内容层 + 画布水印层 | 一致 |
| 图片水印 | 仅一源有 image prop(实现不可见) | 官方 createImage 通道加载,drawImage 按比例 contain 适配单元格居中 | 参考示例图与配置恰好同比例、无法分辨缩放策略,取无变形方案 |
| 全屏水印 | 仅一源有 fullScreen | fixed 水印层 + 画布尺寸 = 窗口实时值,窗口变化(onResize / onPageShow)自动刷新 | 并集收录;结构位翻转走节点重建 |
| 深色换色 | 一源 darkColor + 自带深色检测重绘 | darkColor + 库主题单例(isDark)watch 重绘 | 同机制接入库主题系统 |
| 平铺算法 | 一源:单元格网格(width+gapX 步进)每单元独立旋转、文字居中 | 同参考算法 | 同代参考 |
| 交互穿透 | 一源水印层 pointer-events: none | 同参考 | 水印只做视觉覆盖,不改变内容交互 |
| 层级默认 | 一源默认 9(盖上);另一源默认 -1(垫底) | 默认 9 盖内容之上 | 防泄露覆盖为水印主用途;垫底场景显式传低值 |
| 空水印态 | 一源默认恒画 'Watermark';另一源默认空 | text 与 image 都空不渲染水印层 | 空水印无意义,默认空更干净 |
| 尺寸跟随 | 一源 SelectorQuery 手动实测容器 + refresh() | 容器尺寸观察器自动跟随 + refresh() 兜底 | 尺寸变化自动重绘,refresh 保留同名 API 作兜底 |
| 错误暴露 | 两源均无 | error 事件(图片加载失败 / 画布通道失败显式暴露) | 静默失败违背库内画布组件一致性(图片加载失败只回退不提示会误判为绘制成功) |
| 定制通道 | 一源 pt 透传对象 | customClass / customStyle | 透传对象已废除,走全库定制通道 |