前言
最近在用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>