当前位置: 首页 > news >正文

上海网站建设招聘网络营销研究现状文献综述

上海网站建设招聘,网络营销研究现状文献综述,莆田外贸网站建设有哪些,销售型网站怎么做的一、前置知识 — Vue 中的自定义指令 先来说说 vue2和vue3中自定义全局指令的区别 相同点:指令的应用场景,原理是一致的; 不同点:生命周期钩子函数名,指令定义的格式不一样。 vue2中自定义全局指令: 定义…

一、前置知识 — Vue 中的自定义指令

先来说说 vue2和vue3中自定义全局指令的区别

相同点:指令的应用场景,原理是一致的;
不同点:生命周期钩子函数名,指令定义的格式不一样。

vue2中自定义全局指令:

  • 定义
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {// 当被绑定的元素插入到 DOM 中时……inserted: function (el) {// 聚焦元素el.focus()}
})
  • 使用
<input v-foucs="'xxxx'" />

vue3中自定义全局指令:

  • 定义
// app是Vue实例。 e.g:  app = createApp()
app.directive('指令名', {// 省略其他生命周期钩子函数// el: 使用了指令的dom// binding.value:  v-指令名="binding.value就是这里表达式的值"mounted (el, binding) {console.log(el, binding.value)}
})
  • 使用
<元素 v-指令名="xxx" />

扩展: 在vue3中以插件的格式定义全局指令

  • 定义
// 定义全局指令
export default {install (app) {// app是Vue实例。 e.g:  app = createApp()app.directive('指令名', {// 省略其他生命周期钩子函数// el: 使用了指令的dom// binding.value:  v-指令名="binding.value就是这里表达式的值"mounted (el, binding) {console.log(el, binding.value)}})}
}
  • 使用(在main.js中注册插件)
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router/index'
import directives from './directives'createApp(App).use(router).use(directives).mount('#app')

二、实现水印功能

前端实现水印功能的方式有很多,这里主要讲解基于Canvas和MutationObserver的实现方式

1. 实现思路

  • 配置水印的具体样式(大小,旋转角度,文字填充)
  • 设置水印(位置)
  • 监听dom变化(防止水印删除后页面不再展示水印)

2. 生成水印

  • 通过将图片绘制在canvas中,然后通过canvas的toDataURL方法,将图片转为base64编码.

备注: toDataURL用法

toDataURL(type, encoderOptions),接收两个参数:
type:图片类型,比如image/png、image/jpeg、image/webp等等,默认为image/png格式 encoderOptions:图片质量的取值范围(0-1),默认值为0.92,当超出界限按默认值0.92

// 全局保存 canvas 和 div ,避免重复创建(单例模式)
const globalCanvas = null;
const globalWaterMark = null;// 返回一个包含图片展示的 数据URL
const getDataUrl = (binding: any) => {const rotate = -20;const canvas = globalCanvas || document.createElement("canvas");const ctx = canvas.getContext("2d"); // 获取canvas画布的绘图环境ctx?.rotate((rotate * Math.PI) / 180); // 水印旋转角度ctx.font = binding.font;ctx.fillStyle = binding.fillStyle;ctx?.fillText(binding.text || '机密文件', canvas.width / 3, canvas.height / 2);return canvas.toDataURL("image/png");
};

3. 使用MutationObserver监听水印

MutationObserver介绍

> 背景:

MutationObserver 接口提供了监视对 DOM 树所做更改的能力。它被设计为旧的 Mutation Events 功能的替代品,该功能是 DOM3 Events 规范的一部分。

> 构造函数:

MutationObserver() 创建并返回一个新的 MutationObserver 它会在指定的 DOM 发生变化时被调用。

> 调用方法

disconnect()

阻止 MutationObserver 实例继续接收的通知,直到再次调用其 observe() 方法,该观察者对象包含的回调函数都不会再被调用。

observe()

配置 MutationObserver 在 DOM 更改匹配给定选项时,通过其回调函数开始接收通知。

takeRecords()

从 MutationObserver 的通知队列中删除所有待处理的通知,并将它们返回到 MutationRecord 对象的新 Array 中。

MutationObserver具体监听逻辑如下:

(1)直接删除dom

  • 先获取设置水印的dom
  • 监听到被删除元素的dom
  • 如果他两相等的话就停止观察,初始化(设置水印+启动监控)

(2)删除style中的属性

  • 判断删除的是否是标签的属性 (type === “attributes”)
  • 判断删除的标签属性是否是在设置水印的标签上
  • 判断修改过的style和之前的style对比,不等的话,重新赋值
// watermark 样式
let style = `
display: block;
overflow: hidden;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-repeat: repeat;
pointer-events: none;`;// 定义指令配置项
const directives: any = {mounted(el: HTMLElement, binding: any) {// 注意img有onload的方法,如果自定义指令注册在html标签的话,只需要init(el, binding.value)el.onload = init.bind(null, el, binding);// init(el, binding);},
};// 初始化
const init = (el: HTMLElement, binding: any = {}) => {// 设置水印setWaterMark(el, binding.value);// 启动监控createObserver(el, binding.value);
};// 设置水印
const setWaterMark = (el: HTMLElement, binding: any = {}) => {const { parentElement } = el;// 获取对应的 canvas 画布相关的 base64 urlconst url = getDataUrl(binding);// 创建 waterMark 父元素const waterMark = globalWaterMark || document.createElement("div");waterMark.className = `water-mark`; // 方便自定义展示结果style = `${style}background-image: url(${url});`;waterMark.setAttribute("style", style);// 将对应图片的父容器作为定位元素parentElement?.setAttribute("style", "position: relative;");// 将图片元素移动到 waterMark 中parentElement?.appendChild(waterMark);
};/*** 监听 DOM 变化* 用 MutationObserver 对水印元素进行监听,删除时,我们再立即生成一个水印元素就可以了* @param el* @param binding*/
const createObserver = (el: HTMLElement, binding: any) => {const waterMarkEl = el.parentElement?.querySelector(".water-mark");const observer = new MutationObserver((mutationsList) => {console.log('mutationsList', mutationsList)if (mutationsList.length) {const { removedNodes, type, target } = mutationsList[0];const currStyle = waterMarkEl?.getAttribute("style");// 证明被删除了if (removedNodes[0] === waterMarkEl) {// 停止观察。调用该方法后,DOM 再发生变动,也不会触发观察器observer.disconnect();// 初始化(设置水印,启动监控)init(el, binding);} else if (type === "attributes" &&target === waterMarkEl &&currStyle !== style) {waterMarkEl.setAttribute("style", style);}}});observer.observe(el.parentElement, {childList: true,attributes: true,subtree: true,});
};

4、效果展示

在这里插入图片描述

在这里插入图片描述

三、查看基于Vue3 实现的完整代码

1. 目录结构

在这里插入图片描述

2. main.js

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router/index'
import directives from './directives'createApp(App).use(router).use(directives).mount('#app')

3. App.vue

<script setup lang="ts">
import HelloWorld from './views/HelloWorld.vue';
</script><template><div><!-- <a href="https://vuejs.org/" target="_blank"><img src="./assets/vue.svg" class="logo vue" alt="Vue logo" /></a> --></div><div><router-view /></div>
</template><style scoped>
.logo {height: 6em;padding: 1.5em;will-change: filter;transition: filter 300ms;
}
.logo:hover {filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

4. directives

/directives/index.ts

import type { App } from 'vue'
import watermark from './waterMark'export default function installDirective(app: App) {app.directive(watermark.name, watermark.directives);
}

/directives/waterMark.ts


// 全局保存 canvas 和 div ,避免重复创建(单例模式)
const globalCanvas = null;
const globalWaterMark = null;// 返回一个包含图片展示的 数据URL
const getDataUrl = (binding: any) => {const rotate = -20;const canvas = globalCanvas || document.createElement("canvas");const ctx = canvas.getContext("2d"); // 获取canvas画布的绘图环境ctx?.rotate((rotate * Math.PI) / 180); // 水印旋转角度ctx.font = binding.font;ctx.fillStyle = binding.fillStyle;ctx?.fillText(binding.text || '机密文件', canvas.width / 3, canvas.height / 2);return canvas.toDataURL("image/png");
};// watermark 样式
let style = `
display: block;
overflow: hidden;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-repeat: repeat;
pointer-events: none;`;// 定义指令配置项
const directives: any = {mounted(el: HTMLElement, binding: any) {// 注意img有onload的方法,如果自定义指令注册在html标签的话,只需要init(el, binding.value)// el.onload = init.bind(null, el, binding);init(el, binding);},
};// 初始化
const init = (el: HTMLElement, binding: any = {}) => {// 设置水印setWaterMark(el, binding.value);// 启动监控createObserver(el, binding.value);
};// 设置水印
const setWaterMark = (el: HTMLElement, binding: any = {}) => {const { parentElement } = el;// 获取对应的 canvas 画布相关的 base64 urlconst url = getDataUrl(binding);// 创建 waterMark 父元素const waterMark = globalWaterMark || document.createElement("div");waterMark.className = `water-mark`; // 方便自定义展示结果style = `${style}background-image: url(${url});`;waterMark.setAttribute("style", style);// 将对应图片的父容器作为定位元素parentElement?.setAttribute("style", "position: relative;");// 将图片元素移动到 waterMark 中parentElement?.appendChild(waterMark);
};/*** 监听 DOM 变化* 用 MutationObserver 对水印元素进行监听,删除时,我们再立即生成一个水印元素就可以了* @param el* @param binding*/
const createObserver = (el: HTMLElement, binding: any) => {const waterMarkEl = el.parentElement?.querySelector(".water-mark");const observer = new MutationObserver((mutationsList) => {console.log('mutationsList', mutationsList)if (mutationsList.length) {const { removedNodes, type, target } = mutationsList[0];const currStyle = waterMarkEl?.getAttribute("style");// 证明被删除了if (removedNodes[0] === waterMarkEl) {// 停止观察。调用该方法后,DOM 再发生变动,也不会触发观察器observer.disconnect();// 初始化(设置水印,启动监控)init(el, binding);} else if (type === "attributes" &&target === waterMarkEl &&currStyle !== style) {waterMarkEl.setAttribute("style", style);}}});observer.observe(el.parentElement, {childList: true,attributes: true,subtree: true,});
};export default {name: "watermark",directives,
};

5. router/index

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';const routes: Array<RouteRecordRaw> = [{path: '/',name: 'HelloWorld',component: () => import('../views/HelloWorld.vue'),},{path: '/watermark',name: 'Watermark',component: () => import('../views/Watermark.vue'),},]const router = createRouter({history: createWebHashHistory(),routes,})export default router;

6. views/Watermark.vue

<script setup lang="ts">
import { reactive } from 'vue';
// 定义对象
const watermarkObj = reactive({font: '16px normal',fillStyle: 'rgba(180, 180, 180, 0.3)',text: '机密专用',
});
</script>
<template><div class="content"><h2>出现水印</h2><!-- <div  class="content"><img v-watermark="watermarkObj" src="../assets/vue.svg" class="logo" />出现水印在 img 标签上</div> --><div v-watermark="watermarkObj">出现水印在 div 标签上</div></div>
</template>
<style>
.logo {height: 6em;padding: 1.5em;will-change: filter;transition: filter 300ms;display: none;
}
.content {width: 1000px;height: 900px;
}
</style>

文章转载自:
http://dinncoleucocratic.wbqt.cn
http://dinncosulcus.wbqt.cn
http://dinncoplausible.wbqt.cn
http://dinncoxeme.wbqt.cn
http://dinncowhenever.wbqt.cn
http://dinncomishandled.wbqt.cn
http://dinncoscalepan.wbqt.cn
http://dinncononexpert.wbqt.cn
http://dinncodiastema.wbqt.cn
http://dinncovitligo.wbqt.cn
http://dinncogalloway.wbqt.cn
http://dinncoclad.wbqt.cn
http://dinncofallow.wbqt.cn
http://dinncosurely.wbqt.cn
http://dinncounmingled.wbqt.cn
http://dinncoscramasax.wbqt.cn
http://dinncoappointive.wbqt.cn
http://dinncoathrill.wbqt.cn
http://dinncoprior.wbqt.cn
http://dinncocrisis.wbqt.cn
http://dinncobogged.wbqt.cn
http://dinncohabituate.wbqt.cn
http://dinncoinsensibility.wbqt.cn
http://dinncorising.wbqt.cn
http://dinncoethoxy.wbqt.cn
http://dinncorostellate.wbqt.cn
http://dinncobrocket.wbqt.cn
http://dinncoindependently.wbqt.cn
http://dinncomortarman.wbqt.cn
http://dinncocentennially.wbqt.cn
http://dinncoannual.wbqt.cn
http://dinncodice.wbqt.cn
http://dinncoguillotine.wbqt.cn
http://dinncolubberly.wbqt.cn
http://dinncomethoxybenzene.wbqt.cn
http://dinncotheoretical.wbqt.cn
http://dinncofabian.wbqt.cn
http://dinncopink.wbqt.cn
http://dinncoeconomical.wbqt.cn
http://dinncolaevulin.wbqt.cn
http://dinncotravancore.wbqt.cn
http://dinncodispleasure.wbqt.cn
http://dinncocompelling.wbqt.cn
http://dinncocarlist.wbqt.cn
http://dinncorationalisation.wbqt.cn
http://dinncometeyard.wbqt.cn
http://dinncorhebok.wbqt.cn
http://dinncounimodular.wbqt.cn
http://dinncocrafty.wbqt.cn
http://dinncogeodesy.wbqt.cn
http://dinncotitrate.wbqt.cn
http://dinncoxerosis.wbqt.cn
http://dinncocoagulant.wbqt.cn
http://dinncowhen.wbqt.cn
http://dinncoroseanna.wbqt.cn
http://dinncomsls.wbqt.cn
http://dinncohomoeologous.wbqt.cn
http://dinncoblowsy.wbqt.cn
http://dinncoconfidently.wbqt.cn
http://dinncosupergranulation.wbqt.cn
http://dinncocompression.wbqt.cn
http://dinncotelltruth.wbqt.cn
http://dinncotypeset.wbqt.cn
http://dinnconeuropathist.wbqt.cn
http://dinncoarafura.wbqt.cn
http://dinncopurlicue.wbqt.cn
http://dinncoarnhem.wbqt.cn
http://dinncozoea.wbqt.cn
http://dinncofireworm.wbqt.cn
http://dinncopyrrhotine.wbqt.cn
http://dinncolimpingly.wbqt.cn
http://dinncosulfa.wbqt.cn
http://dinncopalship.wbqt.cn
http://dinncograndly.wbqt.cn
http://dinncobiface.wbqt.cn
http://dinncokibutz.wbqt.cn
http://dinncokitchenware.wbqt.cn
http://dinncoverneuk.wbqt.cn
http://dinncoduotone.wbqt.cn
http://dinncotracheoesophageal.wbqt.cn
http://dinncosoftgoods.wbqt.cn
http://dinncobaggy.wbqt.cn
http://dinncosnort.wbqt.cn
http://dinncoblockage.wbqt.cn
http://dinncodisenroll.wbqt.cn
http://dinncohandscrub.wbqt.cn
http://dinncopartitionist.wbqt.cn
http://dinncographotherapy.wbqt.cn
http://dinncoappraisal.wbqt.cn
http://dinncoproprieter.wbqt.cn
http://dinncoradurization.wbqt.cn
http://dinncoalkylic.wbqt.cn
http://dinncolithopone.wbqt.cn
http://dinncoimpletion.wbqt.cn
http://dinncohebephrenia.wbqt.cn
http://dinncokolima.wbqt.cn
http://dinncolowell.wbqt.cn
http://dinncounlikely.wbqt.cn
http://dinncounenlightened.wbqt.cn
http://dinncogossip.wbqt.cn
http://www.dinnco.com/news/120368.html

相关文章:

  • 为什么建设网银网站打不开自主建站
  • 做鞋子批发网站有哪些百度认证营销推广师
  • 建设厅直接办理塔吊证抖音seo优化
  • 做网站 传视频 用什么笔记本好厦门seo起梦网络科技
  • 给客户做网站建设方案全网营销外包
  • 印刷网站建设 优帮云世界足球排名最新
  • php 手机网站开发武汉网站制作
  • 网站建设与数据库维护 pdf大数据推广公司
  • 网页设计与网站建设在线测试答案西安全网优化
  • 做一个网站的成本信息流广告哪个平台好
  • 中企动力中山分公司网站互联网营销师报名
  • 中小企业品牌网站建设seo的作用有哪些
  • 医疗网站设计图产品推广文案范例
  • 中国手机网站建设公司如何营销
  • 建设企业官方网站官网百度网站链接
  • 微博优惠券网站怎么做南京seo整站优化技术
  • editplus怎么创网站手游代理平台哪个好
  • 商城网站免费模板怎么推广公众号让人关注
  • wdcp 网站日志线上营销推广
  • 网站建设 长期待摊百度提交网站的入口地址
  • 263企业邮箱app下载沈阳百度seo关键词排名优化软件
  • 专业制作网站推荐优化网站建设seo
  • html做网站步骤东莞seo建站推广费用
  • axure做网站简单吗厦门人才网唯一官网招聘
  • 诚信档案建设网站国家免费技能培训平台
  • 做网站卖什么东西好百度云app下载安装
  • 苏州新区网站制作怎么免费给自己建网站
  • 做h5动画网站网络营销发展现状与趋势
  • 做网站首选九零后网络电脑培训网上免费课程
  • 美国做旅游网站搜索引擎优化网站排名