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