当时业务有个需求,需要自动触焦点,并且enter键可以自动失焦且做一些逻辑,考虑到别的模块也可能有这方面的功能,所以自己做了一个这方面的指令
import Vue from 'vue';
// 自定义的基于Element-ui的el-input组件的指令 , 指令名字inputEv
Vue.directive('inputEv', {
inserted: function (el, binding, vnode) {
// 因为基于Element-ui的el-input组件的指令 ,,如果是要给原生的input设置该指令,那么 需要改为 el = el
el = el.firstElementChild;
if (binding.modifiers.focus) {
el.focus(); // 触礁
}
if (!binding.value) {
return;
} else {
let valType = Object.prototype.toString.call(binding.value);
if (valType !== '[object Object]') {
throw new Error(' Only object data types can be accepted ');
}
}
let keyboardType = ['keyEnter', 'keyEsc']; // 收集想要的key的名字
let keyboardValue = [13, 27]; // 与上面的keyboardType的keyCode一一对应
let argKeys = Object.keys(binding.value);
window.addEventListener('keydown', function (ev) {
ev = ev || event;
argKeys.forEach((key, index) => {
let hasKey = keyboardType.indexOf(key); // 判断是否有keyboardType中的键盘的英文 ,没有则不作处理
if (hasKey > -1) {
if (ev.keyCode === keyboardValue[hasKey]) { // 找到相应的 键盘的英文键位
let fn, count = 0, argList = [];
for (var keyItem in binding.value[key]) { // 遍历所有属性 ,判断是否存在函数, 且计算其数量
if (typeof binding.value[key][keyItem] === 'function') {
fn = binding.value[key][keyItem];
count++;
if (count > 1) {
throw new Error('Object property values must have one and only one function ');
}
} else {
// 值为非函数的属性 存放在一起
argList.push(binding.value[key][keyItem]);
}
}
if (count === 0) {
throw new Error(' Object property values must have one and only one function ');
}
// 值为非函数的属性作为参数被值为函数的属性调用
fn(...argList);
}
}
});
});
}
});组件内需要的指令书写格式
例子 : <input v-inputEv.focus = '{ keyEnter:{ a:()=>{} , b:b , c:c }}' />/*
格式写法 例子 : v-inputEv.focus = '{ keyEnter:{ a:()=>{} , b:b , c:c }}'
写了.focus可以让input获取焦点 , 不写就是不自动触焦
值必须是对象 , 属性名是 key+键盘上的名字 ,比如enter键就是keyEnter,esc就是keyEsc ,
对于每个属性的值,必须有且只有一个函数 , 其余随意 , 到时候会自动调用函数且其余值作为函数的参数
*/
未来如果想要监听别的键盘按钮的话,只需要添加对应的键值对就可以,
比如 :
let keyboardType = ['keyEnter', 'keyEsc' , 'keyA']; // 添加了a的监听 let keyboardValue = [13, 27, 65]; // 与上面的keyboardType的keyCode一一对应