1. 程式人生 > >VueJs(4)---V-model指令

VueJs(4)---V-model指令

IT ctype 思考 disable new ash exp 同步 func

V-model指令

摘要

限制

v-model只能用在:<input> <select> <textarea> <components>

修飾符

  • .lazy - 取代 input 監聽 change 事件
  • .number - 輸入字符串轉為數字
  • .trim - 輸入首尾空格過濾

基礎用法

v-model 會忽略所有表單元素的 valuecheckedselected 特性的初始值而總是將 Vue 實例的數據作為數據來源。你應該通過 JavaScript 在組件的 data

選項中聲明初始值。

文本

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

技術分享圖片

多行文本

<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"
></textarea>

技術分享圖片

復選框

單個復選框,綁定到布爾值

<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

技術分享圖片

多個復選框,綁定到同一個數組

<div id=‘example-3‘>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"
> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span> </div> new Vue({ el: ‘#example-3‘, data: { checkedNames: [] } })

技術分享圖片

單選按鈕

<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
  <br>
  <span>Picked: {{ picked }}</span>
</div>

技術分享圖片

選擇框

單選時

<div id="example-5">
  <select v-model="selected">
    <option disabled value="">請選擇</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
new Vue({
  el: ‘#example-5‘,
  data: {
    selected: ‘‘
  }
})

技術分享圖片

註意:如果 v-model 表達式的初始值未能匹配任何選項,<select> 元素將被渲染為“未選中”狀態。在 iOS 中,這會使用戶無法選擇第一個選項。因為這樣的情況下,iOS 不會觸發 change 事件。因此,更推薦像上面這樣提供一個值為空的禁用選項。

多選時 (綁定到一個數組)

<div id="example-6">
  <select v-model="selected" multiple style="width: 50px;">
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <br>
  <span>Selected: {{ selected }}</span>
</div>
new Vue({
  el: ‘#example-6‘,
  data: {
    selected: []
  }
})

技術分享圖片

v-for 渲染的動態選項

<select v-model="selected">
  <option v-for="option in options" v-bind:value="option.value">
    {{ option.text }}
  </option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
  el: ‘...‘,
  data: {
    selected: ‘A‘,
    options: [
      { text: ‘One‘, value: ‘A‘ },
      { text: ‘Two‘, value: ‘B‘ },
      { text: ‘Three‘, value: ‘C‘ }
    ]
  }
})

技術分享圖片

值綁定

對於單選按鈕,復選框及選擇框的選項,v-model 綁定的值通常是靜態字符串 (對於復選框也可以是布爾值):

<!--看到這裏上面的你都應該明白了-->
<!--
當選中時,`picked` 為字符串 "a" --> <input type="radio" v-model="picked" value="a"> <!-- `toggle` 為 true 或 false --> <input type="checkbox" v-model="toggle"> <!-- 當選中第一個選項時,`selected` 為字符串 "abc" --> <select v-model="selected"> <option value="abc">ABC</option> </select>

思考:有時我們可能想把值綁定到 Vue 實例的一個動態屬性上,這時可以用 v-bind 實現,並且這個屬性的值可以不是字符串。

修飾符

.lazy

在默認情況下,v-model 在每次 input 事件觸發後將輸入框的值與數據進行同步 (除了上述輸入法組合文字時)。你可以添加 lazy 修飾符,從而轉變為使用 change 事件進行同步

<!-- 在“change”時而非“input”時更新 -->
<input v-model.lazy="msg" >

.number

如果想自動將用戶的輸入值轉為數值類型,可以給 v-model 添加 number 修飾符

<input v-model.number="age" type="number">
<!--這通常很有用,因為即使在 type="number" 時,HTML 輸入元素的值也總會返回字符串-->
<!--我想它主要是用來限制用戶輸入的時候只能是數字-->

.trim

<!--如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符->
<input v-model.trim="msg">

在組件上使用 v-model

用自定義事件的表單輸入組件

講這個前,首先我們要明白的是:

<input v-model="something">
<!--它其實是個語法糖,而真正的其實如下:-->

<input
  v-bind:value="something"
  v-on:input="something = $event.target.value">

<!--所以在組件中使用時,它相當於下面的簡寫-->
<custom-input
  v-bind:value="something"
  v-on:input="something = arguments[0]">
</custom-input>

看了上面我們就明白,父主鍵是無法直接向子主鍵傳值的,它其實綁定了父主鍵的click事件。

所以要讓組件的 v-model 生效,它應該 (從 2.2.0 起是可配置的):

  • 接受一個 value prop
  • 在有新的值時觸發 input 事件並將新值作為參數

案例:

貨幣輸入的自定義控件,限制最多小數點保留兩位

<currency-input v-model="price"></currency-input>
Vue.component(‘currency-input‘, { template: <span> $ <input ref="input" v-bind:value="value" v-on:input="updateValue($event.target.value)" > </span> , props: [‘value‘], methods: { // 不是直接更新值,而是使用此方法來對輸入值進行格式化和位數限制 updateValue: function (value) { var formattedValue = value // 刪除兩側的空格符 .trim() // 保留 2 位小數 .slice( 0, value.indexOf(‘.‘) === -1 ? value.length : value.indexOf(‘.‘) + 3 ) // 如果值尚不合規,則手動覆蓋為合規的值 if (formattedValue !== value) { this.$refs.input.value = formattedValue } // 通過 input 事件帶出數值 this.$emit(‘input‘, Number(formattedValue)) } } })

最後結果,就你可以沒有小數,但如果有小數後面最後只能有兩位小數

技術分享圖片

上面案例我是看官方API有三點不理解,希望知道的能留言告訴我,一點也是好的,萬分感謝!

1:這裏為什麽要加反斜線?

2:ref="input" 具體用意是什麽?

3:this.$emit(‘input‘, Number(formattedValue)) 為什麽還要帶出值?

上面案例我理解的:

slice方法

技術分享圖片

$emit理解

關於$emit的用法

1、父組件可以使用 props 把數據傳給子組件。
2、子組件可以使用 $emit 觸發父組件的自定義事件。

子組件

<template>  
  <div class="train-city">  
    <span @click=‘select(`大連`)‘>大連</span>  
  </div>  
</template>  
<script>  
export default {  
  name:‘trainCity‘,  
  methods:{  
    select(val) {  
      let data = {  
        cityname: val  
      };  
      this.$emit(‘showCityName‘,data);//select事件觸發後,自動觸發showCityName事件  
    }  
  }  
}  
</script>  

父組件

<template>  
    <trainCity @showCityName="updateCity" :index="goOrtoCity"></trainCity> //監聽子組件的showCityName事件。  
<template>  
<script>  
export default {  
  name:‘index‘,  
  data () {  
   return {  
      toCity:"北京"  
    }  
  }  
  methods:{  
    updateCity(data){//觸發子組件城市選擇-選擇城市的事件    
      this.toCity = data.cityname;//改變了父組件的值  
      console.log(‘toCity:‘+this.toCity)        
    }  
  }  
}  
</script>  

結果為:toCity: 大連

在找個例子:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="counter-event-example">
            <p>{{ total }}</p>
            <button-counter v-on:increment1="incrementTotal"></button-counter>
            <button-counter v-on:increment2="incrementTotal"></button-counter>
        </div>
    </body>
    <script src="vue/vue.min.js"></script>
    <script>
        Vue.component(button-counter,{
            template:<button v-on:click="increment">{{ counter }}</button>,
            data:function(){
                return {counter: 0}<!--組件數據就是這樣的,函數式的,請註意-->
            },
            methods:{
                increment:function(){
                    this.counter += 1;
                    this.$emit(increment1,[12,kkk]);<!--$emit-->
                }
            }
        });
        new Vue({
            el:#counter-event-example,
            data:{
                total:0
            },
            methods:{
                incrementTotal:function(e){
                    this.total += 1;
                    console.log(e);
                }
            }
        });
    </script>
</html>

先看組件 button-counter

綁定了事件click————>increment

然後 this.counter += 1; this.$emit(‘increment1‘,[12,‘kkk‘]);

這邊就是觸發事件 increment1,參考文獻裏面有點亂,這邊是不是清晰多了

然後 <button-counter v-on:increment1="incrementTotal"></button-counter>

v-on相當於監聽吧,就觸發 incrementTotal

輸出// [12, "kkk"]

想的太多,做的太少,中間的落差就是煩惱,要麽去做,要麽別想 中尉【13】


VueJs(4)---V-model指令