Vue-常見的組件通訊方式

前言

最近一直在從頭開始學習vue,順手整理一下vue組件化的相關通訊方式,分析不到之處,還望各位指正。html

組件化

vue組件系統提供了⼀種抽象,讓咱們可使⽤獨⽴可復⽤的組件來構建⼤型應⽤,任意類型的應⽤界⾯均可以抽象爲⼀個組件樹。組件化能提⾼開發效率⽅便重複使⽤簡化調試步驟提高項⽬可維護性便於多⼈協同開發等。vue

組件之間常見的通訊方式

1. props / $emit

父子組件通訊vuex

// 父組件
<template>
  <div>
    <span>{{ desc }}</span>
    <child1 :msg="msg" @getEmit="getEmit"></child1>
  </div>
</template>
<script>
import child1 from "@/components/child1";
export default {
  components: { child1 },
  data() {
    return {
      msg: "我是父組件的msg",
      desc:"default"
    };
  },
  methods: {
    getEmit(data) {
      this.desc = data;
    }
  }
};
</script>

複製代碼
// 子組件 => child1
<template>
  <div>
    <span>我是父組件傳來的{{ msg }}</span>
    <button @click="getEmit"></button>
  </div>
</template>
<script>
export default {
  props: {
    msg: String
  },
  data() {
    return {
      msg: "我是父組件的msg",
      childMsg:"我是child1的msg"
    };
  },
  methods: {
    getEmit(data) {
      this.$emit("getEmit",this.childMsg)
    }
  }
};

複製代碼

2. eventBus

兄弟組件通訊npm

準備條件能夠分爲兩種方式
  
1.  npm install vue-bus / main.js中引用
    import Vue from 'vue';
    import VueBus from 'vue-bus';
    Vue.use(VueBus);
    組件中直接使用this.$bug.on()和this.$bus.emit()來作相應的處理
    
2.  建立bus.js,該文件內寫入
    import Vue from "vue";
    export default new Vue();
複製代碼
// 子組件 => child2
// 這裏採用了第二種建立bus.js的方法,而後在該組件內引用
<template>
  <div>
    <button @click="handleSendToChild3">{{ msg }}</button>
  </div>
</template>
<script>
import Bus from "@/components/bus.js";
export default {
  data() {
    return {
      msg: "點我向child3組件傳參",
      childMsg:"我是child1的msg"
    };
  },
  methods: {
    handleSendToChild3(data) {
      Bus.$emit("getData",this.childMsg)
    }
  }
};

複製代碼
// 子組件 => child3
// 這裏採用了第二種建立bus.js的方法,而後在該組件內引用
<template>
  <div>
   <span>{{ msg }}</span>
  </div>
</template>
<script>
import Bus from "@/components/bus.js";
export default {
  data() {
    return {
      msg: "",
     
    };
  },
  methods: {
    handleSendToChild3(data) {
      Bus.$on("getData",(data)=>{
          this.msg = data
      })
    }
  }
};

複製代碼

3. $attrs / $listeners

父 => 子 => 孫組件通訊ide

其中子組件只作數據傳遞
多級組件嵌套須要傳遞數據時,若是僅僅是傳遞數據,而不作中間處理,可使用這種方法
$attrs:沒有被子組件組冊prop,$listener:子組件能夠觸發父組件的非.native事件
複製代碼
// 父組件
<template>
  <div>
    <span>{{ desc }}</span>
    <child1 :msg="msg" @getEmit="getEmit" v-on="$listener"></child1>
  </div>
</template>
<script>
import child1 from "@/components/child1";
export default {
  components: { child1 },
  data() {
    return {
      msg: "我是父組件的msg",
      desc:""
    };
  },
  methods: {
    getEmit(data) {
      this.desc = data;
    }
  }
};
</script>

複製代碼
// 子組件 => child1 => 相對於child2組件,該組件爲兄弟組件
<template>
  <div>
    <child2 v-bind="$attrs"></child2>
  </div>
</template>
<script>
import child2 from "@/components/child2
export default {
 // inheritAttrs:false,不會把未被註冊的 prop 呈現爲普通的 HTML 屬性 ,也就是:prop="data" prop不會做爲html的新屬性
  inheritAttrs: false,
  components: { child2 },
  data() {
    return {
      msg: "我是父組件的msg",
      childMsg:"我是child1的msg"
    };
  },
  mounted(){
      this.$emit("getEmit",this.childMsg);
  }
 
};

複製代碼
// 子組件 => child2 => 相對比child1組件,該組件爲兄弟組件
<template>
  <div>
    <span>{{ msg }} {{ $attrs.msg }}</span>
  </div>
</template>
<script>
export default {
  data() {
    return {
      msg: "該組件拿到父組件經過child1組件傳遞過來的值 => ",
    };
  },
};

複製代碼

4. provide / inject

父 => 子、父 => 孫組件通訊組件化

這種官方不推薦使用,可是,在咱們寫UI組件庫的時候就每每頗有用了,詳見elementUI的部分源碼(如form表單),這裏我準備後續在此基礎之上再進一步展開
複製代碼
// 父組件
<template>
  <div>
    <span>{{ desc }}</span>
    <child1 :msg="msg"></child1>
  </div>
</template>
<script>
import child1 from "@/components/child1";
export default {
  provide:{
    desc:this.desc // 這裏不接收動態傳參,可是能夠直接傳this過去,從而實現動態響應式
  }
  components: { child1 },
  data() {
    return {
      msg: "我是父組件的msg",
      desc:"我是父組件的desc"
    };
  }
};
</script>

複製代碼
// child1部分代碼上面已經贅述過多,此處省略
複製代碼
// 孫組件 =>  grandson1
<template>
  <div>
    <span>{{ desc }}</span>
  </div>
</template>
<script>
export default {
  inject:['desc'],
};
</script>

複製代碼

5. $ref

父子組件通訊學習

// 父組件
<template>
  <div>
    <child1 ref="sendMsg"></child1>
  </div>
</template>
<script>
import child1 from "@/components/child1";
export default {
  components: { child1 },
  data() {
    return {
      msg: "我是父組件的msg",
    };
  },
  mounted() {
      this.refs.sendMsg.handleSendToChild1(this.msg)
  }
};
</script>

複製代碼
// 子組件 => child1
<template>
  <div>
    <span>{{ msg }} </span>
  </div>
</template>
<script>
export default {
  data() {
    return {
      msg: "",
    };
  },
  methods: {
    handleSendToChild1(data) {
      this.msg = data;
    }   
  },
};

複製代碼

6. vuex

vue的狀態管理器,能夠集中式儲存各組件之間的狀態this

// 該小節,我準備留在之後補充....

複製代碼

講在最後

這篇文章從開頭到結尾,雖然篇幅很少,可是完成度是比較坎坷的,緣由是由於個人時間管理不夠強,寫着寫着就又開始去學習其餘的技術了(源碼這種東西看多了,真的會上癮),老是想着玉米西瓜一把抓,而忽略了一件事情從開始到閉環到重要性,但願總結於此,之後應當引覺得戒。spa

相關文章
相關標籤/搜索