vue点击复制文本代码 vue文本旁边添加复制按钮使用( 二 )

使用:给 Dom 加上 v-longpress 回调函数即可
<template><button v-longpress=\"longpress\">长按</button></template> <script> export default {methods: {longpress () {alert(\'长按指令生效\')}}}</script>v-debounce背景:在开发中,有些提交保存按钮有时候会在短时间内被点击多次,这样就会多次重复请求后端接口,造成数据的混乱,比如新增表单的提交按钮,多次点击就会新增多条重复的数据 。
需求:防止按钮在短时间内被多次点击,使用防抖函数限制规定时间内只能点击一次 。
思路:

定义一个延迟执行的方法,如果在延迟时间内再调用该方法,则重新计算执行时间 。
将时间绑定在 click 方法上 。
const debounce = {inserted: function (el, binding) {let timerel.addEventListener(\'keyup\', () => {if (timer) {clearTimeout(timer)}timer = setTimeout(() => {binding.value()}, 1000)})},} export default debounce使用:给 Dom 加上 v-debounce 回调函数即可
<template><button v-debounce=\"debounceClick\">防抖</button></template> <script> export default {methods: {debounceClick () {console.log(\'只触发一次\')}}} </script>v-emoji背景:开发中遇到的表单输入,往往会有对输入内容的限制,比如不能输入表情和特殊字符,只能输入数字或字母等 。
我们常规方法是在每一个表单的 on-change 事件上做处理 。
<template><input type=\"text\" v-model=\"note\" @change=\"vaidateEmoji\" /></template> <script> export default {methods: {vaidateEmoji() {var reg = /[^u4E00-u9FA5|d|a-zA-Z|rns,.?!,。?!…—&$=()-+/*{}[]]|s/gthis.note = this.note.replace(reg, \'\')},},} </script>这样代码量比较大而且不好维护,所以我们需要自定义一个指令来解决这问题 。
需求:根据正则表达式,设计自定义处理表单输入规则的指令,下面以禁止输入表情和特殊字符为例 。
let findEle = (parent, type) => {return parent.tagName.toLowerCase() === type ? parent : parent.querySelector(type)} const trigger = (el, type) => {const e = document.createEvent(\'HTMLEvents\')e.initEvent(type, true, true)el.dispatchEvent(e)} const emoji = {bind: function (el, binding, vnode) {// 正则规则可根据需求自定义var regRule = /[^u4E00-u9FA5|d|a-zA-Z|rns,.?!,。?!…—&$=()-+/*{}[]]|s/glet $inp = findEle(el, \'input\')el.$inp = $inp$inp.handle = function () {let val = $inp.value$inp.value = https://www.fajihao.com/i/val.replace(regRule, /'\')trigger($inp, \'input\')}$inp.addEventListener(\'keyup\', $inp.handle)},unbind: function (el) {el.$inp.removeEventListener(\'keyup\', el.$inp.handle)},} export default emoji使用:将需要校验的输入框加上 v-emoji 即可
<template><input type=\"text\" v-model=\"note\" v-emoji /></template>v-LazyLoad背景:在类电商类项目,往往存在大量的图片,如 banner 广告图,菜单导航图,美团等商家列表头图等 。图片众多以及图片体积过大往往会影响页面加载速度,造成不良的用户体验,所以进行图片懒加载优化势在必行 。
需求:实现一个图片懒加载指令,只加载浏览器可见区域的图片 。
思路:
图片懒加载的原理主要是判断当前图片是否到了可视区域这一核心逻辑实现的
拿到所有的图片 Dom,遍历每个图片判断当前图片是否到了可视区范围内
如果到了就设置图片的 src 属性,否则显示默认图片
图片懒加载有两种方式可以实现,一是绑定 srcoll 事件进行监听,二是使用 IntersectionObserver 判断图片是否到了可视区域,但是有浏览器兼容性问题 。
下面封装一个懒加载指令兼容两种方法,判断浏览器是否支持 IntersectionObserver API,如果支持就使用 IntersectionObserver 实现懒加载,否则则使用 srcoll 事件监听 + 节流的方法实现 。
const LazyLoad = {// install方法install(Vue, options) {const defaultSrc = https://www.fajihao.com/i/options.defaultVue.directive(/'lazy\', {bind(el, binding) {LazyLoad.init(el, binding.value, defaultSrc)},inserted(el) {if (IntersectionObserver) {LazyLoad.observe(el)} else {LazyLoad.listenerScroll(el)}},})},// 初始化init(el, val, def) {el.setAttribute(\'data-src\', val)el.setAttribute(\'src\', def)},// 利用IntersectionObserver监听elobserve(el) {var io = new IntersectionObserver((entries) => {const realSrc = https://www.fajihao.com/i/el.dataset.srcif (entries[0].isIntersecting) {if (realSrc) {el.src = realSrcel.removeAttribute(/'data-src\')}}})io.observe(el)},// 监听scroll事件listenerScroll(el) {const handler = LazyLoad.throttle(LazyLoad.load, 300)LazyLoad.load(el)window.addEventListener(\'scroll\', () => {handler(el)})},// 加载真实图片load(el) {const windowHeight = document.documentElement.clientHeightconst elTop = el.getBoundingClientRect().topconst elBtm = el.getBoundingClientRect().bottomconst realSrc = https://www.fajihao.com/i/el.dataset.srcif (elTop - windowHeight