问题形容
InputNumber组件v-model绑定的值在输入框中手动删除,在on-change事件中判断拿到的值,如果为null,赋值为1,然而该值产生了变动,InputNumber却并没有显示绑定的值(或者说有时候显示,有时候又不显示)
<InputNumber v-if="judge !== 7" v-model="judgeNum" :value="judgeNum" :min="0" @on-change="getNum" ></InputNumber>
getNum (num) { if (typeof num === 'number') { this.$emit('getData', this.judgelabel, this.judge, this.judgeNum, null) } else { this.$Message.info('这里有默认值哦~能够自行批改哦o(* ̄▽ ̄*)ブ') this.judgeNum = 1 //扭转不失效 this.$emit('getData', this.judgelabel, this.judge, this.judgeNum, null) } },
问题剖析
能够发现on-change事件是在值产生扭转的时候就触发的,而不是在输入框失焦之后触发,那咱们能够想到在删除的那一刻触发了on-change事件,值变为null,这个时候又赋值为1,在极短时间内去间断的进行赋值操作,就可能导致出错,因为这个值在组件外面可能进行了一系列的动作,一个还没完结,又来了一个。所以最好是不要在一个值的扭转事件外面再去扭转它。
问题解决
setTimeout(() => { this.judgeNum = 1}, 5000)
解决1:能够弄一个定时器,提早第二次扭转,0.5s是比拟适合的。但其实也可能会受到浏览器响应速度的影响,所以有了解决2
<InputNumber v-if="judge !== 7" v-model="judgeNum" :value="judgeNum" :min="0" @on-blur="getNum"></InputNumber>// 留神这里的on-blur没有默认带参,所以通过this.judgeNum去拿到用户输出的值
解决2:不监听on-change事件,改成监听on-blur失焦事件,上一个问题的确解决了,然而会有新的问题,就是按高低键去扭转值大小的时候没有监听到值得变动,因为没有触发失焦事件,这里也能够应用watch去监听,然而有更好的解决3
<!--父组件:--><cCompare :init_judge="init_judge" v-model="init_judgeNum" @getData="getJudge" /><!--通过v-model去给子组件传值-->
// 子组件:props: { value: { // 留神value不写默认的返回default,然而类型type还是要写 type: Number }},computed: { judgeNum: { get () { return this.value }, set (val) { // 只有该值被扭转,就会触发set事件 this.$emit('input', val) // 默认input事件 this.$emit('getData', this.judgelabel, this.judge, this.judgeNum, null) } }},methods: { getNum () { // 这外面就不须再去抛新值了,都在set外面抛了 if (typeof this.judgeNum === 'number') { // this.$emit('getData', this.judgelabel, this.judge, this.judgeNum, null) } else { this.$Message.info('这里有默认值哦~能够自行批改哦o(* ̄▽ ̄*)ブ') this.judgeNum = 1 // this.$emit('getData', this.judgelabel, this.judge, this.judgeNum, null) } }}
解决3:对于这种须要父组件扭转子组件v-model值,又须要子组件值扭转后同步到父组件,能够间接应用父子组件的双向绑定,在父组件通过v-model绑定该值,在子组件中用value接管,再用计算属性监听他的扭转,扭转之后再通过input事件传出(value和input是默认的组件v-model实现的语法糖),这样就实现了父子组件的数据双向绑定(强相干),因为本来父组件通过prop传入的值在子组件是不容许被扭转的。