Vue實現自定義組件數據雙向綁定

前言:使用Vue進行項目開發的時候,通常會用到Vue提供的組件化機制封裝開發所需要的組件以達到開發項目的需求,大到項目中的一快篩選模塊、數據表格,小到分頁面板、級聯面板、乃至一個小小的button按鈕,之所以組件化也是爲提高我們實際的開發效率,那到底什麼是組件化呢?參考一張尤玉溪大大的圖就會很快明白;

簡單來講一個完整項目會分爲很多部分,每個部分都會有各自獨立的功能,每個獨立的功能組件又是由很多小的組件構成,瞭解了什麼是組件之後,就必須要明白組件之間的通訊方式。Vue官方爲我們提供了子傳父、父傳子的方法以及屬性,但是單純使用這些是遠遠不能夠滿足我們的實際開發需求,因爲很多時候我們需要父組件與子組件直接雙向綁定數據,但是Vue中父子組件通信,都是單項的數據流,具體如下:

父組件:

<!-- 父組件 -->
<template>
  <div class="Parent">
    <el-col :span="12">
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <h2>Parent(父組件)</h2>
          <el-button style="float: right; padding: 3px 0" type="text">查看詳情</el-button>
        </div>
        <el-button type="primary" icon="el-icon-plus" circle @click.native="Add(off)"></el-button>
        <Children :Data="off"></Children>
        <el-col :span="12">
          <span>來自子組件的數據:</span>
          {{msg}}
        </el-col>
      </el-card>
    </el-col>
  </div>
</template>

子組件:

<!-- 子組件 -->
<template>
  <div class="Children">
    <el-dialog
      width="30%"
      top="15%"
      title="Children(子組件)"
      :visible.sync="off"
      :before-close="handleClose"
      modal-append-to-body="false"
      append-to-body="false"
    >
      <el-input v-model="input" placeholder="請輸入內容"></el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="off = false">取 消</el-button>
        <el-button type="primary" @click="off = false">提 交</el-button>
      </span>
    </el-dialog>
  </div>
</template>

預覽:

功能:父組件點擊“+”按鈕之後調用子組件,子組件提交數據、父組件藍色部分顯示子組件提交的數據;

思路:首先得明白子組件顯示與否依賴於off,也就是點擊"+"號之後,父組件必須改變子組件的off值子組件數據),父組件data裏必須也有個off值用於傳遞數據父組件數據,從而達到父子組件數據雙向綁定的需求;

接下來改造代碼:

<!-- 父組件 -->
<template>
  <div class="Parent">
    <el-col :span="12">
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <h2>Parent(父組件)</h2>
          <el-button style="float: right; padding: 3px 0" type="text">查看詳情</el-button>
        </div>
        <el-button type="primary" icon="el-icon-plus" circle @click.native="Add()"></el-button>
        <Children :Data="off" @GetData="GetData"></Children>
        <el-col :span="12">
          <span>來自子組件的數據:</span>
          {{msg}}
        </el-col>
      </el-card>
    </el-col>
  </div>
</template>

<script>
import Children from "./Children"; //引入Children
export default {
  components: {
    Children
  },
  data() {
    return {
      msg: "暫無", //穿傳遞初始數據
      off: false
    };
  },
  methods: {
    Add() {
      this.off = true; //修改off 打開子組件
    },
    GetData(off,input) { //這裏的off是接收子組件傳遞過來的值
      this.off = off; //把子組件的數據同步到父組件中
      this.msg = input; //同上
    }
  }
};

Parent解釋:在父組件中引入子組件Children,使用v-bind綁定父組件的off傳遞給子組件,當點擊“+”號之後執行Add方法改變off爲true,使用自定義事件監聽子組件事件是否觸發,觸發之後接收到來自子組件的數據並同步更新到父組件對應的狀態;

<!-- 組件說明 -->
<template>
  <div class="Children">
    <el-dialog
      width="30%"
      top="15%"
      title="Children(子組件)"
      :visible.sync="off"
      :modal-append-to-body="false"
      :append-to-body="false"
    >
      <el-input v-model="input" placeholder="請輸入內容"></el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="Submit(0)">取 消</el-button>
        <el-button type="primary" @click="Submit(1)">提 交</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      input: "",
      off: this.Data //賦初始值 等價於off:false
    };
  },
  props: ["Data"], //接收來自父組件的數據
  watch: {
    Data(N, O) {
      this.off = N; //每次Props數據改變的時候同步更新到off
    }
  },
  methods: {
    Submit(key){
      if(key){          //點擊提交按鈕
        alert("提交!")
        // if(....)    //此處編寫表單效驗通過後的業務邏輯
        this.off = false
      }else if(!key){
        alert("取消!") //點擊取消按鈕
        this.off = false
      }
      this.$emit('GetData',this.off,this.input)
    }
  }
};
</script>

Children解釋:props對象接收父組件數據,組件創建完畢之後第27行初始化來自父組件的數據(此處由於父組件中off值爲false,所以第一次賦值也是false,注意這裏只能賦初始值 後面的父組件傳遞的數據將不會改動,必須由watch監聽變化再更新到data > off),取消/提交調用Submit方法,(38行kye==1 1隱式轉換之後爲true所以不用麻煩寫if(key==1),42行同理),執行Submit之後改變off的值爲false即關閉子組件,並且使用$emit創建自定義事件GetData (此處GetData必須與父組件中第11行綁定的方法一致纔可以觸發自定義事件),觸發子組件的GetData事件並且同步更新到父組件中;

至此 結束,看一下效果!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章