目录
本章所需工具:高德地图开发者账号,高德地图应用key,安全密钥
1.封装面包屑导航
知识点:meta{}
meta简单来说就是路由元信息 也就是每个路由身上携带的信息
需求如下:需要在HomeView.vue组件中,根据当前请求路径,显示相应的面包屑导航。
{
path: 'actor-list',
name: 'xxxxx',
component: ()=>import ('../views/actor/ActorList.vue'),
meta: { // 用于在此处绑定一些自定义数据
title: '演员列表',
breadcrumbs: ['演员管理', '演员列表']
}
}
如上,可以在router/index.js中为路由对象配置一个meta,将一些与路由绑定在一起的数据写在meta中,这些数据可以通过代码直接访问,进而动态显示页面内容。如果想要访问这些数据,则:
this.$route.meta.title
this.$route.meta.breadcrumbs
在HomeView.vue中添加面包屑导航,对breadcrumbs进行遍历,可以动态的显示breadcrumbs里的数组信息,同时可以删掉原来冗余的代码,使代码更加灵活
<!-- 面包屑导航 -->
<el-breadcrumb
style="flex: 1; margin-left: 20px;"
separator-class="el-icon-arrow-right">
<el-breadcrumb-item
v-for="item in $route.meta.breadcrumbs"
:key="item">
{{item}}
</el-breadcrumb-item>
</el-breadcrumb>
router/index.js 更改原来的路由信息
}, {
path: 'actor-list',
component: () => import('../views/actor/ActorList.vue'),
meta: {
breadcrumbs: ['演员管理', '演员列表']
}
}, {
path: 'actor-add',
component: () => import('../views/actor/ActorAdd.vue'),
meta: {
breadcrumbs: ['演员管理', '新增演员']
}
},{
path: 'director-list',
component: () => import('../views/director/DirectorList.vue'),
meta: {
breadcrumbs: ['导演管理', '导演列表']
}
}, {
path: 'director-add',
component: () => import('../views/director/DirectorAdd.vue'),
meta: {
breadcrumbs: ['导演管理', '新增导演']
}
}, {
path: 'movie-add',
component: () => import('../views/movie/MovieAdd.vue'),
meta: {
breadcrumbs: ['电影管理', '新增电影']
}
}, {
path: 'movie-list/:page',
name:'/home/movie-list/page',
component: () => import('../views/movie/MovieList.vue'),
meta: {
// 记录当前路由对应的面包屑导航列表
breadcrumbs: ['电影管理', '电影列表']
}
},{
path: 'movie-update/:id',
name: '/home/movie-update',
component: () => import('../views/movie/MovieUpdate.vue'),
meta: {
breadcrumbs: ['电影管理', '电影列表', '修改电影信息']
}
},{
path: 'movie-list/',
redirect: 'movie-list/1'
}, {
path: 'movie-add',
name:'/home/movie-add',
component: () => import('../views/movie/MovieAdd.vue')
},{
path: 'cinema-add',
name: '/home/cinema-add',
component: () => import('../views/cinema/CinemaAdd.vue'),
meta: {
breadcrumbs: ['电影院管理', '新增电影院']
}
},{
path: 'cinema-list',
name: '/home/cinema-list',
component: () => import('../views/cinema/CinemaList.vue'),
meta: {
breadcrumbs: ['电影院管理', '电影院列表']
}
}
实现效果:
2.实现添加电影院功能模块
需求分析: 以地图的方式,获取选中点的详细信息,回填表单,简化填写表单的操作。点击提交按钮,添加电影院。
实现步骤:
(1)准备一个新增电影院页面:views/cinema/CinemaAdd.vue。配置嵌套路由。
访问http://localhost:8080/home/cinema-add时, 看到它。
(2)在CinemaAdd.vue中提供一个表单,先显示出基本表单结构,然后完成双向数据绑定、表单验证、点击提交等功能。(其中需要使用高德地图),在form中准备好需要的数据,并与表单做好绑定
<template>
<div>
新增电影院页面
<!-- 表单 -->
<el-form label-width="100px" :model="form" style="width:700px;">
<el-form-item label="电影院名称">
<el-input v-model="form.cinema_name"></el-input>
</el-form-item>
<el-form-item label="选择位置">
<div
id="mapContainer"
style="height:200px; border:1px solid #666;">
</div>
</el-form-item>
<el-form-item label="详细地址">
<el-input v-model="form.address"></el-input>
</el-form-item>
<el-form-item label="省份">
<el-input v-model="form.province"></el-input>
</el-form-item>
<el-form-item label="城市">
<el-input v-model="form.city"></el-input>
</el-form-item>
<el-form-item label="地区">
<el-input v-model="form.district"></el-input>
</el-form-item>
<el-form-item label="经度">
<el-input v-model="form.longitude"></el-input>
</el-form-item>
<el-form-item label="纬度">
<el-input v-model="form.latidtude"></el-input>
</el-form-item>
<el-form-item label="选择标签">
<el-select v-model="form.tags" style="width:100%;" placeholder="请选择">
<el-option label="小吃"></el-option>
<el-option label="退"></el-option>
<el-option label="3D"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary">确定新增电影院</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {};
export default {
data() {
return {
form: {
cinema_name: '',
address: '',
province: '',
city: '',
district: '',
longitude: '',
latidtude: '',
tags: [],
}
}
},
};
</script>
<style lang="scss" scoped>
实现效果:
3.在VueCLI项目中使用高德地图
首先需要准备好高德地图开放平台账号,创建并申请秘钥。
登录开放平台:https://lbs.amap.com
按照如下官方文档的步骤,显示地图即可。此处省略图文,只写大体步骤
https://lbs.amap.com/api/javascript-api-v2/guide/abc/amap-vue
步骤一:
在地图组件 MapContainer.vue 中引入 amap-jsapi-loader
import AMapLoader from '@amap/amap-jsapi-loader';
步骤二:
地图初始化函数 initMap()
methods:{
initMap(){
AMapLoader.load({
key:"", // 申请好的Web端开发者Key,首次调用 load 时必填
version:"2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins:[''], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then((AMap)=>{
this.map = new AMap.Map("container",{ //设置地图容器id
viewMode:"3D", //是否为3D地图模式
zoom:5, //初始化地图级别
center:[105.602725,37.076636], //初始化地图中心点位置
});
}).catch(e=>{
console.log(e);
})
},
},
步骤三:
调用地图初始化函数:mounted 函数会在 DOM 初始化完成后调用,建议在 mounted 函数中调用地图初始化方法。
mounted(){
//DOM初始化完成进行地图初始化
this.initMap();
}
实现效果:
4.基于高德地图的逆地理编码完成地图选点,表单回填
知识点:
地理编码包含正向地理编码和逆向地理编码两种:
-
正向地理编码: 将地址 描述信息 转换成 地理坐标(经纬度),对应为AMap.Geocoder的getLocation方法
-
逆向地理编码:将 地理坐标(经纬度) 转换成 地址描述信息,对应为AMap.Geocoder的getAddress方法
实现思路:
- 想办法获取到用户在地图上点击后,所选中的点的经纬度坐标。
- 获取到经纬度坐标后,访问高德地图的逆地理编码服务,获取详细位置信息。
- 将位置信息回填表单即可。
提前需要申请好key和安全密钥
1. 实现点击高德地图,获取经纬度。
methods:{
// 初始化地图
initMap(){
AMapLoader.load({
key:"7bfbe3ab215345f405c23b5eed760ca8", // 申请好的Web端开发者Key,首次调用 load 时必填
version:"2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins:['AMap.Geocoder'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then((AMap)=>{
this.map = new AMap.Map("mapContainer",{ //设置地图容器id
viewMode:"3D", //是否为3D地图模式
zoom:11, //初始化地图级别
center:[116.397505,39.907648], //初始化地图中心点位置
});
// 为map绑定点击事件,获取经纬度
this.map.on('click', (e)=>{
let lng = e.lnglat.KL // 经度
let lat = e.lnglat.kT // 纬度
console.log({lng, lat})
// 通过经纬度,访问高德地图服务,执行逆地理编码,获取位置信息
})
}).catch(e=>{
console.log(e);
})
},
},
mounted(){
this.initMap()
}
};
获取到经纬度坐标后,访问高德地图的逆地理编码服务,获取详细位置信息
// 通过经纬度,访问高德地图服务,执行逆地理编码,获取位置信息
let geocoder = new AMap.Geocoder()
geocoder.getAddress([lng, lat], (status, result)=>{
console.log(status, result)
// 回填表单
this.form.address = result.regeocode.formattedAddress
let addr = result.regeocode.addressComponent
this.form.province = addr.province
this.form.city = addr.city? addr.city:addr.province
this.form.district = addr.district
this.form.latitude = lat
this.form.longitude = lng
})
5.实现选择标签下拉框中数据的加载
- 当组件挂载完毕后,可以发送请求,加载所有的影院标签。保存到data。
- 在el-select中遍历输出el-option,显示所有的影院标签列表项。
</el-form-item>
<el-form-item label="选择标签">
<el-select v-model="form.tags" style="width:100%;" placeholder="请选择">
<el-option
v-for="item in tags" :key="item.id"
:label="item.tagname"
:value="item.tagname">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
@@ -46,10 +48,13 @@
<script>
import AMapLoader from '@amap/amap-jsapi-loader';
import httpApi from '@/http';
export default {
data() {
return {
tags: [], // 保存所有的标签
form: {
cinema_name: '',
address: '',
@@ -94,7 +99,6 @@ export default {
this.form.district = addr.district
this.form.latitude = lat
this.form.longitude = lng
})
})
}).catch(e=>{
@@ -105,6 +109,11 @@ export default {
mounted(){
this.initMap()
// 加载所有的影院标签
httpApi.cinemaApi.queryAllTags().then(res=>{
console.log(res)
this.tags = res.data.data
})
}
};
index.js 加上cinmaApi
import actorApi from "./apis/ActorApi";
import directorApi from "./apis/DirectorApi";
import movieApi from "./apis/MovieApi";
import cinemaApi from "./apis/CinemaApi";
const httpApi = { // 封装http接口
actorApi,
directorApi,
movieApi
movieApi,
cinemaApi
}
export default httpApi;
cinemaApi.js 封装接口
import myaxios from "../MyAxios";
import baseurl from '../BaseUrl';
const BMDURL = baseurl.BMDURL;
const cinemaApi = { // 封装http接口
/** 查询所有影院标签 */
queryAllTags(){
let url = BMDURL + '/cinema/tags'
return myaxios.get(url)
}
}
export default cinemaApi;
实现效果:
6.实现新增电影院业务
- 提供新增影院的API接口。
- 当点击提交按钮时,做好表单验证。收集用户填写的数据。执行新增业务。
- 添加成功后跳转到列表页面。
提供新增影院的API接口。 cinemaApi.js 封装接口
const cinemaApi = { // 封装http接口
/** 新增影院 */
add(params){
let url = BMDURL + '/cinema/add'
return myaxios.post(url, params)
},
当点击提交按钮时,做好表单验证。收集用户填写的数据。执行新增业务 cinemaAdd.vue
<!-- 表单 -->
<el-form label-width="100px" ref="form" :model="form" :rules="rules" style="width:700px;">
<el-form-item label="电影院名称" prop="cinema_name">
<el-input v-model="form.cinema_name"></el-input>
</el-form-item>
<el-form-item label="选择位置">
<div
id="mapContainer"
style="height:200px; border:1px solid #666;">
</div>
</el-form-item>
<el-form-item label="详细地址" prop="address">
<el-input v-model="form.address"></el-input>
</el-form-item>
<el-form-item label="省份" prop="province">
<el-input v-model="form.province"></el-input>
</el-form-item>
<el-form-item label="城市" prop="city">
<el-input v-model="form.city"></el-input>
</el-form-item>
<el-form-item label="地区" prop="district">
<el-input v-model="form.district"></el-input>
</el-form-item>
<el-form-item label="经度" prop="longitude">
<el-input v-model="form.longitude"></el-input>
</el-form-item>
<el-form-item label="纬度" prop="latitude">
<el-input v-model="form.latitude"></el-input>
</el-form-item>
<el-form-item label="选择标签" prop="tags">
<el-select v-model="form.tags" style="width:100%;" placeholder="请选择" multiple>
<el-option
v-for="item in tags" :key="item.id"
:label="item.tagname"
:value="item.tagname">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">确定新增电影院</el-button>
</el-form-item>
</el-form>
rules: {
cinema_name: [
{required:true, message:'必填', trigger:'blur'}
],
address: [
{required:true, message:'必填', trigger:'blur'}
],
province: [
{required:true, message:'必填', trigger:'blur'}
],
city: [
{required:true, message:'必填', trigger:'blur'}
],
district: [
{required:true, message:'必填', trigger:'blur'}
],
longitude: [
{required:true, message:'必填', trigger:'blur'}
],
latitude: [
{required:true, message:'必填', trigger:'blur'}
],
tags: [
{required:true, message:'必填', trigger:'change'}
],
methods:{
// 执行提交表单
submit(){
this.$refs['form'].validate(valid=>{
if(valid){ // 所有字段验证通过
// 整理字段
this.form.tags = this.form.tags.join(',')
console.log(this.form)
// 发送新增影院请求,执行业务
httpApi.cinemaApi.add(this.form).then(res=>{
if(res.data.code==200){ // 新增成功
this.$message({
message: '恭喜,影院新增成功',
type: "success"
})
this.$router.push('/home/cinema-list')
}
})
}
})
},
添加成功后跳转到列表页面。
实现效果:
7.实现电影院列表页
**业务需求:**点击左侧边栏菜单、新增影院成功后需要跳转到影院列表,在列表页中以地图的方式,显示所有影院的位置。以表格的方式呈现列表数据。
实现思路:
-
准备好一个页面:views/cinema/CinemaList.vue。 配置好嵌套路由。
http://localhost:8080/home/cinema-list
-
搭建页面的基本内容,加载影院列表数据,显示在表格中。
提供一个查询所有电影院数据的接口。
在mounted中调用方法 this.listCinemas() 发送请求 。
拿到结果,在el-table中显示 id="mapContainer" 。
-
在顶部显示地图,并且在地图中显示所有电影院的位置信息。
cinema.js
const cinemaApi = { // 封装http接口
/** 查询所有电影院 */
query(){
let url = BMDURL + "/cinemas"
return myaxios.get(url)
},
index.js
},{
path: 'cinema-list',
name: '/home/cinema-list',
component: () => import('../views/cinema/CinemaList.vue'),
meta: {
breadcrumbs: ['电影院管理', '电影院列表']
}
cinemaList.vue
<template>
<div>
<div
style="height:250px; border:1px solid #666;"
id="mapContainer">
</div>
<el-divider content-position="left">电影院列表</el-divider>
<!-- 表格 -->
<el-table :data="cinemas">
<el-table-column
label="影院名称"
prop="cinema_name"
width="280px">
</el-table-column>
<el-table-column label="影院地址" prop="address"></el-table-column>
<el-table-column label="影院位置" width="200px">
<template slot-scope="scope">
{{scope.row.province}}
{{scope.row.city}}
{{scope.row.district}}
</template>
</el-table-column>
<el-table-column label="操作" width="230px">
<el-button size="small" type="info" icon="el-icon-location-outline" circle></el-button>
<el-button size="small" type="primary" icon="el-icon-view" circle></el-button>
<el-button size="small" type="warning" icon="el-icon-edit" circle></el-button>
<el-button size="small" type="danger" icon="el-icon-delete" circle></el-button>
</el-table-column>
</el-table>
</div>
</template>
<script>
import httpApi from '@/http';
export default {
data() {
return {
cinemas: [], // 保存所有影院信息
}
},
methods: {
// 加载所有影院信息
listCinemas() {
httpApi.cinemaApi.query().then(res=>{
console.log(res)
this.cinemas = res.data.data
})
}
},
/** 生命周期 */
mounted(){
// 加载所有影院信息
this.listCinemas()
},
};
</script>
<style lang="scss" scoped>
</style>
实现效果: