VUE2中文文檔:筆記
聲明式渲染
Vue.js 的核心是,可以采用簡潔的模板語法來聲明式的將數據渲染為 DOM:
<div id="app"> {{ message }} //模板語法 </div>
var app = new Vue({ //新建vue實例(響應式) el: ‘#app‘, //掛載到#app data: { message: ‘Hello Vue!‘ //數據 } })
除了文本插值(text interpolation),我們還可以采用這樣的方式綁定 DOM 元素屬性:
<div id="app-2"> <span v-bind:title="message"> //v-bind:屬性=“數據” 鼠標懸停此處幾秒, 可以看到此處動態綁定的 title!</span> </div>
var app2 = new Vue({ el: ‘#app-2‘, data: { message: ‘頁面加載於 ‘ + new Date().toLocaleString() } })
由組件組合而成的應用程序
在 Vue 中,一個組件本質上是一個被預先定義選項的 Vue 實例,在 Vue 中註冊組件很簡單:
// 定義一個被命名為 todo-item 的新組件 Vue.component(‘todo-item‘, { template: ‘<li>這是一個 todo 項</li>‘ })
現在你可以在另一個組件模板中組合使用它:
<ol> <!-- 創建一個 todo-item 組件的實例 --> <todo-item></todo-item> </ol>
將數據從父作用域傳到子組件。讓我們來修改下組件的定義,使它可以接受一個 prop:
var app7 = new Vue({ //vue實例掛載到app-7
el: ‘#app-7‘,
data: {
groceryList: [
{ id: 0, text: ‘蔬菜‘ },
{ id: 1, text: ‘奶酪‘ },
{ id: 2, text: ‘其他人類食物‘ }
]
}
})
<div id="app-7"> //組件模板app-7 <ol> <!-- 現在我們為每個 todo-item 提供了 todo 對象, 其中它的內容是動態的。 我們還需要為每個組件提供一個 "key", 這將在之後詳細解釋。 --> <todo-item v-for="item in groceryList" v-bind:todo="item" //將遍歷的每個item對象傳遞給todo v-bind:key="item.id"> //由於vue對組件渲染是可復用的,如果不給每一個添加不同的key,後面循環的組件不會重新渲染 </todo-item> //而是直接復用第一次渲染的結果 </ol> </div>
Vue.component(‘todo-item‘, { props: [‘todo‘], //子組件用props接受todo template: ‘<li>{{ todo.text }}</li>‘ //子組件模板 })
下面正式開始:
Vue 實例
var vm = new Vue({ //創建 // 選項 })
Vue 應用程序由「一個使用 new Vue
創建的 Vue 根實例」、「嵌套的樹結構(可選)」和「可復用的組件」組成。
data 和 methods
在創建 Vue 實例時,會將所有在 data
對象中找到的屬性,都添加到 Vue 的響應式系統中。每當這些屬性的值發生變化時,視圖都會“及時響應”,並更新相應的新值。
每當 data 對象發生變化,都會觸發視圖重新渲染。值得註意的是,如果實例已經創建,那麽只有那些 data
中的原本就已經存在的屬性,才是響應式的。也就是說,如果在實例創建之後,添加一個新的屬性,
例如:vm.b = ‘ hide‘;
然後,修改 b
不會觸發任何視圖更新。如果你已經提前知道,之後將會用到一個開始是空的或不存在的屬性,你需要預先設置一些初始值。例如:
data: { newTodoText: ‘‘, visitCount: 0, hideCompletedTodos: false, todos: [], error: null }
唯一的例外是,使用 Object.freeze()
來防止已有屬性被修改,這也意味著響應式系統無法追蹤變化。
除了 data 屬性, Vue 實例還暴露了一些有用的實例屬性和方法。這些屬性與方法都具有前綴 $
,以便與用戶定義(user-defined)的屬性有所區分。例如:
var data = { a: 1 } var vm = new Vue({ el: ‘#example‘, data: data }) vm.$data === data // => true 實例屬性,獲取實例data vm.$el === document.getElementById(‘example‘) // => true 獲取掛載的DOM對象 // $watch 是一個實例方法 vm.$watch(‘a‘, function (newValue, oldValue) { // 此回調函數將在 `vm.a` 改變後調用 })
點擊API文檔,來獲取實例屬性(instance property)和方法(methods)的完整列表。
實例生命周期鉤子函數
每個 Vue 實例在被創建之前,都要經過一系列的初始化過程 - 例如:
Vue 實例需要設置數據觀察(set up data observation)、
編譯模板(compile the template)、
在 DOM 掛載實例(mount the instance to the DOM),
數據變化時更新 DOM(update the DOM when data change)。
在這個過程中,Vue 實例還會調用執行一些生命周期鉤子函數,這樣用戶能夠在特定階段添加自己的代碼。
生命周期示意圖
模板語法
所有 Vue.js 的模板都是有效的 HTML,能夠被遵循規範的瀏覽器和 HTML 解析器解析。
在底層的實現上,Vue 將模板編譯為可以生成 Virtual DOM 的 render 函數。結合響應式系統,在應用程序狀態改變時,Vue 能夠智能地找出重新渲染的最小數量的組件,並應用最少量的 DOM 操作。
如果你熟悉虛擬 DOM 的概念,並且傾向於使用原生 JavaScript,還可以不使用模板,而是直接編寫 render 函數,具備可選的 JSX 語法支持。
插值(Interpolations)
文本(Text)
使用 “mustache” 語法(雙花括號)的文本插值(text interpolation),也可以通過使用 v-once 指令,執行一次性插值,也就是說,在數據改變時,插值內容不會隨之更新。但是請牢記,這也將影響到同一節點上的其他所有綁定。
原始 HTML(Raw HTML) (不建議使用)
屬性(Attributes)
使用 JavaScript 表達式
有個限制是,每個綁定都只能包含單個表達式。
computed 屬性和 watcher
你可以像綁定普通屬性一樣,將 computed 屬性的數據,綁定(data-bind)到模板中的表達式上。Vue 能夠意識到 computed屬性
依賴於 實例的數據,也會在 示例數據修改後,更新所有依賴於 computed屬性
的數據綁定。最恰到好處的部分是,我們是通過聲明式來創建這種依賴關系:computed 屬性的 getter 函數並無副作用(side effect),因此也更加易於測試和理解。
computed 緩存 vs method 方法
computed 屬性會基於它所依賴的數據進行緩存。每個 computed 屬性,只有在它所依賴的數據發生變化時,才會重新取值(re-evaluate)。這就意味著,只要 computed屬性函數依賴的實例數據
沒有發生變化,多次訪問 computed 屬性,將會立刻返回之前計算過的結果,而不必每次都重新執行函數。
為什麽我們需要將依賴數據緩存起來?假設一種場景,我們有一個高性能開銷(expensive)的 computed 屬性 A,在 computed 屬性的 getter 函數內部,需要遍歷循環一個巨大數組,並進行大量計算。然後還有其他 computed 屬性直接或間接依賴於 A。如果沒有緩存,我們將不可避免地多次執行 A 的 getter 函數,這遠多余實際需要執行的次數!然而在某些場景下,你可能不希望有緩存,請使用 method 方法替代。
computed 屬性和 watch 屬性
更推薦的方式是,使用 computed 屬性,而不是命令式(imperative)的 watch
回調函數。例如:
computed版本
var vm = new Vue({ el: ‘#demo‘, data: { firstName: ‘Foo‘, lastName: ‘Bar‘ }, computed: { fullName: function () { return this.firstName + ‘ ‘ + this.lastName //需要一個返回值加入到實例數據或者修改實例數據 } //computed屬性會檢測其依賴的實例數據 } })
watch版本
var vm = new Vue({ el: ‘#demo‘, data: { firstName: ‘Foo‘, lastName: ‘Bar‘, fullName: ‘Foo Bar‘ //watch屬性,檢測已經存在的屬性數據,不會自動返回為新實例屬性數據,所以要先聲明 }, watch: { firstName: function (val) { //觀測發生改變的屬性對象,而不觀測其依賴的實例數據,所以需要分為兩個函數實現功能。 this.fullName = val + ‘ ‘ + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ‘ ‘ + val } } })
對比 computed 屬性實現的版本,以上代碼是命令式和重復的。
computed 屬性中設置 setter
computed 屬性默認只設置 getter 函數,不過在需要時,還可以提供 setter 函數:
var vm = new Vue({ el: ‘#demo‘, data: { firstName: ‘Foo‘, lastName: ‘Bar‘, fullName: ‘Foo Bar‘ }, computed: { fullName: { // getter 函數 get: function () { //get函數觀測對象依賴,並返回變化 return this.firstName + ‘ ‘ + this.lastName }, // setter 函數 set: function (newValue) { //set函數觀測對象,讓你可以在computed中更改對象依賴的數據 var names = newValue.split(‘ ‘) this.firstName = names[0] this.lastName = names[names.length - 1] } } } })
現在當你運行 vm.fullName = ‘John Doe‘
,將會調用 setter,然後會對應更新 vm.firstName
和 vm.lastName
。
watcher
雖然在大多數情況下,更適合使用 computed 屬性,然而有些時候,還是需要一個自定義 watcher。當你需要在數據變化響應時,執行異步操作,或高性能消耗的操作,自定義 watcher 的方式就會很有幫助。
<div id="watch-example"> <p> 問一個答案是 yes/no 的問題: <input v-model="question"> //v-modle會將input輸入值傳給question </p> <p>{{ answer }}</p> </div>
<!-- 對於 ajax 庫(ajax libraries)和通用工具方法的集合(collections of general-purpose utility methods)來說, --> <!-- 由於已經存在大量與其相關的生態系統, --> <!-- 這也可以使你自由隨意地選擇自己最熟悉的。 --> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script> <script> var watchExampleVM = new Vue({ el: ‘#watch-example‘, data: { question: ‘‘, answer: ‘你要先提出問題,我才能給你答案!‘ }, watch: { //這種需求,不是更新觀測對象(computed.get)或者更新其依賴(computed.set), 而是觀測變化去做與數據無關的操作,computed無法實現 // 只要 question 發生改變,此函數就會執行 question: function (newQuestion, oldQuestion) { //不是很懂兩個參數,但我想可能這是watch能監測到的改變之前和之後的對象, this.answer = ‘等待輸入停止……‘ this.getAnswer() } }, methods: { // _.debounce 是由 lodash 提供的函數, // 在運行特別消耗性能的操作時, // 可以使用 _.debounce 來限制頻率。 // 在下面這種場景中,我們需要限制訪問 yesno.wtf/api 的頻率, // 等到用戶輸入完畢之後,ajax 請求才會發出。 getAnswer: _.debounce( function () { if (this.question.indexOf(‘?‘) === -1) { this.answer = ‘問題通常需要包含一個中文問號。;-)‘ return } this.answer = ‘思考中……‘ var vm = this //ajax請求中的this可能沒有指向實例,所以在請求之前先把實例對象this賦值給變量vm axios.get(‘https://yesno.wtf/api‘) .then(function (response) { vm.answer = _.capitalize(response.data.answer) }) .catch(function (error) { vm.answer = ‘錯誤!API 無法處理。‘ + error }) }, // 這是用戶停止輸入操作後所等待的毫秒數。 // (譯者註:500毫秒之內,用戶繼續輸入,則重新計時) 500 ) } }) </script>
class 和 style 綁定
與 HTML 的 class 綁定(Binding HTML Classes)
(內聯、外部引用)這兩種方式的渲染結果相同。我們還可以將 class 和 style 與某個 computed 屬性綁定在一起,此 computed 屬性所對應的 getter 函數需要返回一個對象。這是一種常用且強大的用法
<div v-bind:class="classObject"></div> //簡寫 :class="classObject"
data: { isActive: true, error: null }, computed: { //通過computed屬性控制classObjecr對其它class的影響 classObject: function () { //如果classObject屬性去除了,先前computed return的樣式會恢復嗎? return { active: this.isActive && !this.error, ‘text-danger‘: this.error && this.error.type === ‘fatal‘ } } }
我們可以向 v-bind:class
傳入一個數組,來與 class 列表對應:
<div v-bind:class="[activeClass, errorClass]"></div>
<div v-bind:class="[isActive ? activeClass : ‘‘, errorClass]"></div>
//這裏會直接添加 errorClass
,但是只有在 isActive
值是 truthy 時,才會添加 activeClass
。
<div v-bind:class="[{ active: isActive }, errorClass]"></div> //這裏使用對象語法比三元運算更加簡潔
在組件中使用
當你在自定義組件中使用 class
屬性,這些 class 會被添加到組件的根元素上。根元素上已經存在的 class 不會被覆蓋。
與內聯 style 綁定(Binding Inline Styles)
<div v-bind:style="{ color: activeColor, fontSize: fontSize + ‘px‘ }"></div>
v-bind:style
的對象語法,通常也會和 computed 屬性結合使用,此 computed 屬性所對應的 getter 函數需要返回一個對象。
<div v-bind:style="[baseStyles, overridingStyles]"></div>
從 2.3.0+ 起,你可以為每個 style 屬性提供一個含有多個(前綴)值的數組,例如:
<div v-bind:style="{ display: [‘-webkit-box‘, ‘-ms-flexbox‘, ‘flex‘] }"></div>
根據條件進行渲染
v-else
元素必須緊跟在 v-if
或 v-else-if
元素之後 - 否則無法識別它。
使用 key
控制元素是否可復用
Vue 會盡可能高效地渲染元素,通常會復用已渲染元素,而不是從頭重新渲染。這樣的實現方式,除了有助於使 Vue 變得非常快之外,還具有一些額外的優勢。
但是這樣有時並不符合實際需求,所以 Vue 為如下所述的情況提供了一種方式:“這兩個元素是完全獨立的 - 請不要復用它們”。那就是為它們添加一個具有不同值的 key
屬性。
具有 v-show
的元素會始終渲染並保留在 DOM 中。v-show
只會切換元素的 display
這個 CSS 屬性。
v-if
是“真實”的條件渲染,因為它會確保條件塊(conditional block)在切換的過程中,完整地銷毀(destroy)和重新創建(re-create)條件塊內的事件監聽器和子組件。
v-if
是惰性的(lazy):如果在初始渲染時條件為 false,它不會執行任何操作 - 在條件第一次變為 true 時,才開始渲染條件塊。
通常來說,v-if
在切換時有更高的性能開銷,而 v-show
在初始渲染時有更高的性能開銷。因此,如果需要頻繁切換,推薦使用 v-show
,如果條件在運行時改變的可能性較少,推薦使用 v-if
。
列表渲染
使用 v-for
遍歷數組生成元素
在 v-for
代碼塊中,我們可以完全地訪問父級作用域下的屬性。v-for
還支持可選的第二個參數,作為當前項的索引。
使用 v-for
遍歷對象
還可以提供第二個參數,作為對象的鍵名(key,然後第三個參數作為索引(index):
<div v-for="(value, key, index) in object"> {{ index }}. {{ key }}: {{ value }} </div>
在遍歷一個對象時,是按照 Object.keys()
得出 key 的枚舉順序來遍歷,無法保證在所有 JavaScript 引擎實現中完全一致。
推薦,在使用 v-for
時,盡可能提供一個 key
,除非叠代的 DOM 內容足夠簡單,或者你是故意依賴於默認行為來獲得性能提升。
數組變化檢測(Array Change Detection)
變化數組方法(Mutation Methods)
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
替換一個數組(Replacing an Array)
例如 filter()
, concat()
和 slice()
你可能會認為這將導致 Vue 丟棄現有 DOM 並重新渲染(re-render)整個列表 - 幸運的是,情況並非如此。Vue 實現了一些智能啟發式方法(smart heuristic)來最大化 DOM 元素重用(reuse),因此將一個數組替換為包含重疊對象的另一個數組,會是一種非常高效的操作。
註意事項(Caveats)
由於 JavaScript 的限制,Vue 無法檢測到以下數組變動:
- 當你使用索引直接設置一項時,例如
vm.items[indexOfItem] = newValue
- 當你修改數組長度時,例如
vm.items.length = newLength
為了解決第 1 個問題,以下方式都可以實現相同的效果,但是卻可以通過響應式系統出發狀態更新:
// Vue.set Vue.set(vm.items, indexOfItem, newValue) // Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue) //你還可以使用 vm.$set 實例方法,這也是全局 Vue.set 方法的別名: vm.$set(vm.items, indexOfItem, newValue)
為了解決第 2 個問題,你可以使用 splice
:
vm.items.splice(newLength)
有時,你想要向已經存在的對象上添加一些新的屬性,例如使用 Object.assign()
或 _.extend()
方法。在這種情況下,應該創建一個新的對象,這個對象同時具有兩個對象的所有屬性,因此,改為: //不是很理解
Object.assign(vm.userProfile, { age: 27, favoriteColor: ‘Vue Green‘ }) //可以通過如下方式,添加新的響應式屬性: vm.userProfile = Object.assign({}, vm.userProfile, { age: 27, favoriteColor: ‘Vue Green‘ })
顯示過濾/排序結果(Displaying Filtered/Sorted Results)
有時,我們想要顯示一個數組過濾或排序後(filtered or sorted)的副本,而不是實際改變或重置原始數據。在這種情況下,可以創建一個返回過濾或排序數組的計算屬性。
<li v-for="n in evenNumbers">{{ n }}</li>
data: { numbers: [ 1, 2, 3, 4, 5 ] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } }
在計算屬性不適用的情況下(例如,在嵌套的 v-for
循環內),可以使用一個 method 方法: //不是很理解紅色部分,參考上面循環,思考如果外部再套一層循環的computed結果
data: { numbers: [ 1, 2, 3, 4, 5 ] }, methods: { even: function (numbers) { return numbers.filter(function (number) { return number % 2 === 0 }) } }
使用 v-for
在整數值範圍內叠代
<div> <span v-for="n in 10">{{ n }}</span> </div>
帶有 v-if
的 v-for
當它們都處於同一節點時,v-for
的優先級高於 v-if
。這意味著,v-if
將分別在循環中的每次叠代上運行。當你只想將某些項渲染為節點時,這會非常有用,如下:
<li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo }} </li>
如果你的意圖與此相反,是根據條件跳過執行循環,可以將 v-if
放置於包裹元素上(或放置於 <template>
上)。例如:
<ul v-if="todos.length"> <li v-for="todo in todos"> {{ todo }} </li> </ul> <p v-else>No todos left!</p>
使用 v-for
遍歷組件
現在,在 2.2.0+ 版本,當對組件使用 v-for
時,必須設置 key
屬性。
無法自動向組件中傳入數據,這是因為組件有自己的獨立作用域。為了將組件外部的叠代數據傳入組件,我們還需要額外使用 props:
<my-component v-for="(item, index) in items" v-bind:item="item" v-bind:index="index" v-bind:key="item.id" ></my-component>
沒有通過 v-for 將 item
自動註入到組件中的原因是,一旦自動註入,就會使得組件與 v-for
指令的運行方式緊密耦合(tightly coupled)在一起。通過顯式聲明組件數據來源,可以使得組件可重用於其他場景。
<div id="todo-list-example"> <input v-model="newTodoText" v-on:keyup.enter="addNewTodo" placeholder="Add a todo" > <ul> <li is="todo-item" //註意is="todo-item"
屬性。這在 DOM 模板中是必需的,因為在<ul>
中,只有<li>
是有效元素。這與調用<todo-item>
的實際結果相同,但是卻可以解決瀏覽器潛在的解析錯誤。 v-for="(todo, index) in todos" v-bind:key="todo.id" v-bind:title="todo.title" v-on:remove="todos.splice(index, 1)" ></li> </ul> </div>
事件處理
監聽事件
我們可以使用 v-on
指令監聽 DOM 事件,並在事件被觸發時執行一些 JavaScript 代碼。
由於許多事件處理器的邏輯很復雜,所以把 JavaScript 代碼都保存在 v-on
屬性的值中是不可行的做法。這就是為什麽 v-on
還可以接收要調用的方法名。
在行內語句的事件處理器中,有時我們也需要訪問原始 DOM 事件對象。可以使用特殊的 $event
變量將它傳遞給一個方法:
<button v-on:click="warn(‘Form cannot be submitted yet.‘, $event)"> Submit </button> // ... methods: { warn: function (message, event) { // 現在,我們可以訪問原始事件對象 if (event) event.preventDefault() alert(message) } }
事件修飾符(Event Modifiers)
盡管我們可以在 methods 中輕松實現這點,但更好的方式是:methods 只有純粹的數據邏輯,而不是去處理 DOM 事件細節。
Vue.js 為 v-on
提供了事件修飾符。回想一下,修飾符是以點(.)開頭的指令後綴來表示。
<!-- 停止點擊事件冒泡 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重新載入頁面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修飾符可以鏈式調用 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修飾符 --> <form v-on:submit.prevent></form> <!-- 添加事件監聽器時,使用事件捕獲模式 --> <!-- 也就是說,內部元素觸發的事件先在此處處理,然後才交給內部元素進行處理 --> //想不到實際運用場景 <div v-on:click.capture="doThis">...</div> <!-- 只有在 event.target 是元素自身時,才觸發處理函數。 --> <!-- 也就是說,event.target 是子元素時,不觸發處理函數 --> <div v-on:click.self="doThat">...</div>
<!-- 點擊事件將只會觸發一次 -->
<a v-on:click.once="doThis"></a>
<!-- 滾動事件的默認行為(滾動)將立即發生, -->
<!-- 而不是等待 `onScroll` 完成後才發生, -->
<!-- 以防在滾動事件的處理程序中含有 `event.preventDefault()` 調用 -->
<div v-on:scroll.passive="onScroll">...</div> //.passive
修飾符對於提高移動設備的性能尤其有用。
使用修飾符時的順序會產生一些影響,因為相關的代碼會以相同的順序生成。所以,使用 v-on:click.prevent.self
會阻止所有點擊,而 v-on:click.self.prevent
只阻止元素自身的點擊。
不要將 .passive
和 .prevent
放在一起使用,因為 .prevent
將被忽略,並且瀏覽器可能會顯示一條警告。記住,.passive
會向瀏覽器傳達的意思是,你並不希望阻止事件的默認行為。
按鍵修飾符(Key Modifiers)
<!-- 和上面的示例相同 --> <input v-on:keyup.enter="submit"> <!-- 也可用於簡寫語法 --> <input @keyup.enter="submit">
這裏列出所有的按鍵修飾符別名:
.enter
.tab
.delete
(捕獲“刪除”和“退格”按鍵).esc
.space
.up
.down
.left
.right
還可以自定義按鍵修飾符別名,通過全局 config.keyCodes
對象設置:
// 可以使用 `v-on:keyup.f1` Vue.config.keyCodes.f1 = 112
自動對應按鍵修飾符(Automatic Key Modifers)
也可以直接使用 KeyboardEvent.key
暴露出來的所有合法按鍵名作為修飾符,但是要將它們轉換為串聯式命名(kebab-case):
<input @keyup.page-down="onPageDown">
系統輔助按鍵(System Modifier Keys)
僅在以下修飾符對應的按鍵被按下時,才會觸發鼠標或鍵盤事件監聽器:
.ctrl
.alt
.shift
.meta
<!-- Alt + C --> <input @keyup.alt.67="clear"> <!-- Ctrl + Click --> <div @click.ctrl="doSomething">做一些操作</div>
.exact
修飾符(.exact Modifier)
.exact
修飾符可以控制觸發事件所需的系統輔助按鍵的準確組合。
<!-- 如果 Alt 鍵或 Shift 鍵與 Ctrl 鍵同時按下,也會觸發事件 --> <button @click.ctrl="onClick">A</button> <!-- 只在 Ctrl 按鍵按下,其他按鍵未按下時,觸發事件 --> <button @click.ctrl.exact="onCtrlClick">A</button> <!-- 只在系統輔助按鍵按下時,觸發事件 --> <button @click.exact="onClick">A</button>
鼠標按鍵修飾符(Mouse Button Modifiers)
.left
.right
.middle
這些修飾符會限制處理函數,僅響應特定的鼠標按鍵觸發的事件。
表單 input 綁定
可以通過使用 v-model
指令,在表單 input 和 textarea 元素上創建雙向數據綁定。v-model
指令可以根據 input 的 type 類型,自動地以正確的方式更新元素。雖然略顯神奇,然而本質上 v-model
不過是「通過監聽用戶的 input 事件來更新數據」的語法糖,以及對一些邊界情況做特殊處理。
v-model
會忽略所有表單元素中 value
, checked
或 selected
屬性上初始設置的值,而總是將 Vue 實例中的 data 作為真實數據來源。因此你應該在 JavaScript 端的組件 data
選項中聲明這些初始值,而不是 HTML 端。
與 value 屬性綁定(待補充)
修飾符(modifiers)
.lazy
默認情況下,v-model
會在每次 input
事件觸發之後,將數據同步至 input 元素中(除了上述提到的輸入法組合文字時不會)。可以添加 lazy
修飾符,從而轉為在觸發 change
事件後同步。
.number
如果想要將用戶的輸入,自動轉換為 Number 類型(譯註:如果轉換結果為 NaN 則返回字符串類型的輸入值),可以在 v-model
之後添加一個 number
修飾符,來處理輸入值:
這通常很有用,因為即使是在 type="number"
時,HTML 中 input 元素也總是返回一個字符串類型的值。
.trim
如果想要將用戶的輸入,自動過濾掉首尾空格,可以在 v-model
之後添加一個 trim
修飾符,來處理輸入值:
VUE2中文文檔:筆記