b-input model has value of type string

Viewed 5406

I am trying to create a form with a number field.

<b-input v-model="testNumber" type="number"/>

On my data, I have a simple number var.

data() {
  return {
    testNumber: 10,
  }
},

However when I trace testNumber it is a string

{{ typeof testNumber }}  // String
3 Answers

You can add a modifier to the v-model.

(https://v2.vuejs.org/v2/guide/forms.html#number)

<b-form-input v-model.number="testNumber" />

UPDATE

Don't use the v-model.number this as bootstrap-vue recommens not to do so:

v-model modifiers .number and .trim can cause unexpected cursor jumps when the user is typing (this is a Vue issue with v-model on custom components). Avoid using these modifiers.

But use as b-form-input suggests:

To get around this, <b-form-input> and <b-form-textarea> have two boolean props trim and number which emulate the native Vue v-model modifiers .trim and .number respectively.

<b-form-input v-model="testNumber" :number="true" />

The type=number default return value type is string. you can see here HTML input elements are documented to return string representing a number

For changing this behavior of model value, you need to convert the your value when input is changing. Like below example

Please below code snippet :

new Vue({
  el: '#app',
 
  data() {
    return {
      number:10,
      testNumber:100
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
 <input v-model="number" type="number"/>
 <p>type of number : {{typeof number}}</p>
 
 <input v-model="testNumber" type="number" @input="e => testNumber = +e.target.value" />
 <p>type of testNumber:  {{typeof testNumber}}</p>
</div>

Bootstrap-vue example

In this example, you can use value by getting .valueAsNumber and same as above you can use +.value.

new Vue({
  el: '#app',
  methods: {
    updateVm(e) {
      this.testNumber1 = e.target.valueAsNumber;
    }
  },
  data() {
    return {
      number: null,
      testNumber: null,
      testNumber1: null
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!-- Add this to <head> -->

<!-- Load required Bootstrap and BootstrapVue CSS -->
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />

<!-- Load polyfills to support older browsers -->
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>

<!-- Load Vue followed by BootstrapVue -->
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>

<div id="app" style="padding:10px;">
  <template>
  <b-container fluid>
    <b-row>
      <b-col><b-input  placeholder="First number"  v-model="number" type="number"/></b-col>
      <b-col>{{typeof number}}</b-col>
    </b-row>
    <b-row>
      <b-col><b-input  placeholder="2nd number"  v-model="testNumber" type="number" v-on:input="$v => testNumber = +$v"/></b-col>
      <b-col>{{typeof testNumber}}</b-col>
    </b-row>
     <b-row>
      <b-col><b-input  placeholder="3rd number"  v-model="testNumber1" type="number" v-on:input="updateVm(event)"/></b-col>
      <b-col>{{typeof testNumber1}}</b-col>
    </b-row>
  </b-container>
</template>
</div>

<template>
  <b-container fluid>
    <b-row class="my-1" v-for="type in types" :key="type">
      <b-col sm="3">
        <label :for="`type-${type}`">Type <code>{{ type }}</code>:</label>
      </b-col>
      <b-col sm="9">
        <b-form-input :id="`type-${type}`" :type="type"></b-form-input>
      </b-col>
    </b-row>
  </b-container>
</template>

<script>
  export default {
    data() {
      return {
        types: [
          'number'
        ]
      }
    }
  }
</script>
Related