vue自定义指令
基本的生命周期
参考官方文档:
v-download
下载文件指令
思路:
- 通过指令传入地址,然后对地址进行格式匹配。
- 符合正则的则为标准格式的地址,不符合的则添加约定的前缀
- 创建a标签,调用a标签的点击事件。
- 删除a标签。
bug:某些浏览器下载图片的,会直接在新的窗口打开图片。这是a标签下载的缺陷。
const portReg = /(http|https):\/\/([\w.]+\/?)\S*/; //地址格式匹配
const baseUrl = process.*env*.VUE_APP_REQUEST_URL; // 不同环境下,文件的前缀不同
const createElementA = (url) => {// 如果后端地址没有前缀,添加路径前缀
if (!portReg.test(url)) {
url = baseUrl + url;
}
const a = document.createElement("a");// 创建a标签
a.href = url;
a.download = url.split("//").pop();
a.target = "_blank";
a.click();
};
export default {
bind(el, binding) {
el.addEventListener("click", () => {
const urlStr = binding.value;
const urls = urlStr.split(",");
if (urls.length === 0) return false;
urls.forEach((url) => {
createElementA(url.trim());
});
});
},
unbind(el) {
el.removeEventListener("click", el.handler);
},
};
// 调用方式
<span v-download="path" class="current">下载</span>
v-loadImg
目标:图片地址为空或者路径错误,统一显示默认图片,而不是裂开的图片框。
思路:当触发img 的onerror事件后,将地址替换为事先设置的默认图片
const errorImg = require("@/assets/error.png");//项目中设置的默认图片
export default {
bind(el, binding) {
const src = binding.value;
el.src = src;
el.onerror = function () {
el.src = errorImg;
};
},
};
<img v-loadImg="isShow" alt="" class="cus-home_logo" />
v-trimStartEnd
目标:失去焦点后,删除输入框的两端空格。 思路:给input添加change事件,输入完成后,trim删除两端空格,重新赋值
export default {
inserted(el, binding, vNode) {
el.addEventListener('change', (e) => {
const { value } = e.target;
const newValue = value.trim();
if (vNode.data.model) {
vNode.data.model.callback(newValue);
} else {
e.target.value = newValue;
}
});
},
};
<input v-model='value' v-trimStartEnd="value">
v-limitMaxLength
目标:限制输入框可输入的长度 思路:输入过程中检查输入长度,超出长度后,基于提醒,并截取规定的最大长度。
import Vue from 'vue';
const that = new Vue();
export default {
inserted(el, binding, vnode) {
el.addEventListener('input', (e) => {
const { arg = 0 } = binding;
const argInt = parseInt(arg, 10);
const { value } = e.target;
if (value.length > argInt) {
that.$message.error(`该字段不能超出${arg}个字符`);
if (vnode.data.model) {
vnode.data.model.callback(value.substring(0, argInt));
} else {
e.target.value = value.substring(0, argInt);
}
}
});
},
};
<input v-model='value' v-limitMaxLength:50="value">
如果要解决输入法的超出问题,可以在添加一个change事件,事件的方法和input事件一致。用于输入完成后,在截取最长字段。