您好,登錄后才能下訂單哦!
怎么深入了解vue2中的 v-model以及讓組件支持該語法,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
v-model
的本質是語法糖。『
v-model
本質上不過是語法糖。它負責監聽用戶的輸入事件以更新數據,并對一些極端場景進行一些特殊處理。』 -- 官方文檔。【相關推薦:vue.js教程】
什么是語法糖?
語法糖,簡單來說就是『便捷寫法』。
在大部分情況下, v-model="foo"
等價于 :value="foo"
加上 @input="foo = $event"
;
<!-- 在大部分情況下,以下兩種寫法是等價的 --> <el-input v-model="foo" /> <el-input :value="foo" @input="foo = $event" />
沒錯,在大部分情況下如此。
但也有例外:
vue2
給組件提供了 model
屬性,可以讓用戶自定義傳值的prop名和更新值的事件名。這個暫且略過,第四節會細說。
對于原生 html
原生元素,vue
干了大量『臟活兒』,目的是為了能讓我們忽視 html
在api上的差異性。以下元素的左右兩種寫法是等價的:
textarea
元素:
select
下拉框:
input type='radio'
單選框:
input type='checkbox'
多選框:
在編程思想上,這種幫助使用者『隱藏細節』的方式叫封裝。
v-model
不僅僅是語法糖,它還有副作用。
副作用如下:如果 v-model
綁定的是響應式對象上某個不存在的屬性,那么 vue
會悄悄地增加這個屬性,并讓它響應式。
舉個例子,看下面的代碼:
// template中: <el-input v-model="user.tel"></el-input> // script中: export default { data() { return { user: { name: '公眾號: 前端要摸魚', } } } }
響應式數據中沒有定義 user.tel
屬性,但是 template
里卻用 v-model
綁定了 user.tel
,猜一猜當你輸入時會發生什么?
看效果:
揭曉答案吧:user
上會新增 tel
屬性,并且 tel
這個屬性還是響應式的。
這就是『副作用』帶來的效果,你學會了嗎?
v-model
是雙向綁定還是單向數據流?v-model
是雙向綁定嗎?是,官方說是。
『你可以用 v-model 指令在表單 <input>
、<textarea>
及 <select>
元素上創建雙向數據綁定。』 —— vue2官方文檔
v-model
是單向數據流嗎?是的,它甚至是單向數據流的典型范式。
雖然官方沒有明確表示這點,但我們可以捋一捋兩者的關系。
什么是單項數據流?
子組件不能改變父組件傳遞給它的 prop
屬性,推薦的做法是它拋出事件,通知父組件自行改變綁定的值。
v-model
的做法是怎樣的?
v-model
做法完全符合單項數據流。甚至于,它給出了一種在命名和事件定義上的規范。
眾所周知 .sync
修飾符是單向數據流的另一個典型范式。
『單向數據流』總結起來其實也就8個字:『數據向下,事件向上』。
v-model
雖然不想說,但這確實是高頻面試題。
在定義 vue
組件時,你可以提供一個 model
屬性,用來定義該組件以何種方式支持 v-model
。
model
屬性本身是有默認值的,如下:
// 默認的 model 屬性 export default { model: { prop: 'value', event: 'input' } }
也就是說,如果你不定義 model
屬性,或者你按照當面方法定義屬性,當其他人使用你的自定義組件時,v-model="foo"
就完全等價于 :value="foo"
加上 @input="foo = $event"
。
如果把 model
屬性進行一些改裝,如下:
// 默認的 model 屬性 export default { model: { prop: 'ame', event: 'zard' } }
那么,v-model="foo"
就等價于 :ame="foo"
加上 @zard="foo = $event"
。
沒錯,就是這么容易,讓我們看個例子。
先定義一個自定義組件:
<template> <div> 我們是TI{{ ame }}冠軍 <el-button @click="playDota2(1)">加</el-button> <el-button @click="playDota2(-1)">減</el-button> </div> </template> <script> export default { props: { ame: { type: Number, default: 8 } }, model: { // 自定義v-model的格式 prop: 'ame', // 代表 v-model 綁定的prop名 event: 'zard' // 代碼 v-model 通知父組件更新屬性的事件名 }, methods: { playDota2(step) { const newYear = this.ame + step this.$emit('zard', newYear) } } } </script>
然后我們在父組件中使用該組件:
// template中 <dota v-model="ti"></dota> // script中 export default { data() { return { ti: 8 } } }
看看效果:
讓你的組件支持 v-model
就這么容易。
獲取源碼請訪問github
https://github.com/zhangshichun/blog-vue2-demos/tree/master/src/views/about-v-model
關于怎么深入了解vue2中的 v-model以及讓組件支持該語法問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。