V-model指令
摘要
限制:
v-model只能用在:<input> <select> <textarea> <components>
修飾符
基礎用法
v-model
會忽略所有表單元素的 value
、checked
、selected
特性的初始值而總是將 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)) } } })
最后結果,就你可以沒有小數,但如果有小數后面最后只能有兩位小數
上面案例我理解的:
slice方法
ref ($refs)用法
ref 有三種用法
1.ref 加在普通的元素上,用this.ref.name 獲取到的是dom元素
2.ref 加在子組件上,用this.ref.name 獲取到的是組件實例,可以使用組件的所有方法。
3.如何利用v-for 和ref 獲取一組數組或者dom 節點
一、ref使用在外面的組件上
HTML 部分
<div id="ref-outside-component" v-on:click="consoleRef"> <component-father ref="outsideComponentRef"> </component-father> <p>ref在外面的組件上</p> </div>
js部分
var refoutsidecomponentTem={ template:"<div class='childComp'><h5>我是子組件</h5></div>" }; var refoutsidecomponent=new Vue({ el:"#ref-outside-component", components:{ "component-father":refoutsidecomponentTem }, methods:{ consoleRef:function () { console.log(this); // #ref-outside-component vue實例 console.log(this.$refs.outsideComponentRef); // div.childComp vue實例 } } });
二、ref使用在外面的元素上
HTML部分
<!--ref在外面的元素上--> <div id="ref-outside-dom" v-on:click="consoleRef" > <component-father> </component-father> <p ref="outsideDomRef">ref在外面的元素上</p> </div>
JS部分
var refoutsidedomTem={ template:"<div class='childComp'><h5>我是子組件</h5></div>" }; var refoutsidedom=new Vue({ el:"#ref-outside-dom", components:{ "component-father":refoutsidedomTem }, methods:{ consoleRef:function () { console.log(this); // #ref-outside-dom vue實例 console.log(this.$refs.outsideDomRef); // <p> ref在外面的元素上</p> } } });
三、ref使用在里面的元素上---局部注冊組件
HTML
<!--ref在里面的元素上--> <div id="ref-inside-dom"> <component-father> </component-father> <p>ref在里面的元素上</p> </div>
JS部分
var refinsidedomTem={ template:"<div class='childComp' v-on:click='consoleRef'>" + "<h5 ref='insideDomRef'>我是子組件</h5>" + "</div>", methods:{ consoleRef:function () { console.log(this); // div.childComp vue實例 console.log(this.$refs.insideDomRef); // <h5 >我是子組件</h5> } } }; var refinsidedom=new Vue({ el:"#ref-inside-dom", components:{ "component-father":refinsidedomTem } });
四、ref使用在里面的元素上---全局注冊組件
HTML
<!--ref在里面的元素上--全局注冊--> <div id="ref-inside-dom-all"> <ref-inside-dom-quanjv></ref-inside-dom-quanjv> </div>
JS部分
Vue.component("ref-inside-dom-quanjv",{ template:"<div class='insideFather'> " + "<input type='text' ref='insideDomRefAll' v-on:input='showinsideDomRef'>" + " <p>ref在里面的元素上--全局注冊 </p> " + "</div>", methods:{ showinsideDomRef:function () { console.log(this); //這里的this其實還是div.insideFather console.log(this.$refs.insideDomRefAll); // <input type="text"> } } }); var refinsidedomall=new Vue({ el:"#ref-inside-dom-all" });
$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】