vue元件通訊

皮蛋和豆樹發表於2019-06-08

前言

Vue元件之間的通訊 其實是一種非常常見的場景 不管是業務邏輯還是前段面試中都是非常頻繁出現的 這篇文章將會逐一講解各個傳值的方式 不過在此之前 先來總結一下各個傳值方式吧

  • 1.父元件向子元件傳值 => props
  • 2.子元件向父元件傳值 => $emit
  • 3.平級元件傳值 => 匯流排機制 event-bus
  • 4.Vuex

父元件向子元件傳值

舉個? 你在專案中定義了一個公共元件Header 這個Header裡需要根據具體的業務場景去展示不同的title 那這個時候就是一個非常常見的父元件向子元件傳值的業務場景了

下面 一起來看一下程式碼 首先 定義一個公用的Header元件 這個元件裡也沒有什麼複雜的邏輯 就是用props接受一個父元件傳遞過來的title 並且渲染到頁面上

<template>
  <!-- 通用導航欄 -->
  <div class="head-title">
    {{title}}
  </div>
</template>

<script>
export default {
  name: 'Header',
  props: {
    title: String
  }
}  
</script>
複製程式碼

父元件其實也是啥都沒有 也就是引入Header元件 並且向子元件傳遞一個title的值 子元件利用props接收到這個值 並且渲染在頁面上

<template>
  <div class="container">
    <Header :title="title" />
  </div>
</template>

<script>
import Header from "components/header/header";
export default {
  name: "Home",
  data() {
    return {
      title: "首頁"
    }
  },
  components: {
    Header
  }
}
</script>
複製程式碼

這樣就完成了一個最簡單最基礎的父元件向子元件傳值的過程 不過呢 這個props Vue其實也是支援許多擴充的了 *

  • 例如開發者可以通過 defalut 去定義一個預設值 當沒有接受到父元件傳遞過來的值的時候 可以展示這個預設值
  • type 給props指定一個型別 當型別不符合預期的時候 會在控制檯上報錯
  • 當預設的校驗規則都無法滿足要求的時候 props也支援自定義一個validator 只需要在props裡傳遞一個validator函式即可
props: {
    title: {
        validator: function () {
            // do somethings
        }
    }
}
複製程式碼

子元件向父元件傳值

說到子元件向父元件傳值之前 需要解釋一個名詞 單項資料流 也就是 子元件不能隨意更改父元件傳遞過來的值 以免造成一些資料汙染之類的情況 推薦的做法是 如果子元件想要更改一個值 應該是通知父元件 讓父元件進行更改

話不多說 還是繼續縷一縷思路 然後寫程式碼 首先 需要在子元件裡定義一個事件 例如點選事件 通過點選向父元件派發一個事件同時可以在事件裡攜帶需要向外傳遞的值 同時父元件監聽到了這個事件 並且在事件裡處理對應的邏輯

<template>
  <!-- 通用導航欄 -->
  <div class="head-title" @click="toParent">
    {{title}}
  </div>
</template>

<script>
export default {
  name: 'Header',
  props: {
    title: String
  },
  methods: {
      toParent () {
        // 第一個引數 需要父元件監聽的時間 第二個引數 向外傳遞的值
        this.$emit('getMsg','這是傳遞給父元件的值')
      }
  }
}  
</script>
複製程式碼

這個時候 子元件已經通過$emit向外傳遞了一個事件 那麼接下去就是在父元件裡去監聽這個事件 並且處理對應邏輯

<template>
  <div class="container">
    <Header :title="title" @getMsg="getMsg" />
  </div>
</template>

<script>
import Header from "components/header/header";
export default {
  name: "Home",
  data() {
    return {
      title: "首頁",
      msg: ''
    }
  },
  components: {
    Header
  },
  methods: {
    getMsg(msg) {
        console.log(this.msg)
        this.msg = msg
        console.log(this.msg)
    }
  }
}
</script>
複製程式碼

這樣通過$emit就可以成功獲取從子元件傳遞過來的值 並且父元件可以更改這個值 從而實現一些對應的業務邏輯

平級元件之間傳值

兩個沒什麼關係的元件之間有時候也是會需要傳遞一些值 例如頁面A要傳遞值給頁面B B接受這個值並且渲染在頁面上

下面來說一下實現思路

  • 1.建立一個js檔案 在檔案中新建一個vue的例項 並且在例項上新建一個EventBus 或者在vue的屬性上掛載一個envent-bus 這樣通過屬性的方式建立的event-bus是一個全域性的屬性
  • 2.在需要使用event-bus的元件裡引入 bus並且利用$emit向外觸發事件
  • 3.在需要接受值的元件裡利用$on來接受值

新建一個.js檔案 並且建立event-bus

import Vue from 'vue'
export const EventBus = new Vue()
複製程式碼

利用enent-bus向外觸發事件

<template>
    <button @click="handleClick">-</button>
</template>

<script> import { EventBus } from "../event-bus.js";
    export default {
        name: "Count",
        data () {
            return {
                num: 1,
            }
        },
        methods: {
            decrease() {
                EventBus.$emit("getNum", {
                    num:this.num,
                })
            }
        }
    }
</script>
複製程式碼

監聽事件

 EventBus.$on("getNum", (num) => {
                console.log(num)
            })
            
複製程式碼

這樣就通過event-bus成功將頁面A的值傳遞給了頁面B的值 寫起來的感覺 其實還是和子元件向父元件傳值的過程非常相似

下面還會提到Vuex傳值 不過感覺可以新開一個文章..所以..下次再見啦 ??

相關文章