使用计算 setter 时的 Vue v-model 问题

Vue v-model issue when using a computed setter

我想创建一个用户可以填写的输入字段。问题是我不希望他们用特殊字符填写此字段。目前,我有这个 html 设置:

    <input class="rc-input-editing" id="bioInput" type="text" v-model="wrappedBioName">

还有这个 Vue.js 设置(如您所见,我正在尝试使用计算 setter 来解决这个问题):

    data () {
      return {
        newBioName: '',
      }
    },
    computed: {
      wrappedBioName: {
        get () {
          alert('getting new name!')
          return this.newBioName
        },
        set: function (newValue) {
          const restrictedChars = new RegExp('[.*\W.*]')
          if (!restrictedChars.test(newValue)) {
            this.newBioName = newValue
          }
        }
      }

目前,我的问题是客户端能够继续填写文本输入字段,即使 this.newBioName 没有更新。换句话说,他们能够在输入字段中输入特殊字符,即使 this.newBioName 没有使用这些特殊字符进行更新。

鉴于我目前对 v-model 的理解,此行为与我的预期不同。根据我到目前为止所读的内容,v-model 将输入元素绑定到一些 vue 实例数据,并将该 vue 实例数据绑定到输入元素(双向绑定)。因此,我期望文本输入字段中的文本将直接匹配 this.newBioName.

的值

显然,我遗漏了一些东西,希望能有第二双眼睛!

Vue.js 双向绑定系统没有像您预期的那样工作。每个绑定过程每次都以一种方式工作。所以,你应该做的就是不要让输入文本发生变化。

尝试按键事件而不是像这样计算 属性:

<input class="rc-input-editing" id="bioInput" type="text" v-model="newBioName" @keypress="nameKeyPressAction">
data() {
    return {
        newBioName: ""
    };
},
methods: {
    nameKeyPressAction(event) {
        const restrictedChars = new RegExp("[.*\W.*]");
        const newValue = this.newBioName + event.key;
        if (!restrictedChars.test(newValue))
            this.newBioName = newValue;
        return event.preventDefault();
    }
}

编辑:

当您将数据 属性 或计算的 属性 设置为输入的 v 模型时,vue 会将它们关联起来,但是,如果用户通过输入更新 dom 对象, 属性的setter被触发,流程到此结束。另一方面,当你改变 javascript 端的 属性 的值时,vue 更新 dom 对象,这个过程也到此结束。

在您的示例代码中,您似乎希望计算出的 属性 的 getter 再次设置 dom 但它不能。 属性 已经通过 dom 更改更新,它不能再更新它。否则,可能会出现死循环。