1. 程式人生 > 程式設計 >vue自定義元件實現雙向繫結

vue自定義元件實現雙向繫結

場景:

我們比較常用的父子元件之間的互動方式:
父元件通過props將資料流入到子元件;
子元件通過$emit將更新後的陣列傳送的父元件;

今天,我們通過另一種方式實現互動,參考input框的v-model,實現自定義元件的雙向資料繫結。
即:父元件值改變,子元件的值跟著改變;反之,子元件值發生變化,父元件值隨之變化

子元件定義:

由於不能直接修改props屬性值,我們這裡定義valueData,通過監聽實時接收value值,通過click方法修改valueData。
這裡注意model語法糖prop 是接收的props屬性value,保持一致。event是先上傳遞的事件名。

程式碼如下:

<template>
  <div>
    <div>{{ `子元件值: ${value}` }}</div>
    <div @click="click">點選此處修改值</div>
  </div>
</template>

<script>
export default {
  name: "",model: {
    prop: "value",event: "change"
  },props: {
    value: Number
  },components: {},data() {
    return {
      valueData: ""
    };
  },watch: {
    value(newValue,oldValue) {
      this.valueData = newValue;
      console.log(`子元件值:${newValue}`);
    }
  },created() {
  },mounted() {
  },methods: {
    click() {
      this.valueData++;
      this.$emit("change",this.valueData);
    }
  }
};
</script>
<style lang='less' scoped>
</style>

父元件定義:

父元件通過v-model繫結text值,名稱不一定是value,可以是其他任意符合命名規範的字串,這裡是text。
子元件通過change事件更新資料後,v-mode繫結值隨之變化。
或者父元件修改text值後,子元件value值隨之變化。

程式碼如下:

<template>
  <div>
    <div>{{ `父元件值:${text}` }}</div>
    <div @click="click">點選此處修改值</div>


    <span>-----------------------------------------------------------</span>

    <test-children v-model="text"></test-children>

  </div>
</template>

<script>
import TestChildren from "@/views/TestChildren";

export default {
  name: "",components: { TestChildren },data() {
    return {
      text: 1
    };
  },watch: {
    text(newValue,oldValue) {
      console.log(`父元件值:${newValue}`);
    }
  },methods: {
    click() {
      this.text--;

    }
  }
};
</script>
<style lang='less' scoped>
</style>

結果:

直接copy程式碼到自己專案測試。無論是通過父元件改變值,還是子元件改變值。兩個元件通過v-mode繫結的值始終保持一致。

答疑:

有同學就問了 ,這不是和通過props向下流入資料,再通過$emit方式向上傳遞資料一樣麼也能實現我這種雙向繫結的效果。 其實不然,如果不通過v-model,那麼我們勢必會在父元件寫這樣的程式碼:

<test-children @change="changeText"></test-children>

然後在通過定義changeText方法修改text值。

試想,當我們的頁面比較複雜,引用元件量比較龐大,頁面中就需要多定義這樣十幾、二十幾個方法。可閱讀行大大降低,增加了維護成本。

擴充套件:

vue2.3之後提供了sync方式,也能實現雙向繫結

父元件中的寫法:

<test-children :value.sync="text"></test-children>

子元件中不需要使用下面model定義,直接刪除即可。

model: {
prop: “value”,event: “change”
},

向父元件傳遞資料使用如下方式:

this.$emit("update:value",this.valueData);

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。