需求: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)
}
}
}