Vue(4):Vue兄弟組件傳值在echarts點擊事件中的使用

前言
​ 最近在用Vue+echarts+d3作一個項目,網上大多數是零散的,我把項目中遇到 的問題都總結起來,放在博客下,便於往後查看以及分享一下爬坑經驗。vue

​ 我所遇到的困難在網上大多數能夠找到,但比較零散,且很差找,這是Vue項目的第四篇博客,由於也是初次使用Vue,因此多詳細記錄一下。app

這篇博客主要分享的知識點是Vue中父組件傳以及echarts鼠標事件中的父組件傳值,還解決了一個在父組件傳值的過程當中div被加載了兩次的問題。echarts

1.Vue子組件向父組件傳值

​ 二話不說,先上代碼。函數

子組件代碼:this

<template>
    <div class="child">
       <button @click="sendMsg">給父組件發送數據</button>
    </div>
</template>
<script>
export default {
     name:'child',
     methods:{
         sendMsg(){
             //this.$emit()是向父組件發送數據的函數
             //參數1:規定必須父組件使用的事件類型,
             //參數2: 向父組件發射的數據
             //getData: 是父組件指定的傳數據綁定的函數,在父組件中引入子組件標籤時定義
             //"老爹,我來啦":子組件給父組件傳遞的數據
             this.$emit('getData', "老爹,我來啦")
         }
     }
}
</script>

父組件代碼:spa

<template>
    <div class="parent">
        <--第三步,child爲引入子組件的名字,@getData爲指定數據綁定的函數,在子組件中的this.$emit()給這個函數發送數據,getMsgFormSon爲父組件接收子組件傳值過來的函數,用於接收數據-->
        <child @getData="getMsgFormSon"></child>
    </div>
</template>

<script>
import child from './child.vue'//第一步,先在這裏導入子組件文件,並指名爲child
export default {
    components:{
        child,//第二步,把子組件引入到父組件中,若是不寫這個,在第三步的時候會報錯,說child沒有註冊
    },
    methods:{
            getMsgFormSon(data){
                console.log(data)//當點擊按鈕的時候,父組件就會打印"老爹,我來啦"
            }
    }
}
</script>

2.Vue父組件向子組件傳值

在本系統中設定APP.vue是惟一的父組件,其餘全部的組件都是他的子組件.net

參考文檔博客文章 https://blog.csdn.net/qq_42376617/article/details/106193508code

子組件代碼:component

<template>
    <div class="child"></div>
</template>
<script>
export default {
     name:'child',
     props: ['getCityName'],//getCityName是父組件中定義的,必定要有這行,代表從父組件中獲取到這個值
     watch: {//監聽事件,父組件值發生變化,就會傳給子組件
      getCityName(data) {
        console.log(data)//這裏的data就是父組件穿過來的數據
      }
    },
}
</script>

父組件代碼:orm

父組件傳值用到的是「v-bind:」。

<template>
    <div class="parent">
		<button v-bind:getCityName="CityName">給子組件發送數據</button>
    </div>
</template>

<script>
import child from './child.vue'//第一步,先在這裏導入子組件文件,並指名爲child
export default {
    data(){
        return{
            CityName:'china'//在父組件中給CityName複製,把這個值傳給子組件,能夠在下面的代碼中對CityName進行動態複製,只要只一改變,子組件就會監聽到,數據就傳送過去了。
        }
    }
    components:{
        child,//把子組件引入到父組件中,若是不寫這個,在第三步的時候會報錯,說child沒有註冊
    },
}
</script>

3.Vue兄弟組件傳值

​ 兄弟組件之間傳值是須要一箇中轉站的,也就是要藉助於事件車, 經過事件車的方式傳遞數據 。也就是說讓各兄弟同用一個事件機制( 建立一個Vue的實例 )。

​ 傳遞數據方,經過一個事件觸發eventVue. e m i t ( 方 法 名 , 傳 遞 的 數 據 ) 。 接 收 數 據 方 , 通 過 m o u n t e d ( ) 觸 發 e v e n t V u e . emit(方法名,傳遞的數據)。 接收數據方,經過mounted(){}觸發eventVue. emit()mounted()eventVue.on(方法名,function(接收數據的參數){用該組件的數據接收傳遞過來的數據}),此時函數中的this已經發生了改變,能夠使用箭頭函數。

先建立一個js文件夾,文件夾下面建立 eventVue.js ,內容爲

import Vue from 'vue'
export default new Vue

父組件引入兩個子組件(路由方法):

<router-view name="main" />
<router-view name="bottom" />

子組件bottom(傳遞方):

<template>
    <div class="child">
       <button @click="sendMsg">給父組件發送數據</button>
    </div>
</template>

<script>
 import eventVue from '../js/eventVue.js'
 export default {
    name:'app',
    sendMsg(){
         eventVue.$emit('getData', "大哥,弟弟bottom來啦")
    }
</script>

子組件main(接收方):

<script>
 import eventVue from '../js/eventVue.js'
 export default {
    name:'app',
    mounted: function () {
      this.getMsg();
    },
    methods: {
      getMsg() {
        eventVue.$on("getData", (data) => { //這裏最好用箭頭函數,否則this指向有問題
          console.log(data)
        })
      },
    }
</script>

​ 當點擊按鈕時,組件main就會打印"大哥,弟弟bottom來啦"。這就實現了兄弟間傳值
另一種放方式就是經過父組件來轉發,子組件A先把值傳給父組件,父組件再傳給子組件B,這樣就完成了兄弟組件的通訊。

4.Vue傳值致使div覆蓋問題

​ 我在完成子組件向父組件傳值後,發現有兩個按鈕,一個按鈕能夠發送數據,也就是有點擊事件,另一個按鈕沒有點擊事件,也就是不能夠發送數據。後來我看了一下個人echarts圖,也被畫了兩次,也就是說個人子組件被調用了兩次,因此纔會發生重畫div的問題。

​ 解決辦法是,由於我先作的是多個組件合成一個頁面,也就是Vue的多組件問題,我在以前調用組件的時候就已經調用過一次子組件,在APP.vue的文件中寫了 這行代碼掉用子組件,但咱們在傳值的時候又在父組件中寫了<child @getData=「getMsgFormSon」>,這就致使子組件被調用兩次,因此div也就被繪製兩次,咱們把APP.vue文件中的 去掉就行了。

5.echarts鼠標事件給組件傳值

​ 上面講的子組件向父組件傳值是經過按鈕來傳的,但咱們畫echarts時並非用按鈕來傳值的,而是經過給圖形綁定on事件來獲取圖形中的值,因此咱們就要當點擊圖形的時候給父組件傳值,d3傳值也同樣。若是咱們直接在點擊函數中寫

this.$emit('getData', "老爹,我來啦")

​ 會報一個錯誤,說 TypeError: this.$emit is not a function,這時咱們只須要進行一步操做便可解決這個問題。發現是this指向的問題,先把this保存下來便可。看示例代碼:

<script>
export default {
    methods: {
          LineChart(divid) {
            let that = this;//把this賦給變量that
            myChart.on("click", function (param) {
              that.$emit('getData', param['name']);//用that.$emit便可解決傳值問題
            })
          },
    }
}
</script>
相關文章
相關標籤/搜索