宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見問題
產(chǎn)品動態(tài)
精選推薦

基于Vue3水印組件封裝:防篡改守護(hù)

管理 管理 編輯 刪除

基于Vue 3的全新水印通用組件。這款組件不僅功能強(qiáng)大,而且易于集成,能夠輕松為您的網(wǎng)頁或應(yīng)用添加自定義水印,有效防止內(nèi)容被篡改或盜用。

一,編寫watermark組件

<template>
   <div ref="watermarkContainerRef" class="watermark-container">
      <!--  插槽-->
     <slot></slot>
   </div>
</template>

<script setup>
import { ref, onMounted, watchEffect, onUnmounted, computed } from "vue";
// 使用 defineProps 定義一個組件的 props,這些 props 描述了組件從父組件接收的屬性
const props = defineProps({
  // 文本內(nèi)容,類型為字符串,必須提供,默認(rèn)值為'張?zhí)O果博客'
  text: {
    type: String,
    required: true,
    default: '張?zhí)O果博客'
  },
  // 字體大小,類型為數(shù)字,默認(rèn)值為10
  fontSize: {
    type: Number,
    default: 10,
  },
  // 間距,類型為數(shù)字,默認(rèn)值為1
  gap: {
    type: Number,
    default: 1,
  },
  // 顏色,類型為字符串,默認(rèn)值為'rgba(82,75,75,0.58)'
  color: {
    type: String,
    default: 'rgba(82,75,75,0.58)',
  }
});

// 定義一個用于繪制水印的函數(shù),這里可以封裝一下單獨引入。
// 它是一個計算屬性,意味著它的值會根據(jù)其依賴的 props 的變化而自動重新計算
const waterMarkBg = (props) => {
  return computed(() => {
    // 創(chuàng)建一個新的 canvas 元素
    const canvas = document.createElement("canvas");
    // 獲取設(shè)備的像素比,如果未定義則默認(rèn)為1
    const devicePixelRatio = window.devicePixelRatio || 1;
    // 根據(jù)像素比計算字體大小
    const fontSize = props.fontSize * devicePixelRatio;
    // 設(shè)置字體樣式
    const font = fontSize + "px serif";
    // 獲取 canvas 的 2D 渲染上下文
    const ctx = canvas.getContext("2d");
    // 設(shè)置字體
    ctx.font = font;
    // 測量文本的寬度
    const { width } = ctx.measureText(props.text);
    // 計算 canvas 的大小,至少為 60,并根據(jù)文本寬度和間距因子進(jìn)行調(diào)整
    const canvasSize = Math.max(60, width) * props.gap + devicePixelRatio;
    // 設(shè)置 canvas 的寬高
    canvas.width = canvasSize;
    canvas.height = canvasSize;
    // 將 canvas 的原點移動到中心
    ctx.translate(canvas.width / 2, canvas.height / 2);
    // 旋轉(zhuǎn) canvas 45 度
    ctx.rotate((Math.PI / 180) * -45);
    // 設(shè)置填充顏色
    ctx.fillStyle = props.color;
    // 設(shè)置文本對齊方式和基線
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    // 再次設(shè)置字體
    ctx.font = font;

    // 在 canvas 上填充文本
    ctx.fillText(props.text, 0, 0);

    // 返回一個對象,包含 base64 編碼的圖片數(shù)據(jù)、canvas 的大小和樣式尺寸
    return {
      base64: canvas.toDataURL(),
      size: canvasSize,
      styleSize: canvasSize / devicePixelRatio
    };
  });
};

// 用于存儲 MutationObserver 的變量
let ob;
// 用于存儲水印 div 的變量
let div;
// 調(diào)用 waterMarkBg 函數(shù)獲取水印相關(guān)的計算屬性
const bg = waterMarkBg(props);
// 創(chuàng)建一個 ref 用于存儲水印容器的 DOM 引用
const watermarkContainerRef = ref('');
// 創(chuàng)建一個 ref 用于標(biāo)記水印是否需要重新生成
const flag = ref(0);

// 在組件掛載后執(zhí)行
onMounted(() => {
  // 創(chuàng)建一個新的 MutationObserver,用于監(jiān)聽水印容器的變化
  ob = new MutationObserver((records) => {
    // 遍歷所有的變化記錄
    for (const record of records) {
      // 遍歷所有被移除的節(jié)點
      for (const dom of record.removedNodes) {
        // 如果被移除的節(jié)點是水印 div,則更新 flag 的值并返回
        if (dom === div) {
          flag.value++;
          return;
        }
      }
      // 如果變化的節(jié)點就是水印 div,則更新 flag 的值并返回
      if (record.target === div) {
        flag.value++;
        return;
      }
    }
  });
  // 包括子節(jié)點的變化、屬性的變化以及子樹的變化
  ob.observe(watermarkContainerRef.value,{
    childList:true,
    attributes:true,
    subtree:true
  });
})

//卸載
onUnmounted(()=>{
  ob && ob.disconnect();
  div=null;
})

// 生成水印
watchEffect(() => {
  // 觸發(fā) watchEffect 的重新執(zhí)行
  flag.value;
  // 如果水印容器沒有值,則直接返回,不執(zhí)行后續(xù)操作
  if (!watermarkContainerRef.value) {
    return;
  }
  // 如果之前已經(jīng)存在水印 div,則先移除它
  if (div) {
    div.remove();
  }
  // 創(chuàng)建一個新的 div 元素用于作為水印的容器
  div = document.createElement('div');
  // 從計算屬性 bg 中獲取 base64 編碼的圖片數(shù)據(jù)和樣式尺寸
  const { base64, styleSize } = bg.value;
  // 設(shè)置 div 的背景圖片為水印圖片的 base64 編碼
  div.style.backgroundImage = `url(${base64})`;
  // 設(shè)置背景圖片的尺寸
  div.style.backgroundSize = `${styleSize}px ${styleSize}px`;
  // 設(shè)置背景圖片重復(fù)顯示
  div.style.backgroundRepeat = "repeat";
  // 設(shè)置水印 div 的 z-index 為 9999,以確保它顯示在大多數(shù)其他元素之上
  div.style.zIndex = 9999;
  // 設(shè)置水印 div 不響應(yīng)鼠標(biāo)事件,如點擊、懸停等
  div.style.pointerEvents = "none";
  // 設(shè)置水印 div 的位置為絕對定位
  div.style.position = "absolute";
  // 使用 inset 屬性設(shè)置 div 占據(jù)整個父容器的空間
  div.style.inset = "0";
  // 將水印 div 添加到水印容器中
  watermarkContainerRef.value.appendChild(div);
});


</script>

<style scoped>
.watermark-container{
  position: relative;
}

</style>

二,在頁面中引入使用

<template>
 <div>
   <n-grid>
     <n-gi style="margin: 15px"   span="6 1025:2  "  v-for="(item,index) in 4" :key="index">
<!--       引入 Watermark-->
         <Watermark :gap="gap" :text="text" :fontSize="fontSize" :color="color">
           <n-card
               v-motion-pop-visible-once
              title="標(biāo)題"
               hoverable
           >
            這是內(nèi)容 <br>
            這是內(nèi)容 <br>
            這是內(nèi)容 <br>
            這是內(nèi)容 <br>
            這是內(nèi)容 <br>
            這是內(nèi)容 <br>
           </n-card>
         </Watermark>

     </n-gi>
   </n-grid>

 </div>
</template>

<script setup>
import Watermark from '../components/Watermark.vue'
import {ref} from "vue";
const text=ref('張?zhí)O果博客');
const gap=ref(1);
const fontSize=ref('10');
const color=ref('');
</script>

<style scoped>

</style>


請登錄后查看

小碼二開 最后編輯于2024-05-17 10:42:07

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無簡介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
3506
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見問題 產(chǎn)品動態(tài) 精選推薦 首頁頭條 首頁動態(tài) 首頁推薦
取 消 確 定
回復(fù)
回復(fù)
問題:
問題自動獲取的帖子內(nèi)容,不準(zhǔn)確時需要手動修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊

切換手機(jī)號登錄

{{ bind_phone ? '綁定手機(jī)' : '手機(jī)登錄'}}

{{codeText}}
切換微信登錄/注冊
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服