前言
吾欲续前文之未竟,前一期之组件MapView.vue之文未明,盖因袭他人之文也。今明其义,再为是书增益一能,欲再增其用,此文乃令吾等为此项目增设菜单导航之功。
上一期组件MapView组件代码:
<template>
<div id="mapview"></div>
</template>
<script>
import { loadModules } from 'esri-loader';
const options = {
url: 'https://js.arcgis.com/4.18/init.js',
css: 'https://js.arcgis.com/4.18/esri/themes/light/main.css',
};
export default {
name: 'MapView',
components: {},
mounted: function () {
this._createMapView();
},
methods: {
async _createMapView() {
const [Map, MapView] = await loadModules(['esri/Map', 'esri/views/MapView'], options);
const map = new Map({
basemap: 'osm',
});
const view = new MapView({
container: 'mapview',
center: [108, 32],
map: map,
zoom: 5,
});
console.log(view);
},
},
};
</script>
<style>
#mapview {
position: relative;
width: 100%;
height: 100%;
}
</style>
这段代码是一个Vue组件,用于在网页上创建一个Esri地图视图
为了弄清arcgis api for js的相关作用,我特地去查了ArcGIS Maps SDK for JavaScript官网,其中提供了在web应用程序中创建交互式地图和地理信息系统(GIS)功能。这个SDK由Esri开发,它提供了一组JavaScript API,这些API可以让我们轻松地在网页上嵌入地图,并进行各种地图相关的操作。
进入官网 :
https://developers.arcgis.com/javascripthttps://developers.arcgis.com/javascript
Arcgis api for js 的基础使用
官网中代码:
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css">
<script src="https://js.arcgis.com/4.28/"></script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
“link”是指HTML中的
<link>
标签,它用于定义文档与外部资源之间的关系。<link>
标签通常用于链接外部样式表(CSS文件),但也可以用于链接其他资源,如字体文件。以下是
<link>
标签的基本用法:<link rel="stylesheet" href="styles.css">
在这个例子中,
rel
属性指定了资源类型(这里是样式表),而href
属性指定了资源的位置(这里是styles.css
文件)。浏览器会加载并应用这个外部样式表,以改变或增强页面的呈现效果。
“src”是HTML中的一个常用属性,它通常与
<script>
标签一起使用,用于指定外部脚本文件的路径。当浏览器遇到<script>
标签时,它会下载并执行指定的脚本文件。通过设置src
属性,您可以引入外部的JavaScript文件,从而实现更复杂的功能或使用第三方库。以下是
src
属性的基本用法:<script src="script.js"></script>
在这个例子中,浏览器会下载并执行名为
script.js
的外部JavaScript文件。请注意,如果将<script>
标签放在文档的头部(<head>
部分),浏览器可能会在加载其他内容之前先加载并执行脚本。为了优化性能和避免潜在的加载顺序问题,建议将<script>
标签放在文档的底部或使用异步加载技术。
上面的是一个原生HTML页面方法,而在我们的这个项目中:
import { loadModules } from 'esri-loader';
const options = {
url: 'https://js.arcgis.com/4.18/init.js',
css: 'https://js.arcgis.com/4.18/esri/themes/light/main.css',
};
上一期我们下载了 esri-loader 模块,这处代码我们导入了 一个名为 loadModules 的函数,随后定义了一个 options 的常量,加载 ArcGIS 模块的配置选项,对象中url属性指定了其外部JavaScript脚本文件的URL,css属性指定了其外部样式表的URL。
到这里我又去看了看const let var声明的区别,当时学vue的时候走马观花,ES6相关的语法就没怎么学习,想了解的可以看这篇文章:
mounted: function () {
this._createMapView();
},
这是Vue的生命周期函数,调用 _createMapView 方法
methods: {
async _createMapView() {
const [Map, MapView] = await loadModules(['esri/Map', 'esri/views/MapView'], options);
const map = new Map({
basemap: 'osm',
});
const view = new MapView({
container: 'mapview',
center: [108, 32],
map: map,
zoom: 5,
});
console.log(view);
},
}
这里用了一个异步操作,关于这个我也不怎么了解,详情请看这篇文章:
使用 loadModules方法异步加载 esri/Map 和 esri/views/MapView 模块。这个方法会返回一个包含已加载模块的对象;随后创建了一个 地图对象 map,这代表了地图本身,其基础图层为OpenStreetMap。当然除了osm,arcgis也提供了其他的一些基础底图
创建一个新的MapView
对象,这个对象代表了地图的视图,即用户在网页上看到的地图部分。
container:'mapview' | 指定视图应挂载的HTML元素,这里将其设置为id为'mapview'的元素。 |
center:[108,32] | 设置视图的初始中心点为经度108和纬度32。 |
map:map | 将之前创建的地图对象设置为视图的地图。 |
zoom:5 | 设置视图的初始缩放级别为5。 |
以上便是Arcgis api for js 的基础使用
添加菜单导航
现在来给我们的系统加一点功能,使用vue-router实现多页面,这里vue-router在创建vue时就已经安装了就不多赘述了。
再来到Element-UI官网,其提供了相当多的模板,当然也包括菜单导航:
其源码为:
<el-row class="tac">
<el-col :span="12">
<h5>默认颜色</h5>
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>导航一</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</el-col>
<el-col :span="12">
<h5>自定义颜色</h5>
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>导航一</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</el-col>
</el-row>
<script>
export default {
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
}
</script>
其中有几个标签不怎么了解,去问了chatgtp:
<el-row>
是 Element UI 中的栅格系统组件,用于创建栅格布局。class="tac"
是一个 CSS 类,用于给这个<el-row>
组件添加样式。具体来说,
<el-row class="tac">
这段代码的意思是创建一个 Element UI 的栅格行组件,并给它添加一个名为 "tac" 的 CSS 类。这通常用于定制栅格行的样式。
<el-col :span="12">
是 Element UI 中的栅格系统组件,用于在栅格布局中定义列。这里使用了 Vue.js 的语法,
:span="12"
表示这个列占据了 12 个栅格。在 Element UI 的栅格系统中,一行被分为 24 个栅格,所以span="12"
表示这个列占据了一半的行宽。例如,如果你想要创建一个两列的布局,你可以这样使用
<el-col>
组件:<el-row> <el-col :span="12">列 1</el-col> <el-col :span="12">列 2</el-col> </el-row>
这将创建一个栅格布局,其中两列各占据一半的行宽。
<el-submenu index="1">
是 Element UI 中的子菜单组件。在 Element UI 的菜单组件(
el-menu
)中,你可以嵌套使用子菜单组件(el-submenu
)来创建多级菜单。index
属性是用于标识这个子菜单的唯一标识符,通常用于与事件监听器关联,以便在用户与子菜单交互时触发相应的行为。下面是一个简单的示例,展示了如何使用
<el-submenu>
:<el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse"> <el-submenu index="1"> <template slot="title">导航一</template> <el-menu-item index="1-1">选项1</el-menu-item> <el-menu-item index="1-2">选项2</el-menu-item> </el-submenu> <!-- 其他菜单项 --> </el-menu>
在上面的示例中,我们创建了一个名为“导航一”的子菜单,其中包含两个菜单项:“选项1”和“选项2”。通过设置
index
属性,我们可以轻松地识别和操作这个子菜单。
<el-menu-item-group>
是 Element UI 中的组件,用于创建可以包含子项的菜单项组。这个组件通常用于在菜单中组织具有相关性的多个菜单项。使用
<el-menu-item-group>
时,你可以为其指定一个标题,以便将相关的菜单项组织在一起。标题可以通过title
属性来设置。在
<el-menu-item-group>
中,你可以包含<el-menu-item>
组件来表示菜单项。每个<el-menu-item>
可以包含文本、图标等元素,用于表示具体的菜单项。下面是一个简单的示例,展示了如何使用
<el-menu-item-group>
:<el-menu> <el-menu-item-group title="分类一"> <el-menu-item index="1">选项1</el-menu-item> <el-menu-item index="2">选项2</el-menu-item> </el-menu-item-group> <el-menu-item index="3">选项3</el-menu-item> </el-menu>
在上面的示例中,我们创建了一个菜单,其中包含一个名为“分类一”的菜单项组。这个组包含了两个菜单项:“选项1”和“选项2”。通过使用
<el-menu-item-group>
,我们可以将相关的菜单项组织在一起,并提供一个标题来描述这个组的目的或功能。
在 Vue.js 和 Element UI 的上下文中,
<template slot="title"></template>
是一个插槽 (slot) 的使用示例。插槽是 Vue.js 中的一种功能,允许你定义组件模板中的可替换部分。当你使用一个组件并希望在那个组件的模板中插入自定义内容时,你可以使用插槽。
在 Element UI 中,许多组件(如
el-menu
、el-collapse
等)都提供了预定义的插槽,以便你可以插入自定义内容。例如,el-menu
组件有一个title
插槽,你可以使用<template slot="title"></template>
来插入自定义的标题内容。下面是一个简单的例子,展示了如何使用
el-menu
的title
插槽:<template> <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse"> <template slot="title"> <i class="el-icon-location"></i> <span>导航一</span> </template> <el-submenu index="1"> <template slot="title">导航一</template> <el-menu-item index="1-1">选项1</el-menu-item> <el-menu-item index="1-2">选项2</el-menu-item> </el-submenu> <!-- 其他菜单项 --> </el-menu> </template>
在上面的例子中,我们使用了
el-menu
的title
插槽来插入一个自定义的标题内容,包括一个图标和文本“导航一”。
当然我们用不了这么多组件,经过整合修改将其放到我们的项目中:
App.vue:
<template>
<el-container>
<el-header>webgis系统</el-header>
<el-container>
<el-aside width="200px">
<p style="background-color: aliceblue; margin-top: 0;
margin-bottom: 0;">菜单栏</p>
<el-menu
default-active="1"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
background-color="#062344"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="1">
<i class="el-icon-location"></i>
<span slot="title">导航一</span>
</el-menu-item>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main>
<router-view></router-view>
<MapView/>
</el-main>
</el-container>
</el-container>
</template>
<script>
import MapView from "./components/MapView.vue"
export default {
name: 'App',
data(){
return{
isCollapse: true
}
},
components: {MapView},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
};
</script>
<style>
.el-container{
height:100vh
}
.el-header, .el-footer {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #062344;
color: #062344;
text-align: center;
line-height: 60px;
}
.el-main {
background-color: #f6f8fb;
color: #333;
text-align: center;
line-height: 160px;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
</style>
运行后页面如下所示
至此页面的导航功能完成。
使用Vue路由
1.新建文件
在根目录文件下的views文件夹新建两个视图文件
在DataVisual.vue中写入:
<template>
<div class="datavisual-page">首页大屏</div>
</template>
<script>
export default {
name: "DataVisual",
components: {},
};
</script>
<style>
.datavisual-page {
height: 100%;
width: 100%;
background-color: bisque;
}
</style>
在OneMap.vue中写入:
<template>
<div class="onemap-page">WebGIS一张图</div>
</template>
<script>
export default {
name: 'OneMap',
components: {},
};
</script>
<style>
.onemap-page {
height: 100%;
width: 100%;
background-color: cadetblue;
}
</style>
2.配置路由
在下图的文件中配置路由:
import Vue from 'vue'
import VueRouter from 'vue-router'
import DataVisual from '../views/DataVisual.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: DataVisual
},
{
path: '/onemap',
name: 'onemap',
component: () => import('../views/OneMap.vue')
}
]
const router = new VueRouter({
routes
})
export default router
3.实现路由跳转
在App.vue中设置按钮点击后的路由跳转:
为el-menu定义了一个@select="handleMenuSelect"事件,根据index值,来判断要跳转到哪个地址。
<el-menu
default-active="1"
class="el-menu-vertical-demo"
@select="handleMenuSelect"
@open="handleOpen"
@close="handleClose"
background-color="#062344"
text-color="#fff"
active-text-color="#ffd04b">
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
},
handleMenuSelect(index) {
console.log(index);
if (index === '1') {
this.$router.push('/');
} else if (index === '2') {
this.$router.push('/onemap');
}
}
}
运行展示:
一开始运行后我发现有误,因为我切换路由一直是同一个界面,后来才发现缺少<router-view></router-view>
组件
<router-view></router-view>
是 Vue.js 的一个组件,用于渲染当前路由对应的组件视图。它是 Vue Router 的一个核心组件,用于实现单页面应用(SPA)中的页面路由。在 Vue Router 的使用中,当你定义了多个路由,并且每个路由都关联了一个组件时,
<router-view>
就起到了作用。当用户访问不同的 URL 时,<router-view>
会根据当前的路由自动渲染对应的组件。
当然路由跳转方式不止上面的通过事件跳转,还可以通过<router-link>方式跳转:
一开始是这么写的:
运行后出错:
随后改了一下,写为如下代码:
<router-link to="/" tag="el-menu-item">
<el-menu-item index="1">
<i class="el-icon-location"></i>
<span slot="title">导航一</span>
</el-menu-item>
</router-link>
<router-link to="/onemap" tag="el-menu-item">
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
</router-link>
这样就实现了和事件跳转一样的效果。
4.引入MapView.vue组件
在OneMap中引入MapView.vue组件
在一个组件中使用另外的组件,采用三步走战略:
//1 引入别的组件
import MapView from './../src/components/common/MapView.vue';
//2 在components中注册组件
components: {
MapView,
},
//3 在div中实例化组件
<div class="onemap-page">
<MapView />
</div>
编写OneMap.vue
<template>
<div class="onemap-page">
<MapView />
</div>
</template>
<script>
import MapView from "../components/MapView.vue";
export default {
name: "OneMap",
components: { MapView },
};
</script>
<style>
.onemap-page {
height: 100%;
width: 100%;
background-color: cadetblue;
}
</style>
这样就为本项目添加更多功能啦!
格式稍乱,辞不达意,内容繁冗,敬请谅解。