1. App.vue
<template><div id="app" class="app"><router-view></router-view></div>
</template><script>
export default {mounted() {this.updateWatermark();// 监听路由变化this.$router.afterEach(() => {this.$nextTick(() => {this.ensureWatermarkAndTable();});});// 监听 DOM 变化,确保表格背景实时调整this.observeDOM();},data() {return {watermarkText: "",user: {},};},methods: {updateWatermark() {let curUser = sessionStorage.getItem("curUser");if (curUser) {try {const userData = JSON.parse(curUser);this.watermarkText = `${userData.systemUsers.nickname}(${userData.systemRoleList[0].name})`;} catch (e) {console.error("解析 curUser 失败:", e);this.watermarkText = "默认水印"; // 备用文本}} else {this.watermarkText = "默认水印"; // 无用户数据时使用默认值}console.log("水印文本:", this.watermarkText);this.addWatermark();},addWatermark() {const oldWatermark = document.querySelector(".watermark-layer");if (oldWatermark) oldWatermark.remove();const canvas = document.createElement("canvas");canvas.width = 200;canvas.height = 200;const ctx = canvas.getContext("2d");ctx.font = "16px Arial";ctx.fillStyle = "rgba(102, 102, 102, 0.5)";ctx.textAlign = "center";ctx.textBaseline = "middle";ctx.rotate((-20 * Math.PI) / 180);ctx.fillText(this.watermarkText, canvas.width / 2, canvas.height / 2);const dataURL = canvas.toDataURL();const watermarkLayer = document.createElement("div");watermarkLayer.className = "watermark-layer";watermarkLayer.style.backgroundImage = `url(${dataURL})`;watermarkLayer.style.backgroundRepeat = "repeat";document.body.appendChild(watermarkLayer);},ensureWatermarkAndTable() {if (!document.querySelector(".watermark-layer")) {this.addWatermark();}this.adjustTableBackground();},adjustTableBackground() {const tables = document.querySelectorAll(".el-table");tables.forEach((table) => {table.style.backgroundColor = "rgba(255, 255, 255, 0.8)";const wrappers = table.querySelectorAll(".el-table__body-wrapper, .el-table__header-wrapper, .el-table__fixed, .el-table__fixed-right");wrappers.forEach((wrapper) => {wrapper.style.backgroundColor = "rgba(255, 255, 255, 0.8)";});const cells = table.querySelectorAll("th, td, tr");cells.forEach((cell) => {cell.style.backgroundColor = "transparent";});});},observeDOM() {const observer = new MutationObserver(() => {this.ensureWatermarkAndTable();});observer.observe(document.body, {childList: true,subtree: true,});},},
};
</script><style>
.app {width: 100vw;height: 100vh;position: relative;z-index: 1;color: #333;
}.watermark-layer {position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;z-index: 0;pointer-events: none;
}body {margin: 0;padding: 0;position: relative;
}html,
body,
h3,
p {margin: 0;padding: 0;
}
</style>
2. src/assets/css/main.css
/* src/assets/css/main.css */
.el-table,
.el-table__body-wrapper,
.el-table__header-wrapper,
.el-table__fixed,
.el-table__fixed-right,
.el-table__body,
.el-table__header {background-color: rgba(255, 255, 255, 0.8) !important;
}.el-table th,
.el-table tr,
.el-table td,
.el-table__cell {background-color: transparent !important;
}.watermark-layer {position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;z-index: 0 !important;pointer-events: none;
}
3. main.js
import Vue from "vue";
import App from "./App.vue";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
import router from "./router/index";
import store from "./store/index";
import * as echarts from "echarts";
import JsonViewer from "vue-json-viewer";
import VueCron from "vue-cron";
import VideoPlayer from "vue-video-player/src";
import "vue-video-player/src/custom-theme.css";
import "video.js/dist/video-js.css";
import "./assets/css/content.css";
import "./assets/css/main.css"; // 确保引入Vue.prototype.$echarts = echarts;
Vue.use(JsonViewer);
Vue.use(VueCron);
Vue.use(VideoPlayer);
Vue.use(ElementUI);Vue.config.productionTip = false;new Vue({router,store,render: (h) => h(App),created() {store.commit("addMenu", router);},
}).$mount("#app");
4.实现效果
