从零撸一个pc端vue的ui组件库( 计数器组件 )

2020-06-14 06:20:26易采站长站整理

// 不传参数的时候默认值就是undefined
// 对这个值的限制就是, max之内, min以上
if (max !== undefined && newVal > max) newVal = max;
if (min !== undefined && newVal < min) newVal = min;
// 这里兼容一下位数控制
let value = Number(newVal).toFixed(this.precision);
// 这个oldVal下面会解释:point_down:
if (value === this.oldVal) return;
this.oldVal = ls;
// 发出两个事件, 一个负责改变value, 一个负责返回给用户
// 毕竟用户不可能监听input事件然后再把值附上去, 太麻烦
this.$emit("input", value);
this.$emit("change", value);
// 这一步很重要
// 下面会详细说
this.$refs.input.value = value;
}

上面遗留的问题,这里解释一下.

oldVal: 能防止很多多余的改变, 比如说用户复制粘贴了一组数进来, 这个数大于max, 但是当时显示的数值就是max, 所以就不用渲染了, 或者v-model不止绑定了这个组件, 还绑定了其他各种组件, 导致值超出范围, 这边也会进行相应的限制, 而这个oldVal 就是上一个合法的值, 所以在做完检测之后, 检测通过的数值要赋值给他.

this.$refs.input.value = value;
这一步看似很没用, 因为输入框里面的是value, value改变input里面的值自然会改变, 但是实际测试并不是这样, 问题也是出现在v-model上, 绑定很多的时候会出现值的不改变, 可能是vue的机制问题, 而且他要放在
this.$emit(....);
下面操作, 如果放在上面会导致多次执行, 因为他的执行会循环触发input的监听事件, 多次试验之后, 还是放在这里没有bug.
上面的两个问题都是涉及到v-model的问题, 下面还有一个同类的问题, 我们来看看.

对value进行的监控

因为value的变化, 不一定全是 通过+-输入这三种方式, 还有第三方通过v-model的方式, 还有用户手动乱填的方式.


watch: {
value: {
handler() {
// 为了解决, 多组件共同v-model采用的这个方法, 也算是另辟蹊径了
let { value, time } = this;
clearTimeout(time);
// 毕竟把它放入宏任务Macrotasks可以躲过很多无限循环.
time = setTimeout(() => {
if (value !== undefined) this.emitVal(value);
});
},
// 这个是开启进页面的瞬间就出发一次的意思, 很有用, 但是数据稍大会消耗性能, 慎用
// watch还有一个deep属性, 更是吃性能吃的厉害, 可以深度监控里面的数据
immediate: true
}
}

上面的问题都是基于

v-model
的, 所以很早就有人剔除双向绑定的坏处, 封装越多的组件感觉就越明显.