uniapp加上全局水印

文章目录

一、效果图

  • 未登录效果

  • 登录后效果

二、创建watermark.js文件

这里的水印因为我是为了显示store中的用户名字(user.name)和账号(user.userno),所以用了store,切记,这里的user.name和user.userno要换成自己的内容,我做了一个判断,如果是登录页面或者是忘记密码啊等等不用登录就能访问的页面,我都统一显示"请登录",还有的页面不需要显示的,就给他过滤掉,其余的页面就正常显示用户姓名和编号,所以这里做了一个判断

js 复制代码
/**
 * uniapp全局水印插件(支持排除特定页面)
 */
import store from '@/store/index.js'
export default {
  install(app, options = {}) {
    // 默认配置
    const defaultOptions = {
      defaultContent: '未登录',
      width: 170, // 水印宽度
      height: 130, // 水印高度
      fontSize: 14, // 字体大小
      color: 'rgba(0, 0, 0, 0.1)', // 水印字体颜色及透明度
      rotate: -15, // 旋转角度
      zIndex: 999, // 在哪一层
      loginPaths: ['/pages/login', '/pages/forgetpwd'], // 登录相关页面路径(水印为请登录)
      excludePaths: ['/pages/common/webview/unindex'] // 需要排除水印的页面路径
    };
    
    const opts = { ...defaultOptions, ...options };
    let watermarkEl = null;
    let currentContent = '';
    
    // 获取当前页面路径
    function getCurrentPagePath() {
      const pages = getCurrentPages();
      if (pages.length) {
        const currentPage = pages[pages.length - 1];
        return `/${currentPage.route}`;
      }
      return '';
    }
    
    // 检查是否为需要排除水印的页面
    function isExcludedPage() {
      const currentPath = getCurrentPagePath();
      return opts.excludePaths.some(path => currentPath.includes(path));
    }
    
    // 检查是否为登录相关页面
    function isLoginPage() {
      const currentPath = getCurrentPagePath();
      return opts.loginPaths.some(path => currentPath.includes(path));
    }
    
    // 创建水印元素
    function createWatermark(content) {
      const canvas = document.createElement('canvas');
      canvas.width = opts.width;
      canvas.height = opts.height;
      
      const ctx = canvas.getContext('2d');
      ctx.rotate(opts.rotate * Math.PI / 180);
      ctx.font = `${opts.fontSize}px sans-serif`;
      ctx.fillStyle = opts.color;
      ctx.textAlign = 'left';
      ctx.textBaseline = 'middle';
      ctx.fillText(content, canvas.width / 10, canvas.height / 2);
      
      return canvas.toDataURL('image/png');
    }
    
    // 更新水印
    function updateWatermark(force = false) {
      // 如果是排除的页面,隐藏水印
      if (isExcludedPage()) {
        if (watermarkEl) watermarkEl.style.display = 'none';
        return;
      }
      
      // 确保水印元素存在
      if (!watermarkEl) {
        watermarkEl = document.createElement('div');
        watermarkEl.className = 'global-watermark';
        watermarkEl.style.cssText = `
          position: fixed;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          pointer-events: none;
          z-index: ${opts.zIndex};
        `;
        document.body.appendChild(watermarkEl);
      } else {
        watermarkEl.style.display = 'block';
      }
      
      const user = store?.state?.user || {};
      const newContent = isLoginPage() 
        ? opts.defaultContent 
        : ((user.name+' '+user.userno) || opts.defaultContent);
      
      if (newContent !== currentContent || force) {
        currentContent = newContent;
        const watermarkUrl = createWatermark(newContent);
        watermarkEl.style.backgroundImage = `url("${watermarkUrl}")`;
      }
    }
    
    // 初始化路由监听
    function initRouteWatcher() {
      // 轮询检查页面变化
      let lastPagesLength = 0;
      setInterval(() => {
        const pages = getCurrentPages();
        if (pages.length !== lastPagesLength) {
          lastPagesLength = pages.length;
          updateWatermark();
        }
      }, 300);
    }
    
    // 全局混入
    app.mixin({
      onLoad() {
        this.$nextTick(updateWatermark);
      },
      onShow() {
        updateWatermark();
      },
      mounted() {
        // 监听用户状态变化
        this.userWatcher = store?.watch(
          (state) => state.user?.name,
          () => updateWatermark()
        );
      },
      beforeUnmount() {
        // 清理监听器
        if (this.userWatcher) {
          this.userWatcher();
        }
      }
    });
    
    // 初始化
    initRouteWatcher();
    setTimeout(updateWatermark, 100);
  }
};    

三、在main.js中引入

js 复制代码
import watermark from './watermark';
// 使用水印插件,可传入自定义配置
Vue.use(watermark, {
  loginPaths: [
	  '/pages/login',  // 登录页
	  '/pages/forgetpwd' // 忘记密码页面
  ],
  defaultContent: '请登录'
});

App.mpType = 'app';

const app = new Vue({
	store,
	...App
})

四、运行

做完这几个步骤后,运行就可以显示出自己想要的效果了