前言:
高德地图输入提示与 POI 搜索相关文档:输入提示与 POI 搜索-服务插件和工具-进阶教程-地图 JS API 2.0 | 高德地图API (amap.com)
输入提示-输入提示-示例中心-JS API 2.0 示例 | 高德地图API (amap.com)
创建输入框:
引入Element组件库:
关于引入element可以看我的这篇文章:Vue框架中引入Element-UI组件库-CSDN博客
引入输入框组件
components文件夹下创建Search.vue:
<template>
<div id="search">
<el-input placeholder="请输入内容" v-model="input" clearable> </el-input>
</div>
</template>
<script>
export default {
data() {
return {
input: "",
};
},
};
</script>
<style>
#search {
position: relative;
margin-left: auto;
margin-right: auto;
top:30px;
width: 600px;
}
</style>
在MapContainer.vue的plugins中引入’AMap.PlaceSearch’控件
官网上有相关的教程:输入提示与 POI 搜索-服务插件和工具-进阶教程-地图 JS API 2.0 | 高德地图API (amap.com)
AMap.AutoComplete输入提示插件,可以实现在输入框里输入文本片段即显示相关的匹配信息。
输入提示插件支持设置搜索限制条件,比如:传入要搜索的 POI 类型(type)和城市(city)等参数,搜索完成后用户可获取到对应的查询结果。
利用输入提示插件获取匹配信息需要以下代码实现:
//异步加载 AutoComplete 插件 AMap.plugin("AMap.AutoComplete", function () { var autoOptions = { //city 限定城市,默认全国 city: "全国", }; //实例化AutoComplete var autoComplete = new AMap.AutoComplete(autoOptions); //根据关键字进行搜索 keyword 为搜索的关键词 autoComplete.search(keyword, function (status, result) { //搜索成功时,result 即是对应的匹配数据 console.log(result); }); });
通常情况下,开发者需要根据表单控件事件的触发来执行AMap.AutoComplete的search()方法,并将返回结果绘制成 DOM 显示到页面上。为了帮助开发者节省时间、提升效率,高德 JS API 还提供了一套默认的 UI 来自动在页面相应的表单控件上监听输入并显示匹配结果。如果你需要使用此功能,请按照下面代码示例编写即可:
AMap.plugin("AMap.AutoComplete", function () { var autoOptions = { input: "input_id", //"input_id"替换为输入框实际 id }; var autoComplete = new AMap.AutoComplete(autoOptions); //无需再手动执行 search 方法,autoComplete 会根据传 input 对应的 DOM 动态触发 search });
由官网的相关教程可知,修改MapView.vue代码为 :
将autoOption与Search.vue中的input绑定
关于组件之间的传递请看我的这篇文章:Vue组件之间的传递通信-CSDN博客
我们使用事件总线进行传递:
新建eventbus文件夹,在文件夹下新建event-bus.js文件
写入:
import Vue from 'vue';
export const EventBus = new Vue();
引入:
MapView.vue中
Search.vue中
将Search.vue表单进行双向绑定以及动态id还有input监听
这里的id也可以不设置为动态,直接将id写给autoOptions,这个我们后面再说
在methods中定义方法 send
。这个方法会在输入框的值发生变化时被调用(由 @input
事件触发)
在 send
方法中,使用了一个名为 EventBus
的事件总线(从 ../eventbus/event-bus
导入)来发出一个名为 "shareUserInput"
的事件,并传递 inputId
作为参数。
注意mounted生命周期钩子一定要有,要不然只会传值 ,不能挂载到 DOM
(我是这么理解的,一开始没写 mounted,运行一直不对)
Search.vue全部代码:
<template>
<div id="search">
<el-input
type="text"
placeholder="请输入内容"
v-model="userInput"
:id="inputId"
clearable
@input="send"
></el-input>
</div>
</template>
<script>
import { EventBus } from "../eventbus/event-bus";
export default {
data() {
return {
userInput: "",
inputId: "seachInput",
};
},
methods: {
send() {
EventBus.$emit("shareUserInput", this.inputId);
},
},
mounted() {
this.send();//初始化,让其他组件知道这个搜索输入框组件已经被加载并准备好接受用户输入了。
},
}
</script>
<style>
#search {
position: relative;
margin-left: auto;
margin-right: auto;
top: 30px;
width:600px;
}
</style>
在MapView.vue中
当组件被创建时,created()
钩子被调用。在 created()
钩子中,设置了一个事件监听器来监听 "shareUserInput"
事件,接收到传递的数据,handleEvent
方法新 this.autoOptions.input
的值。
最后创建一个实例就成功了
this.auto = new AMap.AutoComplete(this.autoOptions);
MapView.vue全部代码:
<template>
<div id="container"></div>
</template>
<script>
import { EventBus } from "../eventbus/event-bus";
import AMapLoader from "@amap/amap-jsapi-loader";
window._AMapSecurityConfig = {
securityJsCode: "安全密钥",
};
export default {
data() {
return {
map: null,
autoOptions: {
input: ""
},
auto: null,
}
},
created() {
EventBus.$on("shareUserInput", (data) => this.handleEvent(data));
},
methods: {
handleEvent(data) {
this.autoOptions.input = data;
console.log(this.autoOptions.input)
},
initMap() {
AMapLoader.load({
key: "", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [
"AMap.ToolBar",
"AMap.Scale",
"AMap.ControlBar",
"AMap.HawkEye",
"AMap.MapType",
"AMap.AutoComplete",
],
})
.then((AMap) => {
this.map = new AMap.Map("container", {
//设置地图容器id
resizeEnable: true,
viewMode: "3D", //是否为3D地图模式
zoom: 10, //初始化地图级别
center: [121.473667, 31.230525], //初始化地图中心点位置
});
this.auto = new AMap.AutoComplete(this.autoOptions);
// 添加比例尺控件
this.map.addControl(new AMap.Scale());
// 添加工具栏控件
this.map.addControl(new AMap.ToolBar());
// 添加地图类型切换控件
this.map.addControl(new AMap.MapType());
this.map.addControl(new AMap.HawkEye());
this.map.addControl(new AMap.ControlBar());
// 其他地图初始化代码...
})
.catch((e) => {
console.log(e);
});
},
},
mounted() {
//DOM初始化完成进行地图初始化
this.initMap();
},
};
</script>
<style scoped>
#container {
padding: 0px;
margin: 0px;
width: 100%;
height: 100%;
position: absolute;
}
</style>
补充一个小tip
mounted()
生命周期钩子不是一定需要的,它取决于你的应用逻辑和组件的需求。mounted()
钩子函数主要用于执行那些需要在 DOM 渲染完成后才能进行的操作,比如发起网络请求、订阅事件、操作 DOM 元素等。如果您发现没有
mounted()
钩子函数,组件的运行不一样,这可能是因为您的应用逻辑依赖于某些在mounted()
中执行的初始化操作。例如,如果您在mounted()
中发起了一个网络请求来获取数据,并在获取到数据后更新组件的状态,那么没有mounted()
钩子函数,这个数据获取和状态更新的操作就不会发生,从而影响到组件的渲染和行为。另外,如果您在
send()
方法中发送的是一个事件,用于通知其他组件或实例进行某些操作(比如更新状态、渲染内容等),那么没有mounted()
钩子函数,这个事件就不会在组件挂载时发送,可能会影响到其他组件或实例的行为。因此,是否需要使用
mounted()
钩子函数,取决于您的应用逻辑和组件的需求。如果您的组件需要在挂载后执行某些操作,那么就需要使用mounted()
钩子函数。如果不需要,则可以省略它。但是,如果您的应用逻辑依赖于mounted()
中执行的某些操作,而您又没有实现这个钩子函数,那么组件的行为就可能会与预期不符。
当然当然,还有极其简单的方法,直接将输入框 的id写入autoOptions中,都不需要那些杂七杂八的什么事件总线啥的(我也是后来才发现,本来以为不同组件之前的id是需要传递的)