123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- <template>
- <el-dialog
- title="选择位置"
- :visible.sync="open"
- :close-on-click-modal="false"
- width="700px"
- append-to-body
- @close="cancel"
- >
- <!-- 输入框 -->
- <el-autocomplete
- class="mb10"
- style="width: 100%"
- v-model="address"
- value-key="name"
- popper-class="my-autocomplete"
- placeholder="请输入内容"
- :fetch-suggestions="querySearchAsync"
- clearable
- @select="handleSelect"
- >
- <i class="el-icon-search el-input__icon" slot="suffix"></i>
- <template slot-scope="{ item }">
- <div class="name">{{ item.name }}</div>
- <span class="addr">{{ item.district }}</span>
- </template>
- </el-autocomplete>
- <!-- 地图容器 -->
- <div ref="container" class="container"></div>
- <div class="footer" slot="footer">
- <el-button type="primary" @click="submitForm">确 定</el-button>
- </div>
- </el-dialog>
- </template>
- <script>
- let map = null,
- marker = null
- export default {
- name: 'BaseAmapSelect',
- data() {
- return {
- open: false,
- latitude: null,
- longitude: null,
- address: null,
- defaultCenter: [116.41, 39.9]
- }
- },
- destroyed() {
- console.log('销毁')
- map && (map = undefined)
- },
- methods: {
- // 重置数据
- reset() {
- this.latitude = null
- this.longitude = null
- this.address = null
- },
- // 打开组件
- init(options) {
- this.reset()
- this.open = true
- // 初始化地图
- // 无需频繁初始化地图
- if (!map) {
- this.$nextTick(() => {
- this.creatAmap(options)
- })
- } else {
- // 移动视角
- if (options.cityId) {
- // 如果设置了cityId就移动至cityId
- this.getLocationByCityId(options.cityId).then(res => {
- map.setCenter(res)
- })
- } else if (options.center) {
- // 如果设置了经纬度就移动至经纬度地址
- map.setCenter(options.center)
- }
- }
- },
- // 加载地图
- async creatAmap(options) {
- let pOptions = options || {}
- // 初始化参数
- let creatOptions = {
- resizeEnable: true, //窗口大小调整
- center: this.defaultCenter,
- zoom: 15,
- ...pOptions
- }
- try {
- // 如果设置了cityId,将center改为cityId解析后的点位
- if (pOptions.cityId) {
- // console.log(pOptions.cityId);
- creatOptions.center = await this.getLocationByCityId(pOptions.cityId)
- }
- } catch (error) {
- console.log('初始化地图出错:', error)
- } finally {
- map = new AMap.Map(this.$refs.container, creatOptions)
- this.mapAddClick()
- }
- },
- // 给地图添加点击事件
- mapAddClick() {
- if (AMap && map) {
- let geoCoder = new AMap.Geocoder()
- map.on('click', e => {
- if (marker) {
- map.remove(marker)
- }
- // 添加标记点
- marker = new AMap.Marker({
- position: e.lnglat,
- map: map
- })
- geoCoder.getAddress(e.lnglat, (status, res) => {
- if (status === 'complete' && res.info === 'OK') {
- this.address = res.regeocode.formattedAddress
- this.latitude = e.lnglat.lat
- this.longitude = e.lnglat.lng
- } else {
- this.$message({
- message: '获取位置信息失败!',
- type: 'warning'
- })
- }
- })
- })
- }
- },
- // 根据cityId搜索坐标
- getLocationByCityId(cityId) {
- if (AMap && cityId) {
- return new Promise((resolve, reject) => {
- // 基础配置
- const districtSearchOptions = {
- showbiz: false,
- subdistrict: 0
- }
- const amapDistrictSearch = new AMap.DistrictSearch(districtSearchOptions)
- amapDistrictSearch.search(cityId, (status, result) => {
- if (status === 'complete' && result.info === 'OK') {
- // 取数组第一个
- if (result.districtList[0]) {
- const resCenter = result.districtList[0].center
- resolve([resCenter.lng, resCenter.lat])
- }
- } else {
- reject(status)
- }
- // console.log('s:', status);
- // console.log('r:', result);
- })
- })
- } else {
- return Promise.reject('no AMap or no Id')
- }
- },
- // 搜索输入
- querySearchAsync(queryString, cb) {
- // 插件配置
- const autoOptions = {}
- let aMapAutoComplete = null
- if (AMap && queryString) {
- aMapAutoComplete = new AMap.AutoComplete(autoOptions)
- // 搜索
- aMapAutoComplete.search(queryString, (status, result) => {
- if (status === 'complete' && result.info === 'OK') {
- cb(result.tips)
- }
- // console.log('s:', status);
- // console.log('r:', result);
- })
- }
- },
- // 选择搜索项
- handleSelect(item) {
- // console.log(item);
- if (map) {
- map.setCenter([item.location.lng, item.location.lat])
- if (marker) {
- map.remove(marker)
- }
- // 添加标记点
- marker = new AMap.Marker({
- position: [item.location.lng, item.location.lat],
- map: map
- })
- // 给表单数据
- this.address = item.district + item.address
- this.latitude = item.location.lat
- this.longitude = item.location.lng
- }
- },
- // 确认按钮
- submitForm() {
- if (this.address && this.latitude && this.longitude) {
- const data = {
- address: this.address,
- latitude: this.latitude,
- longitude: this.longitude
- }
- this.$emit('get-address', data)
- this.open = false
- } else {
- this.msgError('请选择地点!')
- }
- },
- // 取消按钮
- cancel() {
- // 关闭地图清空按钮
- if (map && marker) {
- map.remove(marker)
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .container {
- width: 100%;
- height: 600px;
- }
- .footer {
- padding: 0 20px 10px;
- }
- // 自定义样式
- .my-autocomplete {
- li {
- line-height: normal;
- padding: 7px;
- .name {
- text-overflow: ellipsis;
- overflow: hidden;
- }
- .addr {
- font-size: 12px;
- color: #b4b4b4;
- }
- .highlighted .addr {
- color: #ddd;
- }
- }
- }
- </style>
|