写网站建设的软文,网站建设服务商排名,视频制作软件手机版,常德网站建设多少钱都是个人理解#xff0c;如果发现错误#xff0c;恳请大家批评指正#xff0c;谢谢。还有我说的会比较啰嗦#xff0c;因为是以自身菜鸡水平的视角来记录学习理解的过程#xff0c;见谅。 1.前言 产品使用vueelement作为前端框架。在功能开发过程中#xff0c;难免遇到使…都是个人理解如果发现错误恳请大家批评指正谢谢。还有我说的会比较啰嗦因为是以自身菜鸡水平的视角来记录学习理解的过程见谅。 1.前言 产品使用vueelement作为前端框架。在功能开发过程中难免遇到使用element的组件没办法满足特殊的业务需要需要对其进行定制例如要求选择器的弹出框中增加搜索过滤跟目前element的输入建议不太一样。于是想说说之前修改element组件并定制为业务组件过程中遇到的问题。
ps:因为对某些组件改动很大所以是直接拷贝了一份源码然后再进行修改但是这样会遇到挺多问题建议对于vue组件如果改动不大只是简单功能扩展就直接使用继承的方式修改。 2.clickoutside指令 element中自定义vue的指令之一clickoutside顾名思义就是当鼠标点击了指令所绑定元素的外部时就会触发绑定方法。用途就以el-select为例当选择器的下拉框展示时监听鼠标点击事件如果鼠标位置在整个选择器外部时进行隐藏下拉框。 2.1使用方式 引入Clickoutside.js
import Clickoutside from element-ui/src/utils/clickoutside 声明指令使用
directives: { Clickoutside }, 模板中正式使用
lt;div v-clickoutsidehandleClickOutsidegt;
lt;/divgt; 2.2实现介绍 简要说明下原理首先vue自定义指令本身(不了解可以点击链接查看官网介绍)。主要就是利用vue指令的功能获取所绑定元素的dom对象dom_A以及传递过来的回调方法fun_A然后监听浏览器的mousedown和mouseup事件(mousedown作为辅助信息真正触发传递的回调方法的是mouseup事件)当前事件中鼠标位置对应的dom对象dom_B不属于dom_A则代表鼠标点击了dom_A外部触发clickoutside回调方法。 2.3扩展介绍 理论上clickoutside只能也只需要绑定一个元素作为inside但是一些特殊的原因(可能是代码不够好)要求clickoutside可以选定多个元素作为inside当鼠标点击了这些元素所构成的inside的外部时再触发事件。结合下图A与B两个元素作为一个inside当鼠标点击在click1位置时触发clickoutside当鼠标点击click2或者click3位置时都不触发clickoutside。 2.3扩展实现 要实现上述功能就必须获取到A和B的dom对象然后在原先鼠标事件的监听的基础上判断鼠标位置是否都不包含在A和B中如果是的话再触发clickoutside。实现方式为在A和B的父级parent元素上绑定v-clickoutside:yourClassNamehandleClickOutside在A和B元素上添加同一个class样式样式名称与指令冒号后面内容一致classyourClassName。主要在处理指令绑定时通过binding.arg即可获取到A和B共有的class存放在dom变量中。在鼠标放开触发事件处理时通过class获取到他们的dom对象。 2.3.1使用示例 clickoutside原来的使用方式不受影响只是添加了多个元素并集作为inside的功能。引入改为自己修改后的clickoutside.js声明不变扩展功能在模板中的使用方式
lt;div v-clickoutside:exactAreaClassNamehandleClickOutsidegt;Parentlt;div classexactAreaClassNamegt;Alt;/divgt;lt;div classexactAreaClassNamegt;Blt;/divgt;
lt;/divgt; 2.3.2代码
// 引入Vue用以判断当前运行环境
import Vue from vue
// element封装的一些常用dom操作这里on可以先当做是addEventListener的封装
import { on } from element-ui/src/utils/dom
// 所有绑定了clickoutside指令的元素的dom对象数组
const nodeList []
// 用来做存放于dom对象中clickoutside相关参数对象的key
const ctx clickoutsideContextlet startClick
let seed 0
// 鼠标按下时记录此时事件信息
!Vue.prototype.$isServer amp;amp; on(document, mousedown, e gt; (startClick e))
// 鼠标松开时候遍历绑定clickoutside的节点进行判断是否在节点外部以触发回调
!Vue.prototype.$isServer amp;amp; on(document, mouseup, e gt; {nodeList.forEach(node gt; node[ctx].documentHandler(e, startClick))
})// 是否在特殊限定范围内
function ifInExact (exactElms, target1, taget2) {for (let i 0; i lt; exactElms.length; i) {let elm exactElms[i]if (elm.contains(target1) || elm.contains(taget2) || elm target1) return true}return false
}// 是否有特殊限定范围
function ifHasExact (el, exactArea) {if (!exactArea) return falsereturn el.getElementsByClassName(exactArea)
}function createDocumentHandler (el, binding, vnode) {return function (mouseup {}, mousedown {}) {if (!vnode ||!vnode.context ||!mouseup.target ||!mousedown.target ||(vnode.context.popperElm amp;amp;(vnode.context.popperElm.contains(mouseup.target) ||vnode.context.popperElm.contains(mousedown.target)))) returnlet exactElms ifHasExact(el, el[ctx].exactArea)// 如果是有特殊限定范围的则进行判断当前点击是否在 限定范围内if (exactElms) {if (ifInExact(exactElms, mouseup.target, mousedown.target)) {return}// 无特殊限定范围则判断点击是否在默认的指令所在范围内} else if (el.contains(mouseup.target) || el.contains(mousedown.target) || el mouseup.target) {return}if (binding.expression amp;amp;el[ctx].methodName amp;amp;vnode.context[el[ctx].methodName]) {vnode.context[el[ctx].methodName]()} else {el[ctx].bindingFn amp;amp; el[ctx].bindingFn()}}
}export default {bind (el, binding, vnode) {nodeList.push(el)const id seedel[ctx] {id,documentHandler: createDocumentHandler(el, binding, vnode),methodName: binding.expression,bindingFn: binding.value,// 特殊限定范围的class限定范围为该class的所有元素的并集exactArea: binding.arg}},update (el, binding, vnode) {el[ctx].documentHandler createDocumentHandler(el, binding, vnode)el[ctx].methodName binding.expressionel[ctx].bindingFn binding.value// 附加 真正起作用部分el[ctx].exactArea binding.arg},unbind (el) {let len nodeList.lengthfor (let i 0; i lt; len; i) {if (nodeList[i][ctx].id el[ctx].id) {nodeList.splice(i, 1)break}}delete el[ctx]}
}3.最后 以上就是关于clickoutside的学习和扩展。 1.引用element的popup注意事项如el-select-menu即el-select中的select-dropdown.vue。2.使用cropperjs制作头像裁剪。浏览器读取本地图片并展示仿微博头像排版裁剪后上传服务器。3.vue指令中的参数vnode学习ps: 个人GayHub后面关于前端的学习内容也会放在这里如果发现bug尽量及时改上去。 原文地址https://segmentfault.com/a/1190000014213030 转载于:https://www.cnblogs.com/lalalagq/p/9919464.html