vue 使用screenfull 实现全屏展示,全局水印实现, 以及全屏放大后部分组件无法使用,水印无法全屏显示问题的解决

需求:1. web项目中看板页面需要单独全屏显示 2. 项目全局增加水印,水印文字为当前用户登录姓名,登录页不显示水印

出现问题描述

  • 单页面进行全屏显示,下拉,时间选择器,抽屉等组件被 全屏覆盖到下一层,无法显示在全屏后页面的上一层
  • 单页面进行全屏展示,放大全屏后,水印消失

一、页面全屏展示

1. 下载screenfull

npm install screenfull@4.2.0 --save

直接使用 npm install screenfull --save 会报错,不支持最新版本

2. 页面引入组件,并使用

<template> 
<div id="embedContainer" ref="scrollBox">
    这是需要全屏的div  

     <el-drawer ref="drawer" id="drawerId" :visible.sync="dialogVisible" size="85%">
         这是抽屉
     </el-drawer>

</div>

<div><i class=" el-icon-full-screen" title="全屏模式"
                style="float: right;margin-right: 200px;margin-top:5px;   font-size: 30px;"
                @click="fullScreenButton"></i></div>

</template>

<script>
import screenfull from "screenfull"  

export default {
   
   methods:{
      fullScreenButton() { 
          if(screenfull.enabled) { 
                  let elementById = document.getElementById('embedContainer');
                   screenfull.toggle(elementById)
          }else {
              this.$message({
              type: 'warning',
              message: '您的浏览器不支持全屏'
          })
        }
        
      }
   }

}

</script>




3. 全屏后相关组件无法使用,被覆盖问题解决

问题1 : 抽屉组件无法在全屏后展示,被覆盖

解决: 将抽屉组件添加进q需要全屏的div,修改methods

在这里插入图片描述

   methods:{
      fullScreenButton() { 
          if(screenfull.enabled) { 
             this.$refs.scrollBox.appendChild(document.getElementById("drawerId"))    
             let elementById = document.getElementById('embedContainer');
             screenfull.toggle(elementById)
          }
        
      }
   }

问题2 : 下拉组件无法在全屏后展示,被覆盖

解决: 加上 :popper-append-to-body=“false”

 <el-select
          :popper-append-to-body="false"
          class="space_query_input"        
          size="small"
          style="width: 200px;"
          filterable
          collapse-tags
          clearable
          placeholder="请选择筛选维度"
          @change="changeType"
          v-model="queryParams.type"
        >
          <el-option
            v-for="item in choose"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>

加上 :popper-append-to-body=“false” 后 el-select 下拉文字会肯会出现没有对齐情况

加上 popper-class=“select-popper”

在这里插入图片描述


  >>> .select-popper {
    .el-select-dropdown__item{
      text-align: left;
    }
  }

问题3 : 级联选择器组件无法在全屏后展示,被覆盖

解决:加上 :append-to-body=“false”

         <el-cascader
          :append-to-body="false"
          size="small"
          placeholder="请选组织"
          style="width:230px"
          v-model="queryParams.orgId"
          :options="orgIdOptions"
          :props="defaultOrgProps"
          clearable
          filterable
          collapse-tags
          :show-all-levels="false"
          class="space_query_input">
        </el-cascader>

问题4 : 时间选择器组件无法在全屏后展示,被覆盖

解决: 加上 :append-to-body=“false”

     <el-date-picker
          :append-to-body="false"
          :picker-options="optionsStart"
          class="space_query_input"
          size="small"
          style="width: 200px"
          v-model="queryParams.beginTime"
          type="date"
          :clearable="false"
          value-format="yyyy-MM-dd"
          placeholder="开始日期">
        </el-date-picker>

二. 项目全局添加水印 (水印文字为当前用户登录姓名)

1. 新建 waterMark.js 文件

//waterMark.js文件

let watermark = {}

let setWatermark = (str) => {
  let id = '1.23452384164.123412416';

  if (document.getElementById(id) !== null) {
    document.body.removeChild(document.getElementById(id));
  }

  //创建一个画布
  let can = document.createElement('canvas');
  //设置画布的长宽
  can.width = 120;
  can.height = 120;

  let cans = can.getContext('2d');
  //旋转角度
  cans.rotate(-15 * Math.PI / 180);
  cans.font = '18px Vedana';
  //设置填充绘画的颜色、渐变或者模式
  cans.fillStyle = 'rgba(200, 200, 200, 0.40)';
  //设置文本内容的当前对齐方式
  cans.textAlign = 'left';
  //设置在绘制文本时使用的当前文本基线
  cans.textBaseline = 'Middle';
  //在画布上绘制填色的文本(输出的文本,开始绘制文本的X坐标位置,开始绘制文本的Y坐标位置)
  cans.fillText(str, can.width / 8, can.height / 2);

  let div = document.createElement('div');
  div.id = id;
  div.style.pointerEvents = 'none';
  div.style.top = '30px';
  div.style.left = '0px';
  div.style.position = 'fixed';
  div.style.zIndex = '100000';
  div.style.width = document.documentElement.clientWidth + 'px';
  div.style.height = document.documentElement.clientHeight + 'px';
  div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat';
  document.body.appendChild(div);
  return id;
}

// 该方法只允许调用一次
watermark.set = (str) => {
  let id = setWatermark(str);
  setInterval(() => {
    if (document.getElementById(id) === null) {
      id = setWatermark(str);
    }
  }, 500);
  window.onresize = () => {
    setWatermark(str);
  };
}

export default watermark;

2. 在 main.js 中引入

import watermark from ".utils/watermark"   

//去除登录页面
router.afterEach((item) =>{ 
//如果不为登录界面,显示水印
  if (item.name !=='login') { 
      //获取存储store中的数据
      watermark.set(store.state.name)
  }
})

3. store 数据存储

以当前(水印为当前登录用户姓名)场景为例,用户登录成功将用户姓名存储进store

  • store 下 index.js文件 添加相关信息
 state:{
    name:''
  },
   mutations:{
    SET_USER(state,name){
      state.name=name
    }
  },
  actions: {
    SET_USER(context,name) {
      context.commit("SET_USER",name)
    }
  }
  • login.vue 用户登录成功后进行存储操作
   this.$store.dispatch("SET_USER", res.data.data.userInfo.name)
  • 解决刷新页面后,store数据消失问题,在App.vue全局监听,刷新前先将数据存储sessionStorage,刷新后数据恢复store
created () {
      if (sessionStorage.getItem('user')) {
      this.$store.dispatch("SET_USER",sessionStorage.getItem('user'))
    }
    window.addEventListener('beforeunload',()=>{
      sessionStorage.setItem('user',this.$store.state.name)
    })
}

4. 点击登出到登录界面,水印依然存在的问题

登出方法中,将水印文字设置为空就好

import watermark from ".utils/watermark"  
   //登出方法
      handleLoginout() {
        this.$cookie.set("token", '');
        //水印设置为空
        watermark.set("")
        this.$router.push('/')
   }

5. 全屏显示时,全屏的页面水印消失问题

  • 在全屏按钮方法中重新绘制一个水印画布
<template> 
<div id="embedContainer" ref="scrollBox">
    这是需要全屏的div  

     <el-drawer ref="drawer" id="drawerId" :visible.sync="dialogVisible" size="85%">
         这是抽屉
     </el-drawer>

</div>

<div><i class=" el-icon-full-screen" title="全屏模式"
                style="float: right;margin-right: 200px;margin-top:5px;   font-size: 30px;"
                @click="fullScreenButton"></i></div>

</template>

<script>
import screenfull from "screenfull"  

export default {
   
   methods:{ 
      fullScreenButton() {
        if (screenfull.enabled) {
          this.$refs.scrollBox.appendChild(document.getElementById("drawerId"))
          let elementById = document.getElementById('embedContainer');
          screenfull.toggle(elementById)
          // 添加水印
          setTimeout(() => {
            const div1 = elementById.firstChild;
            //创建一个画布
            let can = document.createElement('canvas');
            //设置画布的长宽
            can.width = 120;
            can.height = 120;

            let cans = can.getContext('2d');
            //旋转角度
            cans.rotate(-15 * Math.PI / 180);
            cans.font = '18px Vedana';
            //设置填充绘画的颜色、渐变或者模式
            cans.fillStyle = 'rgba(200, 200, 200, 0.40)';
            //设置文本内容的当前对齐方式
            cans.textAlign = 'left';
            //设置在绘制文本时使用的当前文本基线
            cans.textBaseline = 'Middle';
            //在画布上绘制填色的文本(输出的文本,开始绘制文本的X坐标位置,开始绘制文本的Y坐标位置)
            cans.fillText(sessionStorage.getItem("user"), can.width / 8, can.height / 2);

            let div = document.createElement('partwater');
            div.id = "water";
            div.style.pointerEvents = 'none';
            div.style.top = '30px';
            div.style.left = '0px';
            div.style.position = 'fixed';
            div.style.zIndex = '100000';
            div.style.width = document.documentElement.clientWidth + 'px';
            div.style.height = document.documentElement.clientHeight + 'px';
            div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat';
            div1.appendChild(div)
          }, 100);
        } else {
          this.$message({
            type: 'warning',
            message: '您的浏览器不支持全屏'
          })
        }
      }
  }
}

</script>

5. 解决点击全屏,取消全屏(反复操作)水印文字慢慢变深问题

监听是否全屏,未全屏,移除水印节点

mounted() {
         window.onresize = () => {
           if (!screenfull.isFullscreen) {
          let elementById = document.getElementById("water");
          elementById.parentNode.removeChild(elementById)
        }
      }
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue实现组件全屏显示的方法有两种。第一种方法是使用F11键切换全屏,这是一种浏览器原生支持的方式。用户可以按下F11键来切换全屏显示。第二种方法是使用requestFullscreen()方法来实现全屏显示。但需要注意以下几点: 1. document下没有requestFullscreen方法。 2. requestFullscreen方法只能由用户触发,不能在onload事件中触发。 3. 在页面跳转之前,需要先退出全屏。 4. 进入全屏后,元素将脱离其父元素,可能导致之前某些CSS的失效。为解决这个问题,可以使用:full-screen伪类为元素添加全屏时的样式。 5. 如果一个元素A全屏后,其子元素也要全屏,需要先让元素A退出全屏。 在Vue中,可以在组件使用以下代码来实现全屏显示: ```javascript import screenFull from 'screenfull'; // 导入screenFull库 // 在组件中定义一个方法来实现全屏切换 const handleFullscreen = () => { if (screenFull.isEnabled) { // 判断浏览器是否支持全屏 screenFull.toggle(); // 切换全屏状态 } } // 在需要全屏显示组件中,可以通过点击事件或其他触发方式调用handleFullscreen方法 ``` 以上代码中,我们首先导入了screenFull库,然后定义了一个方法handleFullscreen来切换全屏状态。在需要全屏显示组件中,可以通过点击事件或其他触发方式调用handleFullscreen方法来实现全屏显示。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [vue 组件化-全屏](https://blog.csdn.net/m0_71933813/article/details/129226033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [vue全屏组件](https://blog.csdn.net/hjh15827475896/article/details/123370093)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值