Vue3?實現(xiàn)網(wǎng)頁背景水印功能的示例代碼
經(jīng)常有一些公司和組織出于系統(tǒng)文件或信息安全保密的需要,需要在系統(tǒng)網(wǎng)頁上增加帶有個人標(biāo)識(系統(tǒng)賬號或個人信息)的水印,可以簡單防止截圖外傳
首先我們來看這樣一個水印功能的實現(xiàn)思路,通常是在我們原有的網(wǎng)頁上附上一個 DIV 層,將它設(shè)置絕對定位鋪滿整個窗口,然后 z-index 值盡量往大了設(shè),保證讓水印層處于當(dāng)前網(wǎng)頁所有元素的上面,又不影響當(dāng)前網(wǎng)頁的操作。
水印上的字體有兩種方式添加:
- 第一種直接將字體用塊元素包裹,動態(tài)設(shè)置絕對定位,然后通過 transform 屬性旋轉(zhuǎn);
- 第二種通過在 canvas 上繪制出字體,設(shè)置好樣式,然后以圖片的樣式導(dǎo)出,最后用圖片作為水印層的背景圖。
處于性能方面考慮,第二種方式最優(yōu)。我們來看具體怎么實現(xiàn)?
作為一塊獨立的功能,我們在 Vue3 中常用 hooks 來實現(xiàn),通過分析我們概括出實現(xiàn)水印需要的幾個功能函數(shù)和對外接口:
對外接口
- 清除水?。╟lear)
- 設(shè)置水?。╯etWatermark)
核心功能函數(shù)
- 繪制文字背景圖(createBase64)
- 繪制水印層(createWatermark)
- 頁面隨窗口大小調(diào)整更新(updateWatermark)
export function useWatermark( appendEl: Ref<HTMLElement | null> = ref(document.body) as Ref<HTMLElement> ) { // 繪制文字背景圖 function createBase64() {} // 繪制水印層 const createWatermark = () => {}; // 頁面隨窗口調(diào)整更新水印 function updateWatermark(){} // 對外提供的設(shè)置水印方法 function setWatermark() {} // 清除水印 const clear = () => {}; return { setWatermark, clear }; }
有了代碼框架,就只需要實現(xiàn)函數(shù)和接口的內(nèi)部實現(xiàn)了,另外還要考慮傳參,來實現(xiàn)代碼復(fù)用的靈活度和接口參數(shù)的可配置。
我們從具體的功能函數(shù)開始:
繪制文字背景圖
這里的參數(shù) str
就是要添加的水印文字,attr
為文字樣式的屬性,我們定義了屬性的類型為 attr
,它包含文字的字體和大小以及顏色等值
function createBase64(str: string, attr?: attr) { const can = document.createElement("canvas"); const width = 200; const height = 140; Object.assign(can, { width, height }); const cans = can.getContext("2d"); if (cans) { cans.rotate((-20 * Math.PI) / 120); cans.font = attr?.font ?? "12px Reggae One"; cans.fillStyle = attr?.fillStyle ?? "rgba(0, 0, 0, 0.12)"; cans.textAlign = "left"; cans.textBaseline = "middle"; cans.fillText(str, width / 20, height); } return can.toDataURL("image/png"); }
type attr = { font?: string; fillStyle?: string; };
繪制水印層
這個函數(shù)的主要邏輯是先判斷如果已經(jīng)繪制了水印層,直接調(diào)用更新水印方法,如果還沒有,先動態(tài)創(chuàng)建一個 DIV 層,設(shè)置絕對定位,鋪滿當(dāng)前整個瀏覽器窗口。
const id = domSymbol.toString(); const watermarkEl = shallowRef<HTMLElement>(); const createWatermark = (str: string, attr?: attr) => { if (unref(watermarkEl)) { updateWatermark({ str, attr }); return id; } const div = document.createElement("div"); watermarkEl.value = div; div.id = id; div.style.pointerEvents = "none"; div.style.top = "0px"; div.style.left = "0px"; div.style.position = "absolute"; div.style.zIndex = "100000"; const el = unref(appendEl); if (!el) return id; const { clientHeight: height, clientWidth: width } = el; updateWatermark({ str, width, height, attr }); el.appendChild(div); return id; };
更新水印
因為更新水印方法主要是根據(jù)當(dāng)前窗口高度和寬度來的更新水印背景的設(shè)置,利用一張 Base64 格式的圖片平鋪即可。
function updateWatermark( options: { width?: number; height?: number; str?: string; attr?: attr; } = {} ) { const el = unref(watermarkEl); if (!el) return; if (options.width !== "undefined") { el.style.width = `${options.width}px`; } if (ioptions.height !== "undefined") { el.style.height = `${options.height}px`; } if (options.str !== "undefined") { el.style.background = `url(${createBase64( options.str, options.attr )}) left top repeat`; } }
到此,我們實現(xiàn)了主要的三個功能函數(shù),下面就是兩個對外接口:
設(shè)置水印
這里的主要點是考慮設(shè)置頁面resize監(jiān)聽,來及時更新水印的位置。還要考慮 Vue 的生命周期,當(dāng)我們卸載頁面的時候要進(jìn)行清除水印。
function setWatermark(str: string, attr?: attr) { createWatermark(str, attr); addResizeListener(document.documentElement, func); const instance = getCurrentInstance(); if (instance) { onBeforeUnmount(() => { clear(); }); } } const func = throttle(function () { const el = unref(appendEl); if (!el) return; const { clientHeight: height, clientWidth: width } = el; updateWatermark({ height, width }); });
清除水印
清除水印的時候順便移除窗口大小監(jiān)聽函數(shù)
const clear = () => { const domId = unref(watermarkEl); watermarkEl.value = undefined; const el = unref(appendEl); if (!el) return; domId && el.removeChild(domId); removeResizeListener(el, func); };
水印功能 hooks 的使用
import { useWatermark } from "/@/hooks/watermark"; const { setWatermark, clear } = useWatermark(); onMounted(() => { nextTick(() => { setWatermark(watermarkText.value); }); }); onBeforeUnmount(() => { clear(); });
至此,Vue3 版的網(wǎng)頁水印功能實現(xiàn)全部完成。這里水印的字體大小、顏色和排布參考了企業(yè)微信的背景水印,使得看起來不那么突兀。
到此這篇關(guān)于Vue3 實現(xiàn)網(wǎng)頁背景水印功能的文章就介紹到這了,更多相關(guān)vue網(wǎng)頁水印內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
antd?Vue實現(xiàn)Login登錄頁面布局案例詳解?附帶驗證碼驗證功能
這篇文章主要介紹了antd?Vue實現(xiàn)Login登錄頁面布局案例詳解附帶驗證碼驗證功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05vue中選項卡點擊切換且能滑動切換功能的實現(xiàn)代碼
本文通過實例代碼給大家介紹了vue中選項卡點擊切換且能滑動切換功能,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下2018-11-11VueJs單頁應(yīng)用實現(xiàn)微信網(wǎng)頁授權(quán)及微信分享功能示例
本篇文章主要介紹了VueJs單頁應(yīng)用實現(xiàn)微信網(wǎng)頁授權(quán)及微信分享功能示例,具有一定的參考價值,有興趣的可以了解一下2017-07-07在Vue中使用scoped屬性實現(xiàn)樣式隔離的原因解析
scoped是Vue的一個特殊屬性,可以應(yīng)用于<style>標(biāo)簽中的樣式,這篇文章給大家介紹在Vue中,使用scoped屬性為什么可以實現(xiàn)樣式隔離,感興趣的朋友一起看看吧2023-12-12