资讯专栏INFORMATION COLUMN

Vue Form Input Bindings Fail ?

pkwenda / 1055人阅读

Blog Address

Preface

When I was using form validate in Vue, I found sometimes vue doesn"t render data which was modified by me. I even thought it was a bug. Anyway, let"s take a look.

Main

Here is a simple demo:

html,
body {
  width: 100%;
  height: 100%;
}

.app {
  width: 100%;
  height: 100%;
}
  

{{positiveNumResTip}}{{positiveNum}}

let app = new Vue({
  el: "#app",
  data: {
    positiveNumTip: "please enter a positive num",
    positiveNum: "",
    positiveNumResTip: "validated and modified result: "
  },
  methods: {
    oldValidate(event) {
      let value = event.target.value
      let reg = /^[d]+[.]?[d]*$/
      let newVal = Number.parseFloat(value)
      if (!value.match(reg)) {
        if (!isNaN(newVal) || newVal > 0) {
          this.positiveNum = newVal
        } else {
          this.positiveNum = 1
        }
      } else {
        this.positiveNum = value
      }
    }
  }
})

When I was pressing _ffffdffffdffffdd_, what did I got?

The first letter was replaced to 1 but the others not. And the most important is the result I got is always 1 which means this.positiveNum is 1 while the value in the input is not 1.

Why?

I even thought it was a bug until one day I met a similar problem which was solved in SO.

The key is the Lifecycle. The guide mentions it before but I didn"t understand it until now. Let"s see the picture again:

See?

The first time we change positiveNum to 1 and then we always change positiveNum to 1. So, vue wouldn"t re-render because the data doesn"t change. So, the connection between input and positiveNum was cut off until positiveNum isn"t equal to 1.

We can add updated to see how many times data has changed:

let app = new Vue({
  el: "#app",
  data: {
    positiveNumTip: "please enter a positive num",
    positiveNum: "",
    positiveNumResTip: "validated and modified result: "
  },
  methods: {
    oldValidate(event) {
      let value = event.target.value
      let reg = /^[d]+[.]?[d]*$/
      let newVal = Number.parseFloat(value)
      if (!value.match(reg)) {
        if (!isNaN(newVal) || newVal > 0) {
          this.positiveNum = newVal
        } else {
          this.positiveNum = 1
        }
      } else {
        this.positiveNum = value
      }
    }
  },
  updated() {
    console.log("data updated") //only triggered once
  }
})

As explained before, you can only see "data updated" once.

So, how can we solved this problem?

The key is still the Lifecycle. Vue wouldn"t re-render because data doesn"t change. So, we can update data after data has been changed and rendered. Understood? See code below:

  

{{positiveNumResTip}}{{positiveNum}}

let app = new Vue({
  el: "#app",
  data: {
    positiveNumTip: "please enter a positive num",
    positiveNum: "",
    positiveNumResTip: "validated and modified result: "
  },
  methods: {
    oldValidate(event) {
      let value = event.target.value
      let reg = /^[d]+[.]?[d]*$/
      let newVal = Number.parseFloat(value)
      if (!value.match(reg)) {
        if (!isNaN(newVal) || newVal > 0) {
          this.positiveNum = newVal
        } else {
          this.positiveNum = 1
        }
      } else {
        this.positiveNum = value
      }
    },
    newValidate(event) {
      let value = event.target.value
      let reg = /^[d]+[.]?[d]*$/
      this.positiveNum = value
      this.$nextTick(() => {
        if (!this.positiveNum.match(reg)) {
          let newVal = Number.parseFloat(this.positiveNum)
          if (!isNaN(newVal) || newVal > 0) {
            this.positiveNum = newVal
          } else {
            this.positiveNum = "" //for better use I changed the wrong value to ""
          }
        }
      })
    }
  },
  updated() {
    console.log("data updated")
  }
})

See? I move the origin logic to the this.$nextTick(callback). Every time you press the wrong button, it will pass the wrong value to positiveNum and will be corrected in this.$nextTick(callback) which will make the logic run correctly. Also, you can see the updated log at the console.

Ending Reference

change child-component checked state from parent-component synchronously fail

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108820.html

相关文章

  • JavaScript 是如何工作的:编写自己的 Web 开发框架 + React 及其虚拟 DOM

    摘要:与大多数全局对象不同,没有构造函数。为什么要设计更加有用的返回值早期写法写法函数式操作早期写法写法可变参数形式的构造函数一般写法写法当然还有很多,大家可以自行到上查看什么是代理设计模式代理模式,为其他对象提供一种代理以控制对这个对象的访问。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 19 篇。 如果你错过了前面的章节,可以在这里找到它们: 想阅读更多优质文章请...

    余学文 评论0 收藏0
  • 构建利用Proxy和Reflect实现双向数据绑定的微框架(基于ES6)

    摘要:写在前面这篇文章讲述了如何利用和实现双向数据绑定,个人系早期玩家,写这个小框架的时候也没有参考等源代码,之前了解过其他实现,但没有直接参考其他代码,如有雷同,纯属巧合。我们同时也应该支持事件机制,这里我们以最常用的方法作为例子实现。 写在前面:这篇文章讲述了如何利用Proxy和Reflect实现双向数据绑定,个人系Vue早期玩家,写这个小框架的时候也没有参考Vue等源代码,之前了解过其...

    elliott_hu 评论0 收藏0
  • 构建利用Proxy和Reflect实现双向数据绑定的微框架(基于ES6)

    摘要:写在前面这篇文章讲述了如何利用和实现双向数据绑定,个人系早期玩家,写这个小框架的时候也没有参考等源代码,之前了解过其他实现,但没有直接参考其他代码,如有雷同,纯属巧合。我们同时也应该支持事件机制,这里我们以最常用的方法作为例子实现。 写在前面:这篇文章讲述了如何利用Proxy和Reflect实现双向数据绑定,个人系Vue早期玩家,写这个小框架的时候也没有参考Vue等源代码,之前了解过其...

    LuDongWei 评论0 收藏0
  • 构建利用Proxy和Reflect实现双向数据绑定的微框架(基于ES6)

    摘要:写在前面这篇文章讲述了如何利用和实现双向数据绑定,个人系早期玩家,写这个小框架的时候也没有参考等源代码,之前了解过其他实现,但没有直接参考其他代码,如有雷同,纯属巧合。我们同时也应该支持事件机制,这里我们以最常用的方法作为例子实现。 写在前面:这篇文章讲述了如何利用Proxy和Reflect实现双向数据绑定,个人系Vue早期玩家,写这个小框架的时候也没有参考Vue等源代码,之前了解过其...

    时飞 评论0 收藏0
  • Vue.js Guide Essentials-说人话-速记版

    摘要:以下内容根据部分速记。同时,需要在父组件标签中添加这个属性,该属性才能传递到子组件内。把父组件传递的数据当做子组件的初始值。 以下内容根据Vue.js Guide Essentials部分速记。 不含动画/mixin/SSR/路由/状态管理等部分. Introduction 建议阅读原文 https://vuejs.org/v2/guide/in... 什么是Vue 开始 声明式...

    Sanchi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<