Vue項(xiàng)目中通過(guò)v-model封裝ElementUI組件

1. 問(wèn)題

Vue的項(xiàng)目中有如下的代碼共啃,需要根據(jù)不同字典的數(shù)據(jù)去展示下拉組件:

<template>
  <el-select v-model="product.carId" placeholder="請(qǐng)選擇車(chē)型 >
    <el-option
      v-for="item in options"
      :key="item.id"
      :label="item.name"
      :value="item.id"
    ></el-option>
  </el-select>
</template>

<script>
  export default {
    data() {
      return {
        options: Utils.get('PRODUCT_TYPE')
      }
    }
  }
</script>

問(wèn)題在于很多component中都需要用到這樣的代碼片段,而且很多都是重復(fù)的某個(gè)字典鸿脓,書(shū)寫(xiě)麻煩,代碼冗余创泄。

2. 分析

Vue的官方文檔提供了組件封裝的一些介紹。下面是摘自官方文檔的說(shuō)明:

自定義事件也可以用于創(chuàng)建支持 v-model 的自定義輸入組件肋僧。記装呤ぁ:

<input v-model="searchText">

等價(jià)于:

<input :value="searchText" @input="searchText = $event.target.value">

當(dāng)用在組件上時(shí),v-model 則會(huì)這樣:

<custom-input :value="searchText" @input="searchText = $event"></custom-input>

注意:當(dāng)用在組件上時(shí)嫌吠,v-model 則會(huì)這樣 這個(gè)句話有一些隱含信息

我們先假定要封裝一個(gè)簡(jiǎn)單的 input 的組件止潘,你覺(jué)得如下的代碼能達(dá)到目的嗎?

// 調(diào)用代碼

<tsp-input v-model="name"></tsp-input>

//組件定義代碼

<template>
    <input type="text" v-model="value">
</template>

<script>
export default {
  props: ['value']
}
</script>

不妨自己加些輸出展示辫诅,可以看到凭戴,組件定義中的值改變了,并不會(huì)改變外部的值炕矮,也就是說(shuō)并不管用么夫。進(jìn)一步分析:

v-model 等同于 :value @input,是區(qū)別對(duì)待的肤视。先明確一個(gè)概念档痪,directivevue 所有用到 v- 屬性的類(lèi)型的統(tǒng)稱(chēng),所有帶 v- 類(lèi)型的元素其實(shí)都是在跟directive打交道邢滑,directive 再跟底層的原生的元素打交道腐螟。

(1) 當(dāng)v-model被使用在 input中的時(shí)候

input其實(shí)是directiveInput(自己隨意取名),來(lái)自原生input的數(shù)據(jù),會(huì)被隱式地將數(shù)據(jù) 通過(guò) $emit 傳遞給 directiveInput乐纸,對(duì)此 directiveInput 的默認(rèn)接收到數(shù)值的行為是:searchText = $event.target.value衬廷。

(2)當(dāng)它被使用在自定義的組件中的時(shí)候

我們?cè)?tsp-input 中使用 v-model,那么數(shù)據(jù)的流轉(zhuǎn)是 原生inputdirectiveInput 汽绢,再到 directiveTspInput吗跋,directiveInputdirectiveTspInput都有接收值的默認(rèn)行為,但是不具備往外繼續(xù)傳遞的行為庶喜。即 tsp-input雖然掛了input的事件小腊,但是無(wú)法被觸發(fā)。這點(diǎn)不同于 vue 介入 原生input 將值傳遞給了 directiveInput 久窟。

繼續(xù)往外面?zhèn)髦抵雀裕仨氾@示的聲明傳值過(guò)程,如下:

// 調(diào)用代碼

<tsp-input v-model="name"></tsp-input>

//組件定義代碼

<template>
<input type="text" :value="value" @input="$emit('input', $event.target.value)">
</template>

<script>
export default {
  props: ['value']
}

3. 應(yīng)用

假定我們需要基于 el-select 封裝得到一個(gè) tsp-select斥扛,代碼大概是這樣的入问,實(shí)用有效:

//實(shí)際調(diào)用
<tsp-select v-model="product.cardId" dictName="PRODUCT_TYPE"></tsp-select>

// tsp-select.vue 封裝
<template>
  <el-select :value="product.carId" @input="$emit('input', $event)" 
    placeholder="請(qǐng)選擇車(chē)型>
    <el-option
      v-for="item in options"
      :key="item.id"
      :label="item.name"
      :value="item.id"
    ></el-option>
  </el-select>
</template>

<script>
  export default {
    data() {
      return {
        options: Utils.get(this.dictName)
      }
    }
  }
</script>

4. 總結(jié)和完整代碼

使用 ElementUIel-select 能夠成功使用 v-model,說(shuō)明 原生inputdirectiveInput再到directiveElSelect的數(shù)據(jù)流轉(zhuǎn)是ok的(即在el-select代碼內(nèi)部是有封裝 $emit('input', $event) 的)稀颁,那么到了我們的 tsp-select中芬失,想要也能被直接使用,也需要將值繼續(xù)往外傳遞匾灶。如下是完整封裝代碼:

tsp-select.vue

<template>
   <el-select :value="value" @input="$emit('input', $event)" placeholder="請(qǐng)選擇">
      <el-option
        v-for="item in options"
        :key="item.code"
        :label="item.text"
        :value="item.code"
      ></el-option>
    </el-select>
</template>

<script>
export default {
  props: {
    value: [Number, String],
    dictName: String,
  },
  data() {
    return {
      options: G.D.get(this.dictName)
    }
  },
}
</script>

和代碼調(diào)用

<el-form-item label="產(chǎn)品類(lèi)型" prop="carId">
  <tsp-select v-model="product.cardId" dictName="PRODUCT_TYPE"></tsp-select>
</el-form-item>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末棱烂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子阶女,更是在濱河造成了極大的恐慌颊糜,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秃踩,死亡現(xiàn)場(chǎng)離奇詭異衬鱼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)憔杨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)鸟赫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人消别,你說(shuō)我怎么就攤上這事抛蚤。” “怎么了妖啥?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵霉颠,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我荆虱,道長(zhǎng)蒿偎,這世上最難降的妖魔是什么朽们? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮诉位,結(jié)果婚禮上骑脱,老公的妹妹穿的比我還像新娘。我一直安慰自己苍糠,他們只是感情好叁丧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著岳瞭,像睡著了一般拥娄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瞳筏,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天稚瘾,我揣著相機(jī)與錄音,去河邊找鬼姚炕。 笑死摊欠,一個(gè)胖子當(dāng)著我的面吹牛些椒,可吹牛的內(nèi)容都是我干的免糕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼试吁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了余耽?” 一聲冷哼從身側(cè)響起碟贾,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后琼讽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體钻蹬,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溅潜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年设捐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片槐沼。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兼吓,死狀恐怖审孽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搓萧,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布宛畦,位于F島的核電站瘸洛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏次和。R本人自食惡果不足惜反肋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望踏施。 院中可真熱鬧石蔗,春花似錦、人聲如沸畅形。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)日熬。三九已至棍厌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間竖席,已是汗流浹背耘纱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毕荐,地道東北人束析。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像憎亚,于是被迫代替她去往敵國(guó)和親畸陡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容虽填,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,045評(píng)論 0 29
  • VUE介紹 Vue的特點(diǎn)構(gòu)建用戶(hù)界面曹动,只關(guān)注View層簡(jiǎn)單易學(xué)斋日,簡(jiǎn)潔、輕量墓陈、快速漸進(jìn)式框架 框架VS庫(kù)庫(kù)恶守,是一封裝...
    多多醬_DuoDuo_閱讀 2,687評(píng)論 1 17
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,202評(píng)論 0 6
  • 一、了解Vue.js 1.1.1 Vue.js是什么? 簡(jiǎn)單小巧究孕、漸進(jìn)式范舀、功能強(qiáng)大的技術(shù)棧 1.1.2 為什么學(xué)習(xí)...
    蔡華鵬閱讀 3,313評(píng)論 0 3
  • 組件(Component)是Vue.js最核心的功能,也是整個(gè)架構(gòu)設(shè)計(jì)最精彩的地方衫樊,當(dāng)然也是最難掌握的飒赃。...
    六個(gè)周閱讀 5,582評(píng)論 0 32