import Vue from "vue"; import utils from "@/utils.js"; import FormMath from "@/math.js"; import hljs from "highlight.js"; const directive = {}; directive.install = (Vue, opts = {}) => { // 代码高亮指令 Vue.directive('highlight', { componentUpdated: function (el) { setTimeout(() => { let blocks = el.querySelectorAll('pre code'); if (blocks && blocks.constructor === Array) { blocks.forEach((block) => { hljs.highlightBlock(block) }) } }, 1); } }); // 表单tr中根据隐藏字段动态合并单元格的指令 Vue.directive('permit', function (el, binding) { if (el.tagName !== "TR") { throw "v-permit指令只能用在tr元素上."; } if (!binding.value || binding.value.constructor !== Number) { throw "v-permit指令的值只能是大于0的数字."; } el.removeAttribute("hidden"); // tr中没有子元素时,删除tr自身 if (el.cells.length == 0) { el.setAttribute("hidden", "hidden"); } else if (el.cells.length < binding.value) { let colspan = binding.value - el.cells.length + 1; // 设置colspan实现单元格合并 el.cells[el.cells.length - 1].setAttribute("colspan", colspan); } else if (el.cells.length == binding.value) { for (var i = 0, c; c = el.cells[i++];) { c.removeAttribute("colspan"); } } }); // 表单指令,会在表单的vue实例上添加一个map,用以存放数学运算的表达式 Vue.directive('form', { bind: function (el, binding, vnode) { // 修正vee-validate中对于元素上的aria-invalid属性更新的问题 const judgeAriaInvalid = (fields) => { if (!fields || fields.length == 0) { return; } const fieldInst = fields.items[0]; const includes = function (collection, item) { return collection.indexOf(item) !== -1; }; const isCheckboxOrRadioInput = function (el) { return includes(["radio", "checkbox"], el.type); }; const isCallable = function (func) { return typeof func === "function"; }; Object.getPrototypeOf(fieldInst).constructor.prototype.updateAriaAttrs = function updateAriaAttrs() { var this$1 = this; if (!this.aria || !this.el || !isCallable(this.el.setAttribute)) { return; } var applyAriaAttrs = function (el) { el.setAttribute("aria-required", this$1.isRequired ? "true" : "false"); el.setAttribute("aria-invalid", this$1.flags.invalid ? "true" : "false"); // 组件初次加载时,既不显示验证失败也不显示验证成功 if (this$1.flags.invalid == null) { el.removeAttribute("aria-invalid"); } }; if (!isCheckboxOrRadioInput(this.el)) { applyAriaAttrs(this.el); return; } var els = document.querySelectorAll('input[name="' + this.el.name + '"]'); toArray(els).forEach(applyAriaAttrs); } } const inst = vnode.context; inst.$root.$validator && judgeAriaInvalid(inst.$root.$validator.fields); if (inst && !inst.hasOwnProperty("watchMap")) { inst["watchMap"] = new Map(); } } }); // 判断输入框是否作为计算字段,是则添加监听 Vue.directive('express', { componentUpdated: function (el, binding, vnode) { const inst = vnode.context; if (!inst.$vnode.data.model) { return; } let elAttr = inst.$vnode.data.model.expression; if (inst.$vnode && inst.$vnode.componentOptions && inst.$vnode.componentOptions.propsData && inst.$vnode.componentOptions.propsData.modelExpression) { elAttr = inst.$vnode.componentOptions.propsData.modelExpression; } if (elAttr && !inst._expressInit) { inst._expressInit = true; // 子表每一行数据作用域所在的dom元素 let { subScopeEl } = utils.getSubScopeElAndIndex(el); let subname = null; let aliasElAttr = null; // 子表数据,需要找到配置了data-subname的元素 if (subScopeEl) { subname = subScopeEl.dataset["subname"]; if (!subname) { throw ("无法获取到当前子表前缀"); } const elAttrAry = elAttr.split("."), elAttrArySize = elAttrAry.length; if (elAttrArySize < 1) { throw `子表中的数据绑定表达式${elAttr}错误`; } aliasElAttr = `${subname}.${elAttrAry[elAttrArySize - 1]}`; } const p = utils.getOnlineFormInstance(inst); if (p.watchMap && (p.watchMap.has(elAttr) || p.watchMap.has(aliasElAttr))) { if (!inst._watchers.some(m => m.expression === 'inputVal')) { inst.$watch("inputVal", function (newVal, oldVal, farewell) { if (newVal !== oldVal) { const elAttrExpList = p.watchMap.get(elAttr) || []; const aliasElAttrExpList = p.watchMap.get(aliasElAttr) || []; const unionExpList = elAttrExpList.concat(aliasElAttrExpList); const attrExpObj = {}; unionExpList.forEach(item => { let result = 0; const t = item.target; const targetList = attrExpObj[t] || []; if (targetList.indexOf(item.exp) < 0) { targetList.push(item.exp); attrExpObj[t] = targetList; if (subScopeEl && t.split(".").length == 2) { const index = subScopeEl.dataset["index"]; if (index === undefined) { throw ("获取不到当前子表行的索引,无法完成计算."); } result = FormMath.calcSubExpValue(item.exp, p, subname, index); p.$emit(t, { result, index }); } else { result = FormMath.calcExpValue(item.exp, p); p.$emit(t, { result }); } } }); } }, { immediate: true }); } } } } }); // 注册一个过滤器,将byte单位的数值转换为合适单位的数值返回 Vue.filter("computerSize", function renderSize(value) { if (null == value || value == '') { return "0 Bytes"; } var unitArr = new Array("Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"); var index = 0; var srcsize = parseFloat(value); index = Math.floor(Math.log(srcsize) / Math.log(1024)); var size = srcsize / Math.pow(1024, index); size = size.toFixed(2);//保留的小数位数 return size + unitArr[index]; }); Vue.filter('dateformat', function (dataStr, pattern = 'yyyy-MM-dd hh:mm:ss') { if (dataStr) { if (pattern == 'yyyy-MM-dd hh:mm:ss') { pattern = 'YYYY-MM-DD HH:mm:ss'; } return new Date(dataStr).format(pattern) } else { return ""; } }); } if (typeof window !== 'undefined' && window.Vue) { directive.install(window.Vue); } export default directive;