实现防篡改的水印组件封装

需求:实现防止篡改的水印组件

注:该文章只探讨技术层面的实现   不考虑非技术手段

层面1:界面区域打上水印

层面2:防止篡改

<template>
    <div class="container">
        <Watermark text="版权所有">
            <div class="content"></div>
        </Watermark>
        <Watermark text="禁止转载" style="background: #6400a0">
            <div class="content"></div>
        </Watermark>
    </div>
</template>
<template>
    <div class="water-container" ref="parentRef">
        <slot></slot>
<!--        此处新建一个div 把这个div做成一个防篡改的div-->
        <div></div>
    </div>
</template>

<script setup>
    import useWatermarkBg from './useWatermarkBg';
    const props = defineProps({
        text:{
            type:String,
            required:true,
            default:'watermark'
        },
        fontSize:{
            type:Number,
            default:40
        },
        gap:{
            type:Number,
            default:20
        }
    })
    // 这个方法可以返回水印的base64 和尺寸
    const bg = useWatermarkBg(props);
    const parentRef = ref(null);
    // 因为每次重新创建水印 都需要重新创建一个div 需要移除div
    let div;
    // 重置水印  -- 因为要防篡改
    function resetWatermark(){
        if(!parentRef.value) {
            return;
        }
        if(div){
            // parentRef.value.removeChild(div);
            // 或
            div.remove();
            // 两种写法都可以
        }
        const {base64 , size} = bg.value;
        div = document.createElement('div');
        div.style.position = 'absolute';
        div.style.backgroundImage = `url(${base64})`;
        div.style.backgroundSize = `${size}px ${size}px`;
        div.style.backgroundRepeat = `repeat`;
        // 事件穿透 -- 点击水印不做任何处理
        div.style.pointerEvents = 'none';
        div.style.zIndex = 9999;
        //背景图覆盖整个区域
        div.style.inset = 0;
        // 父元素如果有 就把元素加进去
        parentRef.value.appendChild(div);
    }

    // 创建一个观察器
    // 细节 : 到底应该观察什么元素, 只监控水印的div,别的div变化不做处理
    const ob = new MutationObserver((entries)=>{
        // 使用entries参数,把变化的东西都放在这个集合里
        console.log('变化了')
        for (const entry of entries){
            //    关注两个属性
            // removedNodes  -- 表示这一次的变化是某一些节点被移除了 它会把被移除掉的节点放在这个集合里面
            // target -- 表示是什么东西变化了 例:target:div.watermark-container
            console.log('entry',entry)
            // 处理被删除的情况
            for (const node of entry.removedNodes) {
                if(node === div){
                    // 如果相同就等于水印被删除了,那么就重置水印
                    resetWatermark();
                    return;
                }
            }

            // 处理被修改的情况
            console.log('entry',entry)
            // 此时 removedNodes没有被修改 数组为0
            // 被修改后 它的target就变了  变成了被修改的那个元素  例:target:div
            // type:'attributes'  被修改的类型:  属性
            // attributeName : 'style'   被修改的是什么属性 : style属性
            if(entry.target === div){
                // 如果要动水印那个元素 也需要重置一下
                resetWatermark();
            }

        }
    })

    // 调用
    // 1: 一开始调用
    onMounted(()=>{
        resetWatermark();

    //    观察父元素

        ob.observe(parentRef.value,{
            // 观察父元素的子元素
            childList : true,
            // 观察子元素的子元素 子树
            subtree : true,
            // 观察属性的变化
            attributes : true
        })
    })

    // 2: 被篡改时调用 --- MutationObserver  -> 被改动后的一个观察器


    // 组件卸载后取消观察
    onUnMounted(()=>{
        ob.disconnect();
    })

</script>

具体处理还有很多方法,上述只是在学习过程中发现的方法,如果有其他好用的方法,欢迎指教,上文只是参考总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值