寫了幾天谁撼,終于在今天早上完成得差不多了,是一個集百度地圖舟肉,echarts和vue的一個小項目。
具體效果:初始頁面為百度地圖查库,左上角有一個checkbox路媚,是一些地點名稱,點擊勾選一個地點后樊销,使這個地點在地圖上標記出來磷籍,只是路由跳轉(zhuǎn)而已。點擊標記可以跳轉(zhuǎn)到有echarts的頁面现柠,有一個tab院领,可以切換以年月日為橫坐標的圖表。
這么看起來够吩,算是這段時間學(xué)到的東西的綜合應(yīng)用了比然,感謝老板。(不做完不下班是真的狠)
那些vue的項目環(huán)境啊周循,路由啊强法,axios万俗,怎么搭建,怎么加載饮怯,不會就bing一下闰歪。
很重要的問題,地圖什么的千萬不要寫在App.vue上蓖墅,不然之后的路由會出問題库倘。感謝老部長把我?guī)С隹印?br>
按照我寫的過程一步一步來把,現(xiàn)在回過頭看论矾,步驟是可以優(yōu)化的教翩,因為是老板一天一天的給任務(wù),是按照他的任務(wù)順序?qū)懗鰜淼摹?br>
第一步:寫百度地圖贪壳。相當于之前的百度地圖學(xué)習(xí)饱亿,但是比之前的還簡單不少,只要獲取后臺數(shù)據(jù)并把點渲染到地圖上就好了闰靴。
整段代碼都放上來吧彪笼,注釋的地方很大程度是我的思考過程,記得要在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"]; //經(jīng)度
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]); //設(shè)置點擊響應(yīng)事件
}
}
}
var opts = {
width: 250, // 信息窗口寬度
height: 30, // 信息窗口高度
title: "", // 信息窗口標題
enableMessage: true //設(shè)置允許信息窗發(fā)送短息
};
// 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.;
// },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); // 創(chuàng)建信息窗口對象
// 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); // 創(chuàng)建信息窗口對象
// 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 //引入組件
然后就跟著那個博客的內(nèi)容寫零渐,具體的數(shù)據(jù)啊那些東西窒舟,還是要靠自己。
第三步诵盼,三個圖表的跳轉(zhuǎn)惠豺。
一開始是老板說,點擊titile就改變數(shù)據(jù)的顯示风宁,就是點擊year就顯示年的數(shù)據(jù)洁墙,點擊month就顯示月的數(shù)據(jù)。
但是涉及到橫坐標的改變戒财,能力有限热监,研究了幾個小時無果,就改變了方法饮寞。將三個圖表分別寫成年月日三個組件孝扛,用一個tab和router-view來實現(xiàn)三個年月日的圖表跳轉(zhuǎn)列吼。
具體就是在路由里面設(shè)置:
{
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的路由設(shè)置很關(guān)鍵啊,要記住啊苦始。記得在路由的上面要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控件陌选,點擊顯示各個點理郑。
老板說完我就頭暈,在紙上寫寫畫畫怎么實現(xiàn)柠贤。邏輯這個東西實在是難搞香浩。要先找出地圖上的點就是makers與checkbox的關(guān)系。
然后如何在checkbox已選中的情況重新標記點臼勉。能力實在有限啊邻吭,又是想了幾個小時,嘗試了我的各種想法都沒辦法實現(xiàn)宴霸,老板看我做不出來囱晴,就指了跳明路,用路由跳轉(zhuǎn)來實現(xiàn)地圖重新加載把瓢谢。思路一下就清晰了畸写,用一個數(shù)組來記錄每個點的狀態(tài),就是選中還是沒選中氓扛,選中就在數(shù)組里面push相應(yīng)的數(shù)字枯芬。例如:選中第2個checkbox就push '1'到數(shù)組。通過數(shù)組來標出相應(yīng)的地點采郎,然后將這個數(shù)組當作參數(shù)來傳遞到另外一個地圖組件千所,就是在兩個地圖組件里面來回跳轉(zhuǎn),來實現(xiàn)每一次地點標注的重新渲染蒜埋。邏輯在接下來的實現(xiàn)效果的過程中不斷完善淫痰,真是一種極其良好的coding體驗。
一開始是有點蠢的整份,貪快待错,把checkbox數(shù)據(jù)寫死了,因為我知道數(shù)據(jù)里面就四個點烈评,我就寫了四個checkbox火俄,每一個check都綁定一個方法,就是push數(shù)字到數(shù)組里(option)讲冠,然后瓜客,php同事叼我了,說他改了數(shù)據(jù)之后怎么辦,那沒辦法了忆家,想辦法用vue渲染數(shù)據(jù)里面的地點咯犹菇,其實也挺簡單的 就是懶:
<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(地圖標點)關(guān)聯(lián)起來芽卿,參考之前的循環(huán)輸出獲得的數(shù)據(jù)來一個一個標記出數(shù)據(jù)里的點揭芍,我就想到了,用兩個for循環(huán)來相匹配option和makers卸例。就是先for循環(huán)出makers称杨,再將makers的索引放入下一個循環(huán),當兩個索引相等時筷转,option的數(shù)字就跟是第幾個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"]; //經(jīng)度
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]); //設(shè)置點擊響應(yīng)事件
}
}
}
檢驗方法就是 要利用console.log打印,這個方法真是太好用了呜舒。
因為是跳轉(zhuǎn)锭汛,所以是要兩個組件。就復(fù)制了一個cross組件袭蝗。然后將option作為路由參數(shù)傳給cross唤殴,Bmap(當前的地圖組件)也同樣是如此,然后要將接收到的option數(shù)據(jù)放到當前組件的option里到腥。
路由:
routes: [
{
path: '/',
name: 'Bmap',
component: Bmap,
},
{
path: '/cross',
name: 'cross',
component: cross
},
跳轉(zhuǎn)方法與傳參:
methods: {
across: function() {
this.$router.push({ path: "/cross", query: { options: this.options } });
},
獲取數(shù)據(jù)朵逝,寫在axios里面,因為 map渲染就是在axios獲取到數(shù)據(jù)之后渲染的乡范。
this.options = this.$route.query.options;
this.options = this.options == undefined ? [] : this.options;
第二行代碼是什么意思呢配名,第一個=號是賦值,第二個==號是判斷晋辆,就是判斷this.options是不是等于undefined渠脉,等于的話,使this.options=[]栈拖,就是變成空數(shù)組连舍,不等于的話没陡,使this.options等于this.$route.query.options涩哟。因為參數(shù)傳進來之后,this.option是undefind的盼玄,應(yīng)該是跟我胡亂操作data里面的option有關(guān)贴彼,不應(yīng)該這樣寫的,但是我也沒想到其他方法埃儿,就硬撐著寫吧器仗,要靠之后的學(xué)習(xí)去彌補了。
最后就是如何判斷checkbox'的狀態(tài)來進行數(shù)組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的狀態(tài)
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的索引了,因為他們是共用一份數(shù)據(jù)的轨香,就是scope忽你,在creat()里面就把數(shù)據(jù)拉到scope里了。然后就是判斷checkbox的選中狀態(tài)臂容,來決定是否push參數(shù)進去option科雳,或者刪除掉已經(jīng)傳入的參數(shù)。刪除就是通過indexOf來查找option里面是否有等于當前index的值脓杉。有的話就刪除了糟秘。
應(yīng)該是寫得差不多了,之后再把項目傳到github上再附上網(wǎng)址吧球散。