前后端分离的webgis项目(二)

二. 前端vue+leaflet
首先你得安装nodejs并配置环境,看这里,然后安装vue-cli,用它来快速新建项目
可以使用下列任一命令安装

npm install -g @vue/cli
# OR
yarn global add @vue/cli

yarn如果没有,要先安装,yarn的安装包的速度比npm快,建议使用,用下面的命令安装,注意在前面参考的文章配置了global-folder和cache-folder,因此yarn安装后也要配置,看这里,不然会出问题

npm install -g yarn

vue-cli安装完后,使用可以使用vue -V或vue --version命令查看安装版本示意是否安装成功

接下来可以使用vue ui命令进行可视化创建,非常香,但是这里使用命令行创建项目,以便熟悉命令行操作
随意进入一个文件夹,cmd创建项目:vue create 你的项目名

vue create -n hello-world

在这里我加了一个参数-n用来跳过 git 初始化,详情参见官网

创建之后可以看到如下画面

第一个是我之前创建项目保留的项目配置,可以在你的C盘用户文件夹下的.vuerc文件查看和修改配置
第二个是默认配置
第三个是手动选择配置
这里选择第二个默认配置

项目新建完毕后,安装路由使用下面命令

yarn add vue-router

安装axios用于前后端通信

yarn add axios

之后安装leaflet依赖包

yarn add vue2-leaflet

最后安装leaflet地图控制依赖包,如果下载的依赖包地图不全,可以在网上搜索chinesetmsproviders,然后copy覆盖下载的依赖包

yarn add leaflet.chinesetmsproviders

项目的目录如下

main.js内容

import Vue from 'vue'
import App from './App.vue'
import 'leaflet/dist/leaflet.css'
import L from 'leaflet'
import router from './router'Vue.prototype.$imgUrl = process.env.VUE_APP_IMAGESVue.config.productionTip = false/* leaflet icon */
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),iconUrl: require('leaflet/dist/images/marker-icon.png'),shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});new Vue({router,render: h => h(App)
}).$mount('#app')

.env.development内容

## 配置 正式接口地址
VUE_APP_URL = "http://localhost:8082"
VUE_APP_IMAGES = "http://localhost:8083"

vue.config.js内容

const path = require("path");
const sourceMap = process.env.NODE_ENV === "development";module.exports = {// 基本路径publicPath: "./",// 输出文件目录outputDir: "dist",// eslint-loader 是否在保存的时候检查lintOnSave: false,// webpack配置// see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.mdchainWebpack: () => {},configureWebpack: config => {if (process.env.NODE_ENV === "production") {// 为生产环境修改配置...config.mode = "production";} else {// 为开发环境修改配置...config.mode = "development";}Object.assign(config, {// 开发生产共同配置resolve: {extensions: [".js", ".vue", ".json", ".ts", ".tsx"],alias: {vue$: "vue/dist/vue.js","@": path.resolve(__dirname, "./src")}}});},// 生产环境是否生成 sourceMap 文件productionSourceMap: sourceMap,// css相关配置css: {// 是否使用css分离插件 ExtractTextPluginextract: true,// 开启 CSS source maps?sourceMap: false,// css预设器配置项loaderOptions: {},// 启用 CSS modules for all css / pre-processor files.modules: false},parallel: require("os").cpus().length > 1,pwa: {},// webpack-dev-server 相关配置devServer: {open: process.platform === "darwin",overlay: {warnings: false,errors: true},host: "localhost",port: 3001, //8080,https: false,hotOnly: false,proxy: {// 设置代理"/api": {target: process.env.VUE_APP_URL,changeOrigin: true,ws: true,}},before: app => {}},
};

VueLeaflet.vue内容

<template><div class="vue-leaflet"><div class="map" ref="map"></div></div>
</template><script>import { fetch } from "../utils/http-service";import 'leaflet.chinesetmsproviders'export default {name: "VueLeaflet",data() {return {map: '',};},mounted(){this.initMap();this.getSpot();window.addEventListener('scroll', function () {document.querySelector('body').setAttribute('style', 'margin: 0;')})},methods: {initMap(){const baselayers = this.addMulMap();const map =L.map(this.$refs.map, {center: [28.22, 113.01],zoom: 5,layers: [baselayers.天地图],zoomControl: false});this.map = map;L.control.zoom({zoomInTitle: '放大',zoomOutTitle: '缩小'}).addTo(map);L.control.layers(baselayers, null).addTo(map);},getSpot(){const map = this.map;const imgUrl = this.$imgUrl;const that = this;let naturalArr = [], cultureArr = [], parkArr = [], buildArr = [],templeArr = [], ruinsArr = [], townsArr = [], cemeteryArr = [],formerArr = [], religionArr = [];const result = fetch("/spot/virusdata");result.then(function (data) {console.log(data);for(let i=0; i<data.length; i++){const t = data[i];if(t.type==='自然风光'){naturalArr.push(that.addToMarker(t, imgUrl));}else if(t.type==='文化古迹'){cultureArr.push(that.addToMarker(t, imgUrl));}else if(t.type==='公园'){parkArr.push(that.addToMarker(t, imgUrl));}else if(t.type==='古建筑'){buildArr.push(that.addToMarker(t, imgUrl));}else if(t.type==='寺庙'){templeArr.push(that.addToMarker(t, imgUrl));}else if(t.type==='遗址'){ruinsArr.push(that.addToMarker(t, imgUrl));}else if(t.type==='古镇'){townsArr.push(that.addToMarker(t, imgUrl));}else if(t.type==='陵墓陵园'){cemeteryArr.push(that.addToMarker(t, imgUrl));}else if(t.type==='故居'){formerArr.push(that.addToMarker(t, imgUrl));}else if(t.type==='宗教'){religionArr.push(that.addToMarker(t, imgUrl));}}const naturalViews = L.layerGroup(naturalArr);const cultureViews = L.layerGroup(cultureArr);const parkViews = L.layerGroup(parkArr);const buildViews = L.layerGroup(buildArr);const templeViews = L.layerGroup(templeArr);const ruinsViews = L.layerGroup(ruinsArr);const townsViews = L.layerGroup(townsArr);const cemeteryViews = L.layerGroup(cemeteryArr);const formerViews = L.layerGroup(formerArr);const religionViews = L.layerGroup(religionArr);const overlayMaps = {"自然风光": naturalViews,"文化古迹": cultureViews,"公园": parkViews,"古建筑": buildViews,"寺庙": templeViews,"遗址": ruinsViews,"古镇": townsViews,"陵墓陵园": cemeteryViews,"故居": formerViews,"宗教": religionViews};map.addLayer(naturalViews);   // 默认添加自然风光景区到地图L.control.layers(null, overlayMaps).addTo(map);})},addToMarker(t, imgUrl){const p = t.point.split(",");const lng = parseFloat(p[0]);const lat = parseFloat(p[1]);const l = L.marker([lat, lng]).bindPopup("<img alt="+t.name+" width='280' height='200' src="+imgUrl+"/"+t.data_id+".jpg"+"><h3>"+t.name+"</h3><span>"+t.level+" </span>" +"<span>"+t.product_star_level+"</span><br/><span>类型:"+t.type+"</span><br/><span>地址:"+t.address+"</span><br/><span>"+t.intro+"</span>");return l;},addMulMap(){/*** 智图地图内容*/const normalm1 = L.tileLayer.chinaProvider('Geoq.Normal.Map', {maxZoom: 18,minZoom: 5});const normalm3 = L.tileLayer.chinaProvider('Geoq.Normal.PurplishBlue', {maxZoom: 18,minZoom: 5});const normalm2 = L.tileLayer.chinaProvider('Geoq.Normal.Color', {maxZoom: 18,minZoom: 5});const normalm4 = L.tileLayer.chinaProvider('Geoq.Normal.Gray', {maxZoom: 18,minZoom: 5});const normalm5 = L.tileLayer.chinaProvider('Geoq.Normal.Warm', {maxZoom: 18,minZoom: 5});const normalm6 = L.tileLayer.chinaProvider('Geoq.Normal.Cold', {maxZoom: 18,minZoom: 5});/*** 天地图内容*/const normalm = L.tileLayer.chinaProvider('TianDiTu.Normal.Map', {maxZoom: 18,minZoom: 5}),normala = L.tileLayer.chinaProvider('TianDiTu.Normal.Annotion', {maxZoom: 18,minZoom: 5}),imgm = L.tileLayer.chinaProvider('TianDiTu.Satellite.Map', {maxZoom: 18,minZoom: 5}),imga = L.tileLayer.chinaProvider('TianDiTu.Satellite.Annotion', {maxZoom: 18,minZoom: 5});const normal = L.layerGroup([normalm, normala]),image = L.layerGroup([imgm, imga]);/*** 谷歌*/const normalMap = L.tileLayer.chinaProvider('Google.Normal.Map', {maxZoom: 18,minZoom: 5}),satelliteMap = L.tileLayer.chinaProvider('Google.Satellite.Map', {maxZoom: 18,minZoom: 5});/*** 高德地图*/const Gaode = L.tileLayer.chinaProvider('GaoDe.Normal.Map', {maxZoom: 18,minZoom: 5});const Gaodimgem = L.tileLayer.chinaProvider('GaoDe.Satellite.Map', {maxZoom: 18,minZoom: 5});const Gaodimga = L.tileLayer.chinaProvider('GaoDe.Satellite.Annotion', {maxZoom: 18,minZoom: 5});const Gaodimage = L.layerGroup([Gaodimgem, Gaodimga]);const baseLayers = {"智图地图": normalm1,"智图多彩": normalm2,"智图午夜蓝": normalm3,"智图灰色": normalm4,"智图暖色": normalm5,"智图冷色": normalm6,"天地图": normal,"天地图影像": image,"谷歌地图": normalMap,"谷歌影像": satelliteMap,"高德地图": Gaode,"高德影像": Gaodimage,};return baseLayers;}},//创建前设置beforeCreate () {document.querySelector('body').setAttribute('style', 'margin: 0;')},//销毁前清除beforeDestroy () {document.querySelector('body').removeAttribute('style')},};
</script><style scoped>.vue-leaflet {width: 100vw;height: 100vh;font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 0;}.map{width: 100vw;height: 100vh;}
</style>

index.js内容

import Vue from 'vue'
import VueRouter from 'vue-router'
//自定义页面
import VueLeaflet from "../views/VueLeaflet";Vue.use(VueRouter)const routes = [{path: '/',redirect: '/vueLeaflet'   // 重定向},{path: '/vueLeaflet',name: 'vueLeaflet',component: VueLeaflet},{path: '/about',name: 'About',component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')}
]const router = new VueRouter({mode: 'hash',base: process.env.BASE_URL,routes
})export default router

http-service.js内容

import axios from 'axios'axios.defaults.timeout = 5000;  //请求超时设置
axios.defaults.baseURL = process.env.VUE_APP_URL//http request 拦截器
axios.interceptors.request.use(config => {config.data = JSON.stringify(config.data);config.headers = {'Content-Type':'application/x-www-form-urlencoded'}return config;},error => {return Promise.reject(err);}
);//响应拦截器即异常处理
axios.interceptors.response.use(response => {return response
}, err => {if (err && err.response) {switch (err.response.status) {case 400:console.log('错误请求')break;case 401:console.log('未授权,请重新登录')break;case 403:console.log('拒绝访问')break;case 404:console.log('请求错误,未找到该资源')break;case 405:console.log('请求方法未允许')break;case 408:console.log('请求超时')break;case 500:console.log('服务器端出错')break;case 501:console.log('网络未实现')break;case 502:console.log('网络错误')break;case 503:console.log('服务不可用')break;case 504:console.log('网络超时')break;case 505:console.log('http版本不支持该请求')break;default:console.log(`连接错误${err.response.status}`)}} else {console.log('连接到服务器失败')}return Promise.resolve(err.response)
})/*** 封装get方法* @param url* @param data* @returns {Promise}*/
export function fetch(url,params={}){return new Promise((resolve,reject) => {axios.get(url,{params:params}).then(response => {resolve(response.data);}).catch(err => {reject(err)})})
}/*** 封装post请求* @param url* @param data* @returns {Promise}*/
export function post(url,data = {}){return new Promise((resolve,reject) => {axios.post(url,data).then(response => {resolve(response.data);},err => {reject(err)})})
}

最终效果

前后端分离的webgis项目(二)相关推荐

  1. springboot jwt token前后端分离_基于Spring Boot+Spring Security+JWT+Vue前后端分离的开源项目...

    一.前言 最近整合Spring Boot+Spring Security+JWT+Vue 完成了一套前后端分离的基础项目,这里把它开源出来分享给有需要的小伙伴们 功能很简单,单点登录,前后端动态权限配 ...

  2. SpringBoot+vue前后端分离博客项目

    SpringBoot+vue前后端分离博客项目 Java后端接口开发 1.前言 2.新建Springboot项目 3.整合mybatis plus 第一步:导入jar包 第二步:然后去写配置文件: 第 ...

  3. 一款小清新的 SpringBoot+ Mybatis 前后端分离后台管理系统项目

    今日推荐 推荐3个快速开发平台 前后端都有 项目经验又有着落了推荐一个高仿微信的项目 有点屌!!一二线城市知名 IT 互联网公司名单(新版) 项目介绍 前后端分离架构,分离开发,分离部署,前后端互不影 ...

  4. 使用SpringBoot + Vue (若依前后端分离版) 写项目的一些总结(持续更新...)

    使用SpringBoot + Vue(若依前后端分离版) 写项目的一些总结 获取Redis服务 @Autowired private RedisCache redisCache; String cap ...

  5. easyui框架前后端交互_Vue+ElementUI+.netcore前后端分离框架开发项目实战

    点击上方"前端教程",选择"星标" 每天前端开发干货第一时间送达! 转自:我心依旧.cnblogs.com/-clouds/p/11633786.html 框架 ...

  6. 基于SpringBoot+Vue开发的前后端分离博客项目-Java后端接口开发

    文章目录 1. 前言 2. 新建Springboot项目 3. 整合mybatis plus 第一步:导依赖 第二步:写配置文件 第三步:mapper扫描+分页插件 第四步:代码生成配置 第五步:执行 ...

  7. Vue+ElementUI+.netcore前后端分离框架开发项目实战

    点击上方 "程序员小乐"关注公众号, 星标或置顶一起成长 每天凌晨00点00分, 第一时间与你相约 每日英文 Smile and stop complaining about th ...

  8. 超详细!4小时开发一个SpringBoot+vue前后端分离博客项目!!

    小Hub领读: 前后端分离的博客项目终于出来啦,真是花了好多心思录制咧.文末直接进入B站看视频哈! 作者:吕一明 项目代码:https://github.com/MarkerHub/vueblog 项 ...

  9. Vue+Spring Boot 前后端分离的商城项目开源啦!

    1 新蜂商城 Vue 移动端版本开源啦! 去年开源新蜂商城项目后,就一直在计划这个项目 Vue 版本的改造,2020 年开始开发并且自己私下一直在测试,之前也有文章介绍过测试过程和存在的问题,修改完成 ...

最新文章

  1. 机器学习简单代码示例
  2. linux log4j 空文件,log4j在linux上不生成日誌文件
  3. tp5 批量更新多条记录_tp5批量导入数据库
  4. 分布式存储系统设计(2)—— 数据分片
  5. NBA Top Shot过去24小时二级市场交易额突破630万美元
  6. android 后台代码设置动画
  7. win11笔记本没有网络图标问题的解决历程
  8. 关于灰鸽子和黑软的一些看法
  9. 为防泄密 新加坡政府将断掉公务员的网络连接
  10. 利用快速傅里叶计算多项式相乘
  11. 如何应对微软的强制黑屏(转)
  12. ibm tivoli_集成Tivoli Federated Identity Manager和Tivoli Identity Manager
  13. R语言基础学习记录4:重要函数
  14. 06-----the inferior stopped because it triggered an exception
  15. 【ppt入门教程】PowerPoint课件发布全攻略
  16. numpy中np.nan(pandas中NAN)
  17. vue2.0+ axios如何读取本地json文件的数据
  18. centos7FastDFS分布式安装部署
  19. 微信小程序低功耗蓝牙
  20. 【LOJ】#2568. 「APIO2016」烟花表演

热门文章

  1. deferred对象详解
  2. 3天封闭式K8s训练营 | 上海培训
  3. 关于亚马逊5665上架报错?具体解决方案奉上!
  4. js如何实现关闭当前页面
  5. 换小米mix2s信号座(射频座)
  6. ABAP 获取当前服务器域名和端口
  7. 2018春季中美创投峰会即将举办
  8. Word 2003 视频教程-关闭 Word(转)
  9. gdt描述_全局描述符表(GDT)局部描述符表(LDT)
  10. 审核通过≠报名成功,每年都有朋友因这个细节,报名失败