這篇文章給大家分享的是有關vue自定義組件如何實現v-model雙向綁定數據的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
項目中會遇到自定義公共組件供項目調用,正常情況可以使用 props定義參數接收父組件傳的參數,然后通過子組件的$emits()方法回傳數據給父組件。
類似如下:
父組件
<common-checkbox :checked="goodsSelected" class="left" :height="'16px'" :width="'16px'" @checkChange="checkChange"></common-checkbox>
/** * 接收子組件回傳進行處理 */ checkChange(value) { this.goodsSelected=value//子組件數據賦值給父組件 }
子組件
/** * 切換選中回傳 */ toggleCheck(value) { this.$emit('changeCheck', value)//回傳方法,把子組件變化后的數據回傳給父組件處理 }
但是這種寫法需要調用公共組件的頁面額外寫處理的方法,而且顯得太low,我們可不可以像是框架自帶的公共組件一樣去聲明直接v-model雙向綁定呢?接下來提供項目中實際遇到這種情況的處理方法
第一種方式:
正常情況下當你在父組件里給子組件綁定 v-model屬性時,子組件中會默認的將 v-model綁定的數據,付給子組件 名為 value的props屬性,value依然需要提前在子組件props中聲明,否則接收不到。
當 value修改后,并不會立即雙向回傳給父組件。如果想回傳實現同步更新父組件的v-model需要如下操作
this.$emit('input', value)
當未聲明雙向綁定回傳的事件時,默認通過input事件回傳,為什么說 “當未聲明雙向綁定回傳的事件”,這個便是第二種方式,下面會講到。
簡單來說,第一種方式的實現,首先是v-model綁定父組件數據 ,然后子組件value 的props屬性自動接收,最后當數據更改后調用this.$emit('input', value) 回傳父組件,這樣父組件不需要額外實現子組件的回傳就可以實現雙向綁定
第二種方式:
前面提到 “當未聲明雙向綁定回傳的事件” 默認使用 input回傳,既然這樣說了那就存在,如果我不用input呢?這就需要了解vue的一個特殊的屬性:model,這個屬性可以用來聲明 子組件用哪個字段去接收雙向綁定的數據,以及用哪個方法回調更新父組件v-model的數據,寫法如下:
export default { name: 'CommonCkeckBox', model: { prop: 'checked', event: 'changeCheck' }, props: { checked: { type: Boolean, default: false, }, // 選中狀態 } }
這種寫法就意味著,父組件 雙向綁定的數據會綁定到子組件名為checked的props屬性,并且,當子組件調用this.$emit('changeCheck', value)時,會同步的更新父組件的數據,實現雙向綁定。
接下來附一段自定義checkbox的代碼以作參考:
<template> <div class="check-box-container" @click="toggleCheck()" :> <div class="checkbox-icon"> <!-- 三種狀態 選中 未選 禁用 --> <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> /** * 全局統一彈窗 */ export default { name: 'CommonCkeckBox', model: { prop: 'checked', event: 'changeCheck' }, props: { checked: { type: Boolean, default: false, }, // 選中狀態 disabled: { type: Boolean, default: false, }, // 是否禁用 width: { type: String, default: '16px', }, // 按鈕默認寬度 height: { type: String, default: '16px', }, // 按鈕默認高度 }, created() { }, data() { return { } }, methods: { /** * 切換選中回傳 */ toggleCheck() { this.$emit('changeCheck', !this.checked) this.$emit('toggleCheck') } }, watch: { checked: { handler(newValue, oldValue) { // 開放狀態變更事件 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>
具體用哪種方式根據項目場景選擇,若第一種不滿足需求,可以嘗試第二種實現。
感謝各位的閱讀!關于“vue自定義組件如何實現v-model雙向綁定數據”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。