Vue 水印

小花兒_向陽花發表於2019-02-19

直接將下面檔案作為水印檔案waterMark.vue,傳入inputType內容為水印展示的資訊 目前直接渲染到id=blackList上,可以根據情況調整。

<template>
    <div></div>
</template>
<script>
export default {
    props: {
        // 顯示的水印文字
        inputText: {
            type: String,
            default: "waterMark水印"
        },
        // 是否允許通過js或開發者工具等途徑修改水印DOM節點(水印的id,attribute屬性,節點的刪除)
        // true為允許,預設不允許
        inputAllowDele: {
            type: Boolean,
            default: false
        },
        // 是否在元件銷燬時去除水印節點(前提是允許使用者修改DOM,否則去除後會再次自動生成)
        // true會,預設不會
        inputDestroy: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            maskDiv: {} // 當前顯示的水印div節點DOM物件
        };
    },
    mounted() {
        // 確認DOM渲染後再執行
        this.$nextTick(() => {
        // 建立水印節點
        this.init();
            if (!this.inputAllowDele) {
                // 設定水印節點修改的DOM事件
                this.Monitor();
            }
        });
    },
    methods: {
        init() {
            let canvas = document.createElement("canvas");
            canvas.id = "canvas";
            canvas.width = "200"; // 單個水印的寬高
            canvas.height = "130";
            this.maskDiv = document.createElement("div");
            let ctx = canvas.getContext("2d");
            ctx.font = "normal 18px Microsoft Yahei"; // 設定樣式
            ctx.fillStyle = "rgba(112, 113, 114, 0.1)"; // 水印字型顏色
            ctx.rotate((30 * Math.PI) / 180); // 水印偏轉角度
            ctx.fillText(this.inputText, 30, 20);
            let src = canvas.toDataURL("image/png");
            this.maskDiv.style.position = "fixed";
            this.maskDiv.style.zIndex = "9999";
            this.maskDiv.id = "_waterMark";
            this.maskDiv.style.top = "30px";
            this.maskDiv.style.left = "0";
            this.maskDiv.style.height = "100%";
            this.maskDiv.style.width = "100%";
            this.maskDiv.style.pointerEvents = "none";
            this.maskDiv.style.backgroundImage = "URL(" + src + ")";
            // 水印節點插到body下
            document.getElementById("blackList").appendChild(this.maskDiv);
        },
        Monitor() {
            let body = document.getElementsByTagName("body")[0];
            let options = {
                childList: true,
                attributes: true,
                characterData: true,
                subtree: true,
                attributeOldValue: true,
                characterDataOldValue: true
            };
            let observer = new MutationObserver(this.callback);
            observer.observe(body, options); // 監聽body節點
        },
        // DOM改變執行callback
        callback(mutations, observer) {
            // 當attribute屬性被修改
            if (mutations[0].target.id === "_waterMark") {
                this.removeMaskDiv();
            }
            // 當id被改變時
            if (mutations[0].attributeName === "id") {
                this.removeMaskDiv();
                this.init();
            }
            // 當節點被刪除
            if (
                mutations[0].removedNodes[0] &&
                mutations[0].removedNodes[0].id === "_waterMark"
            ) {
                this.init();
            }
        },
        /* public */
        // 手動銷燬水印DOM
        removeMaskDiv() {
            document.body.removeChild(this.maskDiv);
        },
        // 手動生成水印
        createMaskDiv() {
            this.init();
        }
    },
    watch: {
        // 監聽傳入水印文字變化
        inputText() {
            this.$nextTick(() => {
                this.removeMaskDiv();
            });
        }
    },
    destroy() {
        // 元件銷燬時去除生成在body節點下的水印節點
        if (this.inputDestroy) {
            this.removeMaskDiv();
        }
    }
};
</script>
複製程式碼

相關文章