溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue自定義組件如何實現v-model雙向綁定數據

發布時間:2021-10-08 11:26:45 來源:億速云 閱讀:217 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關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雙向綁定數據”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女