您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)vue自定義組件如何實(shí)現(xiàn)v-model雙向綁定數(shù)據(jù)的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
項(xiàng)目中會(huì)遇到自定義公共組件供項(xiàng)目調(diào)用,正常情況可以使用 props定義參數(shù)接收父組件傳的參數(shù),然后通過子組件的$emits()方法回傳數(shù)據(jù)給父組件。
類似如下:
父組件
<common-checkbox :checked="goodsSelected" class="left" :height="'16px'" :width="'16px'" @checkChange="checkChange"></common-checkbox>
/** * 接收子組件回傳進(jìn)行處理 */ checkChange(value) { this.goodsSelected=value//子組件數(shù)據(jù)賦值給父組件 }
子組件
/** * 切換選中回傳 */ toggleCheck(value) { this.$emit('changeCheck', value)//回傳方法,把子組件變化后的數(shù)據(jù)回傳給父組件處理 }
但是這種寫法需要調(diào)用公共組件的頁面額外寫處理的方法,而且顯得太low,我們可不可以像是框架自帶的公共組件一樣去聲明直接v-model雙向綁定呢?接下來提供項(xiàng)目中實(shí)際遇到這種情況的處理方法
第一種方式:
正常情況下當(dāng)你在父組件里給子組件綁定 v-model屬性時(shí),子組件中會(huì)默認(rèn)的將 v-model綁定的數(shù)據(jù),付給子組件 名為 value的props屬性,value依然需要提前在子組件props中聲明,否則接收不到。
當(dāng) value修改后,并不會(huì)立即雙向回傳給父組件。如果想回傳實(shí)現(xiàn)同步更新父組件的v-model需要如下操作
this.$emit('input', value)
當(dāng)未聲明雙向綁定回傳的事件時(shí),默認(rèn)通過input事件回傳,為什么說 “當(dāng)未聲明雙向綁定回傳的事件”,這個(gè)便是第二種方式,下面會(huì)講到。
簡(jiǎn)單來說,第一種方式的實(shí)現(xiàn),首先是v-model綁定父組件數(shù)據(jù) ,然后子組件value 的props屬性自動(dòng)接收,最后當(dāng)數(shù)據(jù)更改后調(diào)用this.$emit('input', value) 回傳父組件,這樣父組件不需要額外實(shí)現(xiàn)子組件的回傳就可以實(shí)現(xiàn)雙向綁定
第二種方式:
前面提到 “當(dāng)未聲明雙向綁定回傳的事件” 默認(rèn)使用 input回傳,既然這樣說了那就存在,如果我不用input呢?這就需要了解vue的一個(gè)特殊的屬性:model,這個(gè)屬性可以用來聲明 子組件用哪個(gè)字段去接收雙向綁定的數(shù)據(jù),以及用哪個(gè)方法回調(diào)更新父組件v-model的數(shù)據(jù),寫法如下:
export default { name: 'CommonCkeckBox', model: { prop: 'checked', event: 'changeCheck' }, props: { checked: { type: Boolean, default: false, }, // 選中狀態(tài) } }
這種寫法就意味著,父組件 雙向綁定的數(shù)據(jù)會(huì)綁定到子組件名為checked的props屬性,并且,當(dāng)子組件調(diào)用this.$emit('changeCheck', value)時(shí),會(huì)同步的更新父組件的數(shù)據(jù),實(shí)現(xiàn)雙向綁定。
接下來附一段自定義checkbox的代碼以作參考:
<template> <div class="check-box-container" @click="toggleCheck()" :> <div class="checkbox-icon"> <!-- 三種狀態(tài) 選中 未選 禁用 --> <img alt :src="`${$cdnImageUrl}/cart/icon-selected.png`" :width="width" :height="height" key="select" v-if="checked&&!disabled"/> <img alt :src="`${$cdnImageUrl}/cart/icon-unselected.png`" :width="width" :height="height" key="unselected" v-if="!checked&&!disabled" /> <img alt :src="`${$cdnImageUrl}/cart/icon-unselected.png`" :width="width" :height="height" class="disabled" key="unselected" v-if="disabled"/> </div> <slot></slot> </div> </template> <script> /** * 全局統(tǒng)一彈窗 */ export default { name: 'CommonCkeckBox', model: { prop: 'checked', event: 'changeCheck' }, props: { checked: { type: Boolean, default: false, }, // 選中狀態(tài) disabled: { type: Boolean, default: false, }, // 是否禁用 width: { type: String, default: '16px', }, // 按鈕默認(rèn)寬度 height: { type: String, default: '16px', }, // 按鈕默認(rèn)高度 }, created() { }, data() { return { } }, methods: { /** * 切換選中回傳 */ toggleCheck() { this.$emit('changeCheck', !this.checked) this.$emit('toggleCheck') } }, watch: { checked: { handler(newValue, oldValue) { // 開放狀態(tài)變更事件 this.$emit('onChange') }, deep: true } }, } </script> <style lang="scss" scoped> .check-box-container{ display: inline-block; .checkbox-icon{ img{ transform: translateZ(0); will-change: auto; } .disabled{ background-color:#f5f5f5; border-radius: 50%; } } } </style>
父組件:
<common-checkbox v-model="item.goodsSelected" class="left" :width="'16px'" :height="'16px'"></common-checkbox>
具體用哪種方式根據(jù)項(xiàng)目場(chǎng)景選擇,若第一種不滿足需求,可以嘗試第二種實(shí)現(xiàn)。
感謝各位的閱讀!關(guān)于“vue自定義組件如何實(shí)現(xiàn)v-model雙向綁定數(shù)據(jù)”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。