Javascript Vue控制输入

Javascript Vue控制输入,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,我想要一个只接受数字序列的文本输入。任何其他字符都应该默默地忽略。以下是我的组件的简化版本: {{tel}} 导出默认值{ 名称:“应用程序”, 数据:()=>({ 电话:1234 }), 方法:{ 塞特尔(五){ const val=v.target.value.replace(/[^0-9]/g,“”); this.tel=val; /*this.tel=v.target.value=v.target.value.replace(/[^0-9]/g,”)*/ } } }; 在React中

我想要一个只接受数字序列的文本输入。任何其他字符都应该默默地忽略。以下是我的组件的简化版本:


{{tel}}

导出默认值{ 名称:“应用程序”, 数据:()=>({ 电话:1234 }), 方法:{ 塞特尔(五){ const val=v.target.value.replace(/[^0-9]/g,“”); this.tel=val; /*this.tel=v.target.value=v.target.value.replace(/[^0-9]/g,”)*/ } } };
在React中,有一个概念,但在Vue中,我看不出有任何相似之处

我找到的解决方法(您可以在注释中看到)是手动修改输入元素的值,但这有点违背了使用Vue的目的

我也尝试过使用
v-model
,但问题仍然存在


您可以做以下几件事:

  • 将输入的类型设置为number
    
    {{tel}}

    导出默认值{ 名称:“应用程序”, 数据:()=>({ 电话:1234 }), 方法:{ 塞特尔(五){ const val=v.target.value.replace(/[^0-9]/g,“”); this.tel=val; /*this.tel=v.target.value=v.target.value.replace(/[^0-9]/g,”)*/ } } };
    我查看了您的沙箱并做了一些修改,请检查这是否是您想要的,视图现在已更新。

    您可以使用
    ({
    电话:1234
    }),
    方法:{
    塞特尔(五){
    v、 target.value=v.target.value.replace(/[^0-9]/g,“”);
    this.tel=v.target.value
    /*this.tel=v.target.value=v.target.value.replace(/[^0-9]/g,”)*/
    }
    }
    };
    

    对于vue在输入中显示文本的部分,是因为当您在替换文本后指定相同的值时,vue不会刷新该特定元素的状态,以避免额外的渲染

    而不是处理
    键向上
    (这将允许键到达输入),您应该处理
    键向下
    。处理程序应调用并忽略该键:

    // ignore non-numeric keys
    if (!/\d/.test(v.key)) {
      v.preventDefault()
      v.stopPropagation()
      return false
    }
    
    输入应允许元键通过(例如,允许复制粘贴或删除):

    此外,此输入应处理
    input
    事件,以便过滤复制粘贴的值

    // template
    <input v-model="tel" @input="onInput" v-on:keydown="setTel" />
    
    // script
    onInput(e) {
      if (e.inputType !== 'insertText' && /[^0-9]/g.test(e.target.value)) {
        const val = e.target.value.replace(/[^0-9]/g, "");
        this.tel = val;
        e.preventDefault()
        e.stopPropagation()
        return false
      }
    }
    
    //模板
    //剧本
    输入(e){
    if(e.inputType!=='insertText'&&/[^0-9]/g.test(e.target.value)){
    const val=e.target.value.replace(/[^0-9]/g,“”);
    this.tel=val;
    e、 预防默认值()
    e、 停止传播()
    返回错误
    }
    }
    

    您通过使用“变通方法”设置输入值来回答自己的问题。 如果希望它像React控制组件一样工作,可以将目标输入的值设置为数据模型中的值,除非它实际更改了数据模型。通过这种方式,Vue数据模型将成为您唯一的真相来源

    <template>
      <div id="app">
        <input 
          v-bind:value="tel" 
          v-on:input="handleInputTel" 
          placeholder="only numbers" 
        />
        <p>{{ tel }}</p>
      </div>
    </template>
    
    <script>
    export default {
      name: "App",
      data: () => ({
        tel: "1234"
      }),
    
      methods: {
        handleInputTel(v) {
          if (validate(v.target.value)) this.tel = v.target.value; 
          else v.target.value = this.tel;
        }
      }
    };
    </script>
    
    
    {{tel}}

    导出默认值{ 名称:“应用程序”, 数据:()=>({ 电话:1234 }), 方法:{ 手动输入按钮(v){ 如果(验证(v.target.value))this.tel=v.target.value; else v.target.value=this.tel; } } };
    由于VUE的渲染策略,如果状态与旧的相同,则此输入组件不会重新渲染。但是输入DOM已经改变了。 因此,您可以在输入事件上使用$forceUpdate

    setTel(v) {
          const val = v.target.value.replace(/[^0-9]/g, "");
          this.tel = val;
          this.$forceUpdate();
        }
    
    

    试着使用
    你可以用普通的JS实现这一点,
    函数formatNumber(element){element.value=Number(element.value.replace(/[^0-9]/g')).toLocalString(未定义,{maximumFractionDigits:2}
    也可以尝试使用keyUp事件。@Boussajrahim需要使用
    type='text
    ,这种情况比我找到的解决方法更普遍,但直接修改输入元素感觉不太好。检查
    this.tel
    在示例中,您可以看到它得到了正确的值,只是视图没有更新…感谢您的努力,但在您的解决方案中,字母确实传递到输入,这不是最佳的。有时,似乎有必要使用
    this。$forceUpdate()
    使vue覆盖用户刚才键入的内容。显然,vue需要重新渲染以防止用户在输入字段中键入内容。您正在发布我在OP中提到的解决方法作为答案:)。我不希望将值分配给
    v.target.value
    ,在此处键入数字而不是点,这可以推广到任何类型的规则。
    // template
    <input v-model="tel" @input="onInput" v-on:keydown="setTel" />
    
    // script
    onInput(e) {
      if (e.inputType !== 'insertText' && /[^0-9]/g.test(e.target.value)) {
        const val = e.target.value.replace(/[^0-9]/g, "");
        this.tel = val;
        e.preventDefault()
        e.stopPropagation()
        return false
      }
    }
    
    <template>
      <div id="app">
        <input 
          v-bind:value="tel" 
          v-on:input="handleInputTel" 
          placeholder="only numbers" 
        />
        <p>{{ tel }}</p>
      </div>
    </template>
    
    <script>
    export default {
      name: "App",
      data: () => ({
        tel: "1234"
      }),
    
      methods: {
        handleInputTel(v) {
          if (validate(v.target.value)) this.tel = v.target.value; 
          else v.target.value = this.tel;
        }
      }
    };
    </script>
    
    setTel(v) {
          const val = v.target.value.replace(/[^0-9]/g, "");
          this.tel = val;
          this.$forceUpdate();
        }