美文网首页
2019-01-17 百度地图,echarts,vue项目

2019-01-17 百度地图,echarts,vue项目

作者: E1FANG | 来源:发表于2019-01-17 16:06 被阅读0次

写了几天,终于在今天早上完成得差不多了,是一个集百度地图,echarts和vue的一个小项目。
具体效果:初始页面为百度地图,左上角有一个checkbox,是一些地点名称,点击勾选一个地点后,使这个地点在地图上标记出来,只是路由跳转而已。点击标记可以跳转到有echarts的页面,有一个tab,可以切换以年月日为横坐标的图表。
这么看起来,算是这段时间学到的东西的综合应用了,感谢老板。(不做完不下班是真的狠)

那些vue的项目环境啊,路由啊,axios,怎么搭建,怎么加载,不会就bing一下。
很重要的问题,地图什么的千万不要写在App.vue上,不然之后的路由会出问题。感谢老部长把我带出坑。
按照我写的过程一步一步来把,现在回过头看,步骤是可以优化的,因为是老板一天一天的给任务,是按照他的任务顺序写出来的。
第一步:写百度地图。相当于之前的百度地图学习,但是比之前的还简单不少,只要获取后台数据并把点渲染到地图上就好了。
整段代码都放上来吧,注释的地方很大程度是我的思考过程,记得要在index.html上引入百度地图的js文件,还有在组件里面给百度地图一个容器div。

created() {
    var url = this.HOME;
    this.$axios
      .post(url)
      .then(res => {
        this.options = this.$route.query.options;
        this.options = this.options == undefined ? [] : this.options;
       
        // console.log(res.data);
        this.scope = res.data.data.scope;
        // console.log(this.scope);
        var agent = navigator.userAgent.toLowerCase();
        var flag = agent.match(/(iphone|ipad|android|Touch)/i);
        var map = new BMap.Map("allmap");
        map.centerAndZoom(new BMap.Point(116.404, 39.915), 12);
        map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
        if (!flag) {
          var top_left_navigation = new BMap.NavigationControl(); //左上角,添加默认缩放平移控件
          map.addControl(top_left_navigation);
          var top_right_navigation = new BMap.NavigationControl({
            anchor: BMAP_ANCHOR_TOP_RIGHT,
            type: BMAP_NAVIGATION_CONTROL_SMALL
          }); //右上角
          map.addControl(top_right_navigation);
          map.enableScrollWheelZoom(true);
        }
        // var scope = res.data.data.scope;
        // console.log(scope)
        var markers = this.markers;
        var point = this.point;
        for (var i = 0; i < this.scope.length; i++) {
          for (var a = 0; a < this.options.length; a++) {
            if (i == this.options[a]) {
              var p0 = this.scope[i]["longitude"]; //经度
              var p1 = this.scope[i]["latitude"]; // 纬度
              this.point[i] = new BMap.Point(p0, p1);
              // map.panTo(point[i]);
              this.markers[i] = new BMap.Marker(point[i]);
              map.addOverlay(markers[i]); // 将标注添加到地图中
              map.panTo(point[this.options[0]]);
              addClickHandler("驻点名称:" + this.scope[i]["name"], markers[i]); //设置点击响应事件
            }
          }
        }

        var opts = {
          width: 250, // 信息窗口宽度
          height: 30, // 信息窗口高度
          title: "", // 信息窗口标题
          enableMessage: true //设置允许信息窗发送短息
        };
        // var ifOpen =true;
        var _this = this;
        function addClickHandler(content, marker) {
          marker.addEventListener("click", function(e) {
            // openInfo(content, e);
            _this.$router.push({ path: "/Charts" });
            // setTimeout(function(){
            //     window.location.href="http://yao.ktvit.cn/yq2.html";
            //   },500)
          });
        }
        //自动打开信息窗口
        // autoOpenInfo('驻点名称:' + this.scope[0]['name'], this.scope[0].longitude,this.scope[0].latitude);
        // function autoOpenInfo(content, lng,lat) {
        //     console.log(lng)
        //     var point = new BMap.Point(lng, lat);
        //     var infoWindow = new BMap.InfoWindow(content, opts);  // 创建信息窗口对象
        //     map.openInfoWindow(infoWindow, point); //开启信息窗口
        //     map.panTo(point);
        //   }
        // function openInfo(content, e) {
        //     var p = e.target;
        //     console.log(p)
        //     console.log(p.getPosition());
        //     var point = new BMap.Point(p.getPosition().lng, p.getPosition().lat);
        //     var infoWindow = new BMap.InfoWindow(content, opts);  // 创建信息窗口对象
        //     map.openInfoWindow(infoWindow, point); //开启信息窗口
        //     map.panTo(point);
        //     // clickHandler(infoWindow);
        // }
        this.options = [];
      })
      .catch(error => {
        console.log(error);
      });
  }

第二步,echarts
在vue里引入echarts,我是参考这篇博客的 https://blog.csdn.net/Amanda_wmy/article/details/79457679
要配置的东西不少。
首先要在vue项目里 install echarts,然后mian.js 文件里面引入echarts组件

// 引入饼状图组件
require('echarts/lib/chart/pie')
// 引入提示框和title组件,图例
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
require('echarts/lib/component/legend')
Vue.prototype.$echarts = echarts //引入组件

然后就跟着那个博客的内容写,具体的数据啊那些东西,还是要靠自己。

第三步,三个图表的跳转。
一开始是老板说,点击titile就改变数据的显示,就是点击year就显示年的数据,点击month就显示月的数据。
但是涉及到横坐标的改变,能力有限,研究了几个小时无果,就改变了方法。将三个图表分别写成年月日三个组件,用一个tab和router-view来实现三个年月日的图表跳转。
具体就是在路由里面设置:

    {
      path: '/Charts',
      name: 'Charts',
      component: Charts,
      children: [
        {
          path: '/year',
          name: 'year',
          component: year
        },
        {
          path: '/',
          name: 'year',
          component: year
        },
        {
          path: '/month',
          name: 'month',
          component: month,
        },
        {
          path: '/day',
          name: 'day',
          component: day,
        },
      ]
    },

children的路由设置很关键啊,要记住啊。记得在路由的上面要import各个组件。
然后集成在一个charts的组件里

<div style="margin-top:10px;">
        <router-link to="year" class="dianji">year</router-link>
        <router-link to="month" class="dianji">month</router-link>
        <router-link to="day" class="dianji">day</router-link>
        <router-view></router-view>
    </div>

第三部,在地图左上角加一个checkbox控件,点击显示各个点。
老板说完我就头晕,在纸上写写画画怎么实现。逻辑这个东西实在是难搞。要先找出地图上的点就是makers与checkbox的关系。
然后如何在checkbox已选中的情况重新标记点。能力实在有限啊,又是想了几个小时,尝试了我的各种想法都没办法实现,老板看我做不出来,就指了跳明路,用路由跳转来实现地图重新加载把。思路一下就清晰了,用一个数组来记录每个点的状态,就是选中还是没选中,选中就在数组里面push相应的数字。例如:选中第2个checkbox就push '1'到数组。通过数组来标出相应的地点,然后将这个数组当作参数来传递到另外一个地图组件,就是在两个地图组件里面来回跳转,来实现每一次地点标注的重新渲染。逻辑在接下来的实现效果的过程中不断完善,真是一种极其良好的coding体验。
一开始是有点蠢的,贪快,把checkbox数据写死了,因为我知道数据里面就四个点,我就写了四个checkbox,每一个check都绑定一个方法,就是push数字到数组里(option),然后,php同事叼我了,说他改了数据之后怎么办,那没办法了,想办法用vue渲染数据里面的地点咯,其实也挺简单的 就是懒:

<div class="check-box">
        <template v-for="(item,index) in scope">
          <label  @change="joinOptions(index,item)" :key="index">
            {{item.name}}
            <input type="checkbox" id="one" v-model="item.state">
          </label>
      </template>

然后,想办法将option与makers(地图标点)关联起来,参考之前的循环输出获得的数据来一个一个标记出数据里的点,我就想到了,用两个for循环来相匹配option和makers。就是先for循环出makers,再将makers的索引放入下一个循环,当两个索引相等时,option的数字就跟是第几个makers相等了。

var markers = this.markers;
       var point = this.point;
       for (var i = 0; i < this.scope.length; i++) {
         for (var a = 0; a < this.options.length; a++) {
           if (i == this.options[a]) {
             var p0 = this.scope[i]["longitude"]; //经度
             var p1 = this.scope[i]["latitude"]; // 纬度
             this.point[i] = new BMap.Point(p0, p1);
             // map.panTo(point[i]);
             this.markers[i] = new BMap.Marker(point[i]);
             map.addOverlay(markers[i]); // 将标注添加到地图中
             map.panTo(point[this.options[0]]);
             addClickHandler("驻点名称:" + this.scope[i]["name"], markers[i]); //设置点击响应事件
           }
         }
       }

检验方法就是 要利用console.log打印,这个方法真是太好用了。
因为是跳转,所以是要两个组件。就复制了一个cross组件。然后将option作为路由参数传给cross,Bmap(当前的地图组件)也同样是如此,然后要将接收到的option数据放到当前组件的option里。
路由:

routes: [
    {
      path: '/',
      name: 'Bmap',
      component: Bmap,
    },
    {
      path: '/cross',
      name: 'cross',
      component: cross
    },

跳转方法与传参:

 methods: {
    across: function() {
      this.$router.push({ path: "/cross", query: { options: this.options } });
    },

获取数据,写在axios里面,因为 map渲染就是在axios获取到数据之后渲染的。

this.options = this.$route.query.options;
this.options = this.options == undefined ? [] : this.options;

第二行代码是什么意思呢,第一个=号是赋值,第二个==号是判断,就是判断this.options是不是等于undefined,等于的话,使this.options=[],就是变成空数组,不等于的话,使this.options等于this.$route.query.options。因为参数传进来之后,this.option是undefind的,应该是跟我胡乱操作data里面的option有关,不应该这样写的,但是我也没想到其他方法,就硬撑着写吧,要靠之后的学习去弥补了。

最后就是如何判断checkbox'的状态来进行数组options的增删了。

 <div class="check-box">
        <template v-for="(item,index) in scope">
          <label  @change="joinOptions(index,item)" :key="index">
            {{item.name}}
            <input type="checkbox" id="one" v-model="item.state">
          </label>
      </template>

用v-model="item.state"来绑定input的状态

joinOptions: function(index,item) {
      if(item.state){
        this.options.push(index);
      }else{
        var index2 = this.options.indexOf(index);
        if(index2>-1){
          this.options.splice(index2,1);
        }
      }
      //  item.state = !item.state;
      console.log(this.options);
    },

方法的传参比较重要,将index和item都传进来,index就相当于是makes和checkbox的索引了,因为他们是共用一份数据的,就是scope,在creat()里面就把数据拉到scope里了。然后就是判断checkbox的选中状态,来决定是否push参数进去option,或者删除掉已经传入的参数。删除就是通过indexOf来查找option里面是否有等于当前index的值。有的话就删除了。

应该是写得差不多了,之后再把项目传到github上再附上网址吧。

相关文章

网友评论

      本文标题:2019-01-17 百度地图,echarts,vue项目

      本文链接:https://www.haomeiwen.com/subject/ghsidqtx.html