vue 集成高德地图,点击图标,弹出van-action-sheet,一闪而过的问题探究

代码

 <van-action-sheet v-model="sheetShow" title="">
      <div class="van-list-vol">
        <van-col span="3">
          <div>
            <van-image
              style="height: 40px; width: 40px"
              round
              :src="
                hospital.orgUrl
                  ? hospital.orgUrl
                  : require('@/assets/images/icon/search_hospital.png')
              "
            />
          </div>
        </van-col>
        <van-col span="21" style="margin-bottom: 10px">
          <div style="display: flex; margin-bottom: 10px">
            <h3 style="margin: 0; padding: 0; flex-grow: 2">
              <span>{{ hospital.orgName }}</span>
            </h3>
          </div>

          <div>
            <label class="radius-blue" v-if="hospital.orgLevel">
              {{ lev[hospital.orgLevel]
              }}{{ hospital.orgGrade ? orgGrade[hospital.orgGrade] : "" }}
            </label>
          </div>

          <div style="margin: 5px 0; display: flex">
            <label style="font-size: 15px"></label>
            <div class="item-right" v-if="hospital.distance">
              距您{{ hospital.distance }}km |
            </div>
            <div
              style="font-size: 15px; margin-left: 5px; margin-right: 5px"
            ></div>
            <div class="item-left">
              {{ hospital.detailAddress || hospital.orgAddress }}
            </div>
          </div>
        </van-col>
        <div>
          <van-row style="margin-left: 20px; margin-top: 10px">
            <van-col span="5">
              <div @click="callTel(hospital)">
                <div class="text-center">
                  <div v-if="hospital.contactPhone">
                    <img src="@/assets/images/icon/map_phone.png" width="20" />
                    <p style="margin-top: 2px">电话</p>
                  </div>
                  <div v-else>
                    <img
                      src="@/assets/images/icon/map_nophone.png"
                      width="20"
                    />
                    <p style="margin-top: 2px; color: #a8a9af">电话</p>
                  </div>
                </div>
              </div>
            </van-col>
            <van-col span="5">
              <div @click="navigation(hospital)">
                <div class="text-center">
                  <img src="@/assets/images/icon/map_navi.png" width="20" />
                  <p style="margin-top: 2px">导航</p>
                </div>
              </div>
            </van-col>
            <van-col span="14">
              <van-button round block type="primary" @click="gotoHos(hospital)"
                >去预约</van-button
              >
            </van-col>
          </van-row>
        </div>
      </div>
    </van-action-sheet>
 hospitalMap() {
      let that = this;
      let markers = [];
      AMapLoader.load({
        key: "", //设置您的key
        version: "2.0",

        AMapUI: {
          version: "1.1",
          plugins: [],
        },
        Loca: {
          version: "2.0",
        },
      })
        .then((AMap) => {
          let center = [that.locationLon, that.locationLat];
          let zo = 10;
          if (window.map != null) {
            center = window.map.getCenter();
            zo = window.map.getZoom(2);
          }
          window.map = new AMap.Map("container", {
            viewMode: "3D",
            animateEnable: false, // 是否支持缓动效果
            zooms: [2, 22],
          });
          if (that.mapInit) {
            window.map.setCenter(center);
            window.map.setZoom(zo);
          }
          window.map.clearMap();
          // 构造矢量圆形
          var circle = new AMap.Circle({
            center: new AMap.LngLat(that.locationLon, that.locationLat), // 圆心位置
            radius: 1000, //半径
            strokeColor: "rgba(0,0,255,1)", //线颜色
            strokeOpacity: 0.5, //线透明度
            strokeWeight: 0.5, //线粗细度
            fillColor: "rgba(0,0,255,1)", //填充颜色
            fillOpacity: 0.2, //填充透明度
          });
          window.map.add(circle);

          var locationMarker = new AMap.Marker({
            map: map,
            position: [that.locationLon, that.locationLat],
            icon: require("@/assets/images/icon/web_location.png"),
            offset: new AMap.Pixel(-18, -40),
          });
      
          window.map.add(locationMarker);

          for (var i = 0; i < that.mapList.length; i++) {
            var marker;
            let item = that.mapList[i];
            // console.log("地图marker", item);

            let imageUrl = require("@/assets/images/icon/web_yy.png");
            if (item.orgType) {
              if (item.orgType.indexOf("CHSC") > -1) {
                imageUrl = require("@/assets/images/icon/web_sq.png");
              }
              if (item.orgType.indexOf("healthCenter") > -1) {
                imageUrl = require("@/assets/images/icon/web_ws.png");
              }
              if (item.orgType.indexOf("clinic") > -1) {
                imageUrl = require("@/assets/images/icon/web_mz.png");
              }
              if (item.orgType.indexOf("MCH") > -1) {
                imageUrl = require("@/assets/images/icon/web_fb.png");
              }
              if (item.orgType.indexOf("other") > -1) {
                imageUrl = require("@/assets/images/icon/web_qt.png");
              }
            }

            if (item.latitude && item.longitude) {
            
              let positionV = [item.longitude, item.latitude];
              marker = new AMap.Marker({
                map: map,
                position: positionV,
                icon: imageUrl,
                offset: new AMap.Pixel(-18, -40),
              });

              // label默认蓝框白底左上角显示,样式className为:amap-marker-label
              marker.setLabel({
                direction: "top",
                offset: new AMap.Pixel(0, 0), //设置文本标注偏移量
                content:
                  "<div style='font-weight:bold;fontSize: 14'>" +
                  item.orgName +
                  "</div>", //设置文本标注内容
              });
            }
            var onMarkerClick = function (e) {
              console.log("marker 点击");
              that.hospital = item;
   			  that.sheetShow = true;
            };
            marker.on("click", onMarkerClick); //绑定click事件

            markers.push(marker);
          }

          window.map.add(markers);
          setTimeout(() => {
            if (markers.length > 3) {
              let firstFewMarker = markers.slice(0, 3); //取前十个marker
              firstFewMarker.push(locationMarker);
              window.map.setFitView(firstFewMarker, true, [50, 60, 50, 60]);
            }
          }, 800);
        })
        .catch((e) => {
          console.log(e);
        });
    },

现象

点击地图上的图标,然后sheetShow 为true,弹框一闪而过

探究

地图图标点击,然后呢,设置sheetShow 为true,弹出van-action-sheet,逻辑上是没错的,我把这个代码放在地图外的控件,是可以正确弹出对话框的,然后在浏览器模式下,是正常能弹出的,切换成手机模式,又不能弹出
在这里插入图片描述
如果是van-action-sheet问题,在地图外的地方能弹出,就应该能排除,如果是地图图标点击代码的问题,在浏览器模式下又能弹出,也就不存在兼容性的问题了,很难排查
后来和公司前端大佬交流,找到了问题,地图图标点击的时候,会刷新地图,van-action-sheet刚弹出来,地图刷新了,van-action-sheet就消失了,所以才出现一闪而过,这样就好解决了,在点击事件里边,加一个延时,刷新完了,在弹出对话框

 var onMarkerClick = function (e) {
              console.log("marker 点击");
              that.hospital = item;
              setTimeout(() => {
                that.sheetShow = true;
              }, 100);
             
            };

我这边试了一下this.$nextTick,没有效果,就先加个延时吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 vant 组件库中的 van-popover 组件来实现这个功能。首先,你需要在你的 Vue 项目中安装 vant: ```bash npm i vant -S ``` 然后,在你的组件中引入 van-popover 组件: ```javascript <template> <div> <van-button type="primary" @click="showPopover($event)">显示 Popover</van-button> <van-popover v-model="show" :actions="actions" :placement="placement" :offset="offset" /> </div> </template> <script> import { ref } from 'vue'; import { Button, Popover } from 'vant'; export default { components: { [Button.name]: Button, [Popover.name]: Popover, }, setup() { const show = ref(false); const actions = [ { name: '选项一', icon: 'success' }, { name: '选项二', icon: 'plus' }, { name: '选项三', icon: 'search' }, { name: '选项四', icon: 'like-o' }, { name: '选项五', icon: 'edit' }, ]; const placement = ref('bottom'); const offset = ref(0); const showPopover = (event) => { show.value = true; offset.value = [event.target.offsetWidth / 2, 10]; }; return { show, actions, placement, offset, showPopover, }; }, }; </script> ``` 在上面的代码中,我们先引入了 vant 的 Button 和 Popover 组件,然后在 setup 函数中定义了一些变量和方法,包括 show、actions、placement、offset 和 showPopover。其中,show 表示 Popover 是否显示,actions 表示 Popover 中的选项,placement 表示 Popover 的位置,offset 表示 Popover 的偏移量,showPopover 是点击按钮时触发的方法。 在模板中,我们使用了 van-button 组件来显示一个按钮,当该按钮被点击时,会触发 showPopover 方法,显示 Popover 组件。Popover 组件的 v-model 绑定到 show 变量,actions、placement 和 offset 属性分别绑定到 actions、placement 和 offset 变量。 最后,我们在 showPopover 方法中计算了 Popover 的偏移量,使其在按钮正下方显示。你可以根据实际需要修改 placement 和 offset 变量来调整 Popover 的位置和偏移量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值