Vue watch 观察自己,修改自己
· 阅读需 3 分钟
自己在做 Vue 项目中,有个需求是输入数字,我用的 <input type="number" v-model="text" />
来实现自动展示数字键盘。
此时有个问题,maxlength
属性是不生效的。所以我对它进行了 watch
,超过一定长度,就进行截断。
我突然发现一个问题,使用 watch
来观察数值,此时还可以修改数值吗?
看下面一段代码:
<template>
<div id="app">
<p>{{ num }}</p>
</div>
</template>
<script>
export default {
data() {
return {
num: 0
}
},
watch: {
num(val, oldVal) {
console.log("num-changed: %i->%i", oldVal, val)
if (val < 3) {
console.log("in-if: val=%i", val)
this.num++
}
},
},
created() {
setTimeout(() => {
this.num = 1
}, 3000)
},
}
</script>
逻辑很简单:
- 默认
num
初始化0
,3 秒后变成1
。 - 观察
num
,如果变化就打印日志。 - 此外,如果不大于
3
,那么进行自增。
观察日志,得到:
num-changed: 0->1
in-if: val=1
num-changed: 1->2
in-if: val=2
num-changed: 2->3
是符合逻辑预期的。
也就是说,在观察中修改当前数值,是完全可行的。不过必须做好中断逻辑,否则会死循环。
这类问题本质在于 Vue 的 v-model
并不是严格双向绑定。虽然可以理解为以下写法,用户输入的内容同步到数据上,修改的数据反映到输入元素上:
<input :value="text" @input="onInput">
比如下面的例子:
<template>
<input :value="text"/>
</template>
<script>
export default {
data() {
return {
text: 'abc'
}
}
}
</script>
很明显的,输入框绑定了 text
的值,但是实际输入框是可以输入的,之后,会发生输入框显示内容和实际绑定的 text
不符的情况。
至于输入框绑定问题,得好好花时间研究下,之前的文章感觉质量还是不够。