1.el-input 输入框,只能输入数字,并且可限制上下限,保留小数位数
- 1.输入的不是数字失去焦点时值会被清空【包括科学计数法 e 也不能输入】
- 2.可配置输入值的范围,超出范围给出提示并清空
- 3.可配置小数位数
import { Message } from 'element-ui';
// 判断值是否为空,注意:0是有值的
function isNUll(val) {
return val === null || val === void 0 || val === '' || val.toString() === 'NaN';
}
/**
* author: yf
* date: 20241212
* 对input type="number" 类型输入框的扩展,
* 1.输入的不是数字失去焦点时值会被清空【包括科学计数法 e 也不能输入】
* 2.可配置输入值的范围,超出范围给出提示并清空
* 3.可配置小数位数
*
* 注意搭配 type="number" 使用效果最佳
* 使用方式:
*
* 方式一:使用默认配置,只是限制了输入的只能是数字【包括e也不能输入】,不然会被清空
* v-number-input-extend
*
* 方式二:带参数,注意: 所有参数都是可选
* v-number-input-extend = "{
label: 'xxx输入框', // 这个输入框的label值,用于提示
min: 0, // 输入值的最小值 - 不传则不会处理
max: 100, // 输入值的最大值 - 不传则不会处理
toFixed: 2, // 值的小数位数 - 不传则不会处理
isPrompt: true, // 不满足验证条件时是否提示,比如最大最小值的验证
isClearZero: false // 值为0时,是否置为空 - 不传则不会处理
* }"
*/
Vue.directive('number-input-extend', {
inserted(el, binding, vnode) {
// 配置
let {
label = '', // 这个输入框的label值,用于提示
min, // 输入值的最小值
max, // 输入值的最大值
toFixed, // 值的小数位数
isPrompt = true, // 不满足验证条件时是否提示,比如最大最小值的验证
isClearZero = false // 值为0时,是否置为空 - 某些场景会用到
} = binding.value || {};
let $input = vnode.componentInstance;
// 设置输入框的值,触发input事件,改变v-model绑定的值
const setVal = val => {
if ($input) {
// 如果是自定义组件就触发自定义组件的input事件
$input.$emit('input', val);
} else {
// 如果是原生组件就触发原生组件的input事件
el.value = val;
el.dispatchEvent(new Event('input'));
}
};
el._customData = {
blur: event => {
const e = event || window.event;
// 去掉非数字字符
let strVal = String(e.target.value || '').replace(/[^\-\d.]/g, '')
let val = parseFloat(strVal);
if (isNUll(val)) {
val = '';
}
if (val !== '' && !isNUll(toFixed)) {
val = Number(val.toFixed(toFixed));
}
// 值为0时,置为空
if (isClearZero && val === 0) {
val = '';
}
// #region 值范围判断
if (val !== '') {
if (!isNUll(min) && !isNUll(max)) {
if (val < min || val > max) {
val = '';
isPrompt &&
Message({
message: `${label}值的范围应该是${min}-${max}`,
type: 'warning'
});
}
} else if (!isNUll(min)) {
if (val < min) {
val = '';
isPrompt &&
Message({
message: `${label}值的最小值为${min}`,
type: 'warning'
});
}
} else if (!isNUll(max)) {
if (val > max) {
val = '';
isPrompt &&
Message({
message: `${label}值的最大值为${max}`,
type: 'warning'
});
}
}
}
// #endregion 值范围判断
e.target.value = val;
setVal(val);
}
};
el.addEventListener('focusout', el._customData.blur);
},
/* eslint-disable no-unused-vars */
unbind(el) {
// 解绑
if (el._customData && el._customData.blur) return;
el.removeEventListener('focusout', el._customData.blur);
}
});
2.div 盒子宽高变化触发resize回调
/**
* div resize
* author: yf
*/
Vue.directive('resize', {
bind: function(el, binding) {
let callbackFn = binding.value; // div resize后的回调函数
if (!callbackFn) return;
let t = binding.arg; // arg:传给指令的参数,可选。例如 v-resize:60 中,参数为 "60"
t = t === void 0 ? 100 : Number(t); // 防抖时间
// console.log(callbackFn, t)
let resizeBox = el;
let domInfo = {
width: 0,
height: 0
};
let resizeObserver = new ResizeObserver(
debounce(() => {
let oldDomInfo = domInfo;
let newDomInfo = (domInfo = getDomWH(el));
try {
// console.log('div resize ....');
callbackFn &&
callbackFn({
resizeBox: el, // 当前 resize 的dom信息
oldDomInfo, // resize 前的宽高信息
newDomInfo // resize 后的宽高信息
});
} catch (e) {
// console.error('div resize', e);
}
}, t)
); // 会在绘制前和布局后调用 resize 事件,因此不用提前调用 event_resize 方法
el._vResize = resizeObserver;
resizeObserver.observe(resizeBox);
},
unbind: function(el, binding) {
let callbackFn = binding.value; // 回调函数
if (!callbackFn) return;
let resizeBox = el;
let resizeObserver = el._vResize;
if (!resizeObserver) return;
resizeObserver.unobserve(resizeBox);
delete el._vResize;
}
});
3 input focus
/**
* author: yf
* date: 20250109
* input focus
* 注意:在 el-table 行编辑时使用此指令可能不会生效,因为 el-table 存在fixed列时,focus的是fixed table 中的 input
* */
Vue.directive('input-focus', {
inserted: function (el) {
if(el.nodeName.toLocaleLowerCase() === 'input'){
el.focus()
}else{
let input = el.querySelector('input')
input && input.focus()
}
}
});
4 el-table 内某个el-input 的 td 挂载时focus
给el-input 绑定了 blur 事件时可能用到这个指令,因为如果没触发focus是不会触发 blur 事件的
// 组件内自定义指令
directives: {
'tableIn-elInput-focus': {
// 指令的定义
inserted: function (el, binding, vnode) {
try {
let tableInx = vnode.context.$refs['MaterialTable'] // 这个el-table 节点是绑定了ref的, ref =“MaterialTable”
if(!tableInx || !tableInx.$el) return
// 因为el-table 表格在表格列 fixed 的时候会创建一模一样的节点,有以下操作为了正确定位节点:
let parentDom = tableInx.$el.querySelector('.el-table__body-wrapper')
if(parentDom && parentDom!== el && parentDom.contains(el)){
el.querySelector('.el-input__inner').focus()
}
}catch(e){
console.error('tableIn-focus', e)
}
}
}
},
若对你有帮助,请点个赞吧,若能打赏不胜感激,谢谢支持!
本文地址:http://08643.cn/p/6af71018f716,转载请注明出处,谢谢。