優雅的封裝model組件

業務場景

當本身想封裝ui組件庫的modal組件時,咱們最初的設想是父組件傳遞一個布爾值(isShow)給子組件,子組件根據該值顯示隱藏;可是組件經過v-model綁定的數據是雙向綁定的,意味着這個數據必須能夠set數據,可是vue裏的props是單向數據流,是不能set數據給父組件的(會形成數據流混亂)。
之前我是這麼作的,經過在自組件定義方法,而後父組件直接調用$ref.xxx來改變子組件的數據,從而達到顯示隱藏的目的。如下爲代碼:vue

<template>
  <div>
    <Modal v-model="isShow" width="600px" title="title">
      <div slot="footer">
        <Button @click="isShow = false">關閉</Button>
      </div>
    </Modal>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch, Emit } from 'vue-property-decorator';

@Component
export default class SecretKeyManage extends Vue {
  isShow: boolean = false
}
</script>

可是這樣直接調用子組件的方法總歸不太優雅,vue推薦使用props將父組件的數據向下傳遞,因而有了下面的這種寫法:ui

代碼實現

<template>
  <div>
    <Modal v-model="isShow" width="600px" title="title">
      <div slot="footer">
        <Button @click="isShow = false">關閉</Button>
      </div>
    </Modal>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch, Emit } from 'vue-property-decorator';

@Component
export default class MyModal extends Vue {
  // 父組件傳遞的值 用於初始化 isShow 
  @Prop({ default: false }) isMyModalShow!: boolean;

  // 用於綁定v-model
  get isShow() {
    return this.secretKeyModal;
  }
  set isShow(val) {
    this.handleEmit(val)
  }
  @Emit('update:isMyModalShow')
  handleEmit(val: boolean) {
    return val;
  }

  @Watch('isShow')
  handleShowModal(val: boolean) {
    if (!val) return;
    // 當顯示modal組件的時候 do something
    
  }
}
</script>

// 父組件調用
<MyModal :isMyModalShow.sync="isMyModalShow" />
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

export default class MyModal extends Vue {
  isMyModalShow: boolean = false
}
    
</script>

其實很簡單 就是經過 set 將數據回傳給父組件,須要注意的是父組件綁定isMyModalShow的時候須要加sync修飾符。this

以上全部代碼使用ts實現 雙向綁定

相關文章
相關標籤/搜索