vue2实现高德地图 JSAPI 2.0海量点标记(标注和标注图层)->自定义点位->定时刷新点位

news2024/10/5 21:23:27

前提: 需要注册高德开放平台,之后创建应用并且开通Web端(JS API)平台,然后拿到securityJsCodekey

1. 基础抽取(还原示例)

1.1 组件代码

代码说明:

  1. 需要修改securityJsCodekey为自己的
  2. allowCollision为标注是否避让marker,默认为false不避让
  3. markers为地图上的标记数组
  4. layer为一个标注层,可以理解为一个图层
  5. 流程其实就是将markers装载到layer再将layer装载到map就可以实现了
  6. this.map.setFitView(null, false, [100, 150, 10,10]);
    • 根据地图上添加的覆盖物分布情况,自动缩放地图到合适的视野级别,参数均可缺省。overlayList为覆盖物数组,缺省时为当前地图上添加的所有覆盖物图层,immediately代表是否需要动画过程,avoid代表上下左右的像素避让宽度,maxZoom代表fitView之后的最大级
    • 参数说明:
    • setFitView(overlays, immediately, avoid, maxZoom)
      • overlays (Array<Overlay>) 覆盖物
      • immediately (Boolean = false) 是否立即过渡
      • avoid (Array<Number> = [60,60,60,60]) 四周边距,上、下、左、右
      • maxZoom (Number = zooms[1]) 最大 zoom 级别
  7. allowCollisionFuncnotAllowCollisionFunc方法我没有使用,主要作用是控制标注避让marker
    • 如果需要这个功能新建两个按钮,点击事件绑定这个两个方法即可;
  8. toggleBtn方法是修改控制标注避让按钮的是否使用(disable)
    • 如果需要vue实现这个功能只需要将对应的按钮的disable绑定为allowCollision即可;
<template>
  <div id="container"></div>
</template>

<script>
  //这里可以导入其他文件(比如: 组件, 工具 js, 第三方插件 js, json文件, 图片文件等等)
  //例如: import 《组件名称》 from '《组件路径》 ';

  import AMapLoader from "@amap/amap-jsapi-loader";
  import moment from "moment";
  import {getTrackList} from '@/services/attendance/statistics.js'
  // 设置安全密钥
  window._AMapSecurityConfig = {
    securityJsCode: 'xxxx你的securityJsCodexxxx',
  }
  export default {
    name: 'PositionContainer',
    //import 引入的组件需要注入到对象中才能使用
    components: {},
    props: {
    },
    data() {
      //这里存放数据
      return {
        AMap: null,
        //此处不声明 map 对象,可以直接使用 this.map赋值或者采用非响应式的普通对象来存储。
        map: null,
        mouseTool: null,
        marker: null,
        allowCollision: false,//标注避让marker
        markers: [],
        layer: null,
      };
    },
    //计算属性 类似于 data 概念
    computed: {},
    //监控 data 中的数据变化
    watch: {
    },
    //方法集合
    methods: {
      allowCollisionFunc () {
        this.allowCollision = true;
        this.layer.setAllowCollision(true);
        this.toggleBtn();
      },
      notAllowCollisionFunc () {
        this.allowCollision = false;
        this.layer.setAllowCollision(false);
        this.toggleBtn();
      },
      toggleBtn (){
        var allowCollisionBtn = document.getElementById('allowCollision');
        var notAllowCollisionBtn = document.getElementById('notAllowCollision');
        var disableClass = 'disable';

        if(this.allowCollision){
          allowCollisionBtn.classList.add(disableClass);
          notAllowCollisionBtn.classList.remove(disableClass);
        }else {
          allowCollisionBtn.classList.remove(disableClass);
          notAllowCollisionBtn.classList.add(disableClass);
        }
      },
      initMarkers(AMap) {
        // 设置一个图标对象
        var icon = {
          // 图标类型,现阶段只支持 image 类型
          type: 'image',
          // 图片 url
          image: 'https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png',
          // 图片尺寸
          size: [64, 30],
          // 图片相对 position 的锚点,默认为 bottom-center
          anchor: 'center',
        };
        var textStyle = {
          fontSize: 12,
          fontWeight: 'normal',
          fillColor: '#22886f',
          strokeColor: '#fff',
          strokeWidth: 2,
          fold: true,
          padding: '2, 5',
        };
        var LabelsData = [
          {
            name: '自提点1',
            position: [116.461009, 39.991443],
            zooms: [10, 20],
            opacity: 1,
            zIndex: 10,
            fold: true,
            icon,
            text: {
              // 要展示的文字内容
              content: '中邮速递易',
              // 文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
              direction: 'right',
              // 在 direction 基础上的偏移量
              offset: [-20, -5],
              // 文字样式
              style: {
                // 字体大小
                fontSize: 12,
                // 字体颜色
                fillColor: '#22886f',
                //
                strokeColor: '#fff',
                strokeWidth: 2,
                fold: true,
                padding: '2, 5',
              }
            }
          },
          {
            name: '自提点2',
            position: [116.466994, 39.984904],
            zooms: [10, 20],
            opacity: 1,
            zIndex: 16,
            icon,
            text: {
              content: '丰巢快递柜-花家地北里',
              direction: 'right',
              offset: [-20, -5],
              style: textStyle
            }
          },
          {
            name: '自提点3',
            position: [116.472914, 39.987093],
            zooms: [10, 20],
            opacity: 1,
            zIndex: 8,
            icon,
            text: {
              content: '丰巢快递柜-中环南路11号院',
              direction: 'right',
              offset: [-20, -5],
              style: textStyle
            }
          },
          {
            name: '自提点4',
            position: [116.471814, 39.995856],
            zooms: [10, 20],
            opacity: 1,
            zIndex: 23,
            icon,
            text: {
              content: '丰巢快递柜-合生麒麟社',
              direction: 'right',
              offset: [-20, -5],
              style: textStyle
            }
          },
          {
            name: '自提点5',
            position: [116.469639, 39.986889],
            zooms: [10, 20],
            opacity: 1,
            zIndex: 6,
            icon,
            text: {
              content: '速递易快递柜-望京大厦',
              direction: 'right',
              offset: [-20, -5],
              style: textStyle
            }
          },
          {
            name: '自提点6',
            position: [116.467361, 39.996361],
            zooms: [10, 20],
            opacity: 1,
            zIndex: 5,
            icon,
            text: {
              content: 'E栈快递柜-夏都家园',
              direction: 'right',
              offset: [-20, -5],
              style: textStyle
            }
          },
          {
            name: '自提点7',
            position: [116.462327, 39.996071],
            zooms: [10, 20],
            opacity: 1,
            zIndex: 4,
            icon,
            text: {
              content: '丰巢自提柜-圣馨大地家园',
              direction: 'right',
              offset: [-20, -5],
              style: textStyle
            }
          },
          {
            name: '自提点8',
            position: [116.462349, 39.996067],
            zooms: [10, 20],
            opacity: 1,
            zIndex: 3,
            icon,
            text: {
              content: '丰巢快递-圣馨大地家园',
              direction: 'right',
              offset: [-20, -5],
              style: textStyle
            }
          },
          {
            name: '自提点9',
            position: [116.456474, 39.991563],
            zooms: [10, 20],
            zIndex: 2,
            opacity: 1,
            icon,
            text: {
              content: 'E栈快递柜-南湖渠西里',
              direction: 'right',
              offset: [-20, -5],
              style: textStyle
            }
          }
        ];

        this.layer = new AMap.LabelsLayer({
          zooms: [3, 20],
          zIndex: 1000,
          // collision: false,
          // 设置 allowCollision:true,可以让标注避让用户的标注
          allowCollision: this.allowCollision,
        });
        this.layer.add(this.markers);
        // 图层添加到地图
        this.map.add(this.layer);

        // 初始化 labelMarker
        for (var i = 0; i < LabelsData.length; i++) {
          var curData = LabelsData[i];
          curData.extData = {
            index: i
          };

          var labelMarker = new AMap.LabelMarker(curData);

          this.markers.push(labelMarker);

        }
        // 将 marker 添加到图层
        this.layer.add(this.markers);

        this.map.setFitView(null, false, [100, 150, 10, 10]);

        this.toggleBtn()
      },
      initMap() {
        AMapLoader.load({
          key: "xxxx你的keyCodexxxx",             // 申请好的Web端开发者Key,首次调用 load 时必填
          version: "2.0",      // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
          "plugins": [
            "AMap.Scale",
            "AMap.HawkEye",
            "AMap.ToolBar",
            "AMap.AutoComplete",
            "AMap.PlaceSearch",
            "AMap.ControlBar",
            "AMap.MouseTool",
            "AMap.DragRoute",
            "AMap.MoveAnimation"],         // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        }).then((AMap) => {

          this.AMap=AMap
          this.map = new AMap.Map("container", {  //设置地图容器id
            zoom: 15.8,   // 初始化地图级别
            center: [116.469881, 39.993599], //中心点坐标  成都 104.065735, 30.659462
            showIndoorMap: false,
          });

          this.initMarkers(AMap);


        }).catch(e => {
          console.log(e);
        })
      },
    },
    //生命周期 - 创建完成(可以访问当前 this 实例)
    created() {
      // this.getLineArr(this.equipmentId,moment().valueOf())
    },
    //生命周期 - 挂载完成(可以访问 DOM 元素)
    mounted() {
      this.initMap();
    },
    //生命周期 - 创建之前
    beforeCreate() {
    },
    //生命周期 - 挂载之前
    beforeMount() {
    },
    //生命周期 - 更新之前
    beforeUpdate() {
    },
    //生命周期 - 更新之后
    updated() {
    },
    //生命周期 - 销毁之前
    beforeDestroy() {
    },
    //生命周期 - 销毁完成
    destroyed() {
    },
    //如果页面有 keep-alive 缓存功能, 这个函数会触发
    activated() {
    },
  }
</script>

<style scoped>
  #container {
    padding: 0px;
    margin: 0px;
    width: 100%;
    height: 800px;
  }
  .input-item {
    height: 2.2rem;
  }

  .input-card {
    display: flex;
    flex-direction: column;
    min-width: 0;
    word-wrap: break-word;
    background-color: #fff;
    background-clip: border-box;
    border-radius: .25rem;
    width: 10rem;
    border-width: 0;
    border-radius: 0.4rem;
    box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
    position: fixed;
    bottom: 12rem;
    right: 2rem;
    -ms-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 0.75rem 1.25rem;
  }
</style>

1.2 使用示例

引入组件即可

<template>
  <PositionContainer></PositionContainer>
</template>

<script>
  //这里可以导入其他文件(比如: 组件, 工具 js, 第三方插件 js, json文件, 图片文件等等)
  //例如: import 《组件名称》 from '《组件路径》 ';
  import PositionContainer from '@/pages/components/map/PositionContainer';
  export default {
    name: 'Position',
    //import 引入的组件需要注入到对象中才能使用
    components: {PositionContainer},
    props: {},
    data() {
      //这里存放数据
      return {};
    },
    //计算属性 类似于 data 概念
    computed: {},
    //监控 data 中的数据变化
    watch: {},
    //方法集合
    methods: {},
    //生命周期 - 创建完成(可以访问当前 this 实例)
    created() {},
    //生命周期 - 挂载完成(可以访问 DOM 元素)
    mounted() {},
    //生命周期 - 创建之前
    beforeCreate() {},
    //生命周期 - 挂载之前
    beforeMount() {},
    //生命周期 - 更新之前
    beforeUpdate() {},
    //生命周期 - 更新之后
    updated() {},
    //生命周期 - 销毁之前
    beforeDestroy() {},
    //生命周期 - 销毁完成
    destroyed() {},
    //如果页面有 keep-alive 缓存功能, 这个函数会触发
    activated() {},
  }
</script>

<style scoped>

</style>

1.3 实现效果

image-20230510152656125

2. 进阶抽取(自定义点位+每个点位不同图标+每个点位不同标注)

这里的点位数据为后端返回数据,有需要的可以自己模拟数据

后端返回数据结构类似于如下

[
  {
    "sys_time": 1674206183000,
    "user_name": "名称1",
    "jingdu": 104.751846,
    "weidu": 31.767537,
    "sendTime": "2023-01-20 17:16:23"
    
  },
  {
    "sys_time": 1677735439000,
    "user_name": "名称2",
    "jingdu": 104.7560758,
    "weidu": 31.767168,
    "sendTime": "2023-01-20 17:16:23"
  }
]

2.1组件代码

代码说明:

  1. getNewestPositions方法是调用后端接口返回数据
  2. 然后将后端的list遍历组装为我们需要的数组LabelsData
  3. content: item.user_name+'-'+item.sendTime设置我们展示lable,
  4. image: 'https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png',设置我们点位的图标,后续用户有图标后可以从后端取数据,这里我就先写死
  5. 将后端数据的第一个数据设置为地图中心center
<template>
  <div id="container"></div>
</template>

<script>
  //这里可以导入其他文件(比如: 组件, 工具 js, 第三方插件 js, json文件, 图片文件等等)
  //例如: import 《组件名称》 from '《组件路径》 ';

  import AMapLoader from "@amap/amap-jsapi-loader";
  import {getNewestPositions} from '@/services/attendance/position.js'
  // 设置安全密钥
  window._AMapSecurityConfig = {
    securityJsCode: 'xxxx你的securityJsCodexxxx',
  }
  export default {
    name: 'PositionContainer',
    //import 引入的组件需要注入到对象中才能使用
    components: {},
    props: {
    },
    data() {
      //这里存放数据
      return {
        AMap: null,
        //此处不声明 map 对象,可以直接使用 this.map赋值或者采用非响应式的普通对象来存储。
        map: null,
        mouseTool: null,
        marker: null,
        allowCollision: false,//标注避让marker
        markers: [],
        layer: null,
        LabelsData:[],
        center: [104.065735, 30.659462],
      };
    },
    //计算属性 类似于 data 概念
    computed: {},
    //监控 data 中的数据变化
    watch: {
    },
    //方法集合
    methods: {
      newestPositions () {
        getNewestPositions().then(res => {
          if (res.data.code==0){
            var postions = res.data.data
            console.log(res.data.data)
            this.LabelsData =res.data.data.map(item=>{
              var labelsData = {
                name: item.user_name,
                position: [item.jingdu, item.weidu],
                zooms: [10, 20],
                opacity: 1,
                zIndex: 10,
                fold: true,
                icon: {
                  // 图标类型,现阶段只支持 image 类型
                  type: 'image',
                  // 图片 url
                  image: 'https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png',
                  // 图片尺寸
                  size: [64, 30],
                  // 图片相对 position 的锚点,默认为 bottom-center
                  anchor: 'center',
                },
                text: {
                  // 要展示的文字内容
                  content: item.user_name+'-'+item.sendTime,
                  // 文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
                  direction: 'right',
                  // 在 direction 基础上的偏移量
                  offset: [-20, -5],
                  // 文字样式
                  style: {
                    // 字体大小
                    fontSize: 12,
                    // 字体颜色
                    fillColor: '#22886f',
                    //
                    strokeColor: '#fff',
                    strokeWidth: 2,
                    fold: false,
                    padding: '2, 5',
                  }
                }
              }
              return labelsData
            })
            this.center=[postions[0].jingdu, postions[0].weidu]
            this.initMap()
          }else {
            this.$message.error(res.data.msg)
          }

        })
      },
      initMarkers(AMap) {


        this.layer = new AMap.LabelsLayer({
          zooms: [3, 20],
          zIndex: 1000,
          // collision: false,
          // 设置 allowCollision:true,可以让标注避让用户的标注
          allowCollision: this.allowCollision,
        });
        this.layer.add(this.markers);
        // 图层添加到地图
        this.map.add(this.layer);

        // 初始化 labelMarker
        for (var i = 0; i < this.LabelsData.length; i++) {
          var curData = this.LabelsData[i];
          curData.extData = {
            index: i
          };

          var labelMarker = new AMap.LabelMarker(curData);

          this.markers.push(labelMarker);

        }
        // 将 marker 添加到图层
        this.layer.add(this.markers);

        this.map.setFitView(null, false, [100, 150, 10, 10]);

        // this.toggleBtn()
      },
      initMap() {
        AMapLoader.load({
          key: "xxxx你的keyxxxx",             // 申请好的Web端开发者Key,首次调用 load 时必填
          version: "2.0",      // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
          "plugins": [
            "AMap.Scale",
            "AMap.HawkEye",
            "AMap.ToolBar",
            "AMap.AutoComplete",
            "AMap.PlaceSearch",
            "AMap.ControlBar",
            "AMap.MouseTool",
            "AMap.DragRoute",
            "AMap.MoveAnimation"],         // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        }).then((AMap) => {
          this.AMap=AMap
          this.map = new AMap.Map("container", {  //设置地图容器id
            zoom: 15.8,   // 初始化地图级别
            center: this.center, //中心点坐标  成都 104.065735, 30.659462
            showIndoorMap: false,
          });

          this.initMarkers(AMap);


        }).catch(e => {
          console.log(e);
        })
      },
    },
    //生命周期 - 创建完成(可以访问当前 this 实例)
    created() {
      this.newestPositions()
    },
    //生命周期 - 挂载完成(可以访问 DOM 元素)
    mounted() {
      this.initMap();
    },
    //生命周期 - 创建之前
    beforeCreate() {
    },
    //生命周期 - 挂载之前
    beforeMount() {
    },
    //生命周期 - 更新之前
    beforeUpdate() {
    },
    //生命周期 - 更新之后
    updated() {
    },
    //生命周期 - 销毁之前
    beforeDestroy() {
    },
    //生命周期 - 销毁完成
    destroyed() {
    },
    //如果页面有 keep-alive 缓存功能, 这个函数会触发
    activated() {
    },
  }
</script>

<style scoped>
  #container {
    padding: 0px;
    margin: 0px;
    width: 100%;
    height: 800px;
  }
  .input-item {
    height: 2.2rem;
  }

  .input-card {
    display: flex;
    flex-direction: column;
    min-width: 0;
    word-wrap: break-word;
    background-color: #fff;
    background-clip: border-box;
    border-radius: .25rem;
    width: 10rem;
    border-width: 0;
    border-radius: 0.4rem;
    box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
    position: fixed;
    bottom: 12rem;
    right: 2rem;
    -ms-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 0.75rem 1.25rem;
  }
</style>

2.2 使用示例

参照1.2 ,没有任何改变

2.3 抽取效果

image-20230511163123663

放大地图后

image-20230511163225355

3.最终抽取(定时刷新点位)

3.1 组件代码

代码说明:

  1. 使用定时器来做定时任务
    • this.timer = setInterval(this.newestPositionsWithoutInitMap, 120 * 1000);
  2. 切记beforeDestroy()的时候要 clearInterval(this.timer);
  3. this.map.setFitView(null, false, [100, 150, 10, 10]); 地图缩放到合适的位置
    • 就会导致我们每次刷新都会地图缩放到最大,就是因为这个
  4. 核心思路就是通过定时器来定时请求后端接口,然后渲染地图标记即可
<template>
  <div id="container"></div>
</template>

<script>
  //这里可以导入其他文件(比如: 组件, 工具 js, 第三方插件 js, json文件, 图片文件等等)
  //例如: import 《组件名称》 from '《组件路径》 ';

  import AMapLoader from "@amap/amap-jsapi-loader";
  import {getNewestPositions} from '@/services/attendance/position.js'
  // 设置安全密钥
  window._AMapSecurityConfig = {
    securityJsCode: 'xxxx你的securityJsCodexxxx',
  }
  export default {
    name: 'PositionContainer',
    //import 引入的组件需要注入到对象中才能使用
    components: {},
    props: {
    },
    data() {
      //这里存放数据
      return {
        AMap: null,
        //此处不声明 map 对象,可以直接使用 this.map赋值或者采用非响应式的普通对象来存储。
        map: null,
        mouseTool: null,
        marker: null,
        allowCollision: false,//标注避让marker
        markers: [],
        layer: null,
        LabelsData:[],
        center: [104.065735, 30.659462],
        timer: '',
        zoom: '',
      };
    },
    //计算属性 类似于 data 概念
    computed: {},
    //监控 data 中的数据变化
    watch: {
    },
    //方法集合
    methods: {
      createLable: function (res) {
        var postions = res.data.data
        this.LabelsData = res.data.data.map(item => {
          var labelsData = {
            name: item.user_name,
            position: [item.jingdu, item.weidu],
            zooms: [10, 20],
            opacity: 1,
            zIndex: 10,
            fold: true,
            icon: {
              // 图标类型,现阶段只支持 image 类型
              type: 'image',
              // 图片 url
              image: 'https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png',
              // 图片尺寸
              size: [64, 30],
              // 图片相对 position 的锚点,默认为 bottom-center
              anchor: 'center',
            },
            text: {
              // 要展示的文字内容
              content: item.user_name + '-' + item.sendTime,
              // 文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
              direction: 'right',
              // 在 direction 基础上的偏移量
              offset: [-20, -5],
              // 文字样式
              style: {
                // 字体大小
                fontSize: 12,
                // 字体颜色
                fillColor: '#22886f',
                //
                strokeColor: '#fff',
                strokeWidth: 2,
                fold: false,
                padding: '2, 5',
              }
            }
          }
          return labelsData
        })
        this.center = [postions[0].jingdu, postions[0].weidu]
      },

      newestPositions () {
        getNewestPositions().then(res => {
          if (res.data.code==0){
            this.createLable(res);
            this.initMap()
          }else {
            this.$message.error(res.data.msg)
          }

        })
      },


      newestPositionsWithoutInitMap () {
        getNewestPositions().then(res => {
          if (res.data.code==0){
            this.createLable(res);
            this.initMarkers(this.AMap)
          }else {
            this.$message.error(res.data.msg)
          }

        })
      },
      initMarkers(AMap) {
        this.markers=[]

        this.layer = new AMap.LabelsLayer({
          zooms: [3, 20],
          zIndex: 1000,
          // collision: false,
          // 设置 allowCollision:true,可以让标注避让用户的标注
          allowCollision: this.allowCollision,
        });
        this.layer.add(this.markers);
        // 图层添加到地图
        this.map.clearMap()
        this.map.add(this.layer);

        // 初始化 labelMarker
        for (var i = 0; i < this.LabelsData.length; i++) {
          var curData = this.LabelsData[i];
          curData.extData = {
            index: i
          };

          var labelMarker = new AMap.LabelMarker(curData);

          this.markers.push(labelMarker);

        }
        // 将 marker 添加到图层
        this.layer.add(this.markers);

        // this.map.setFitView(null, false, [100, 150, 10, 10]);  //地图缩放到合适的位置,开启每次都会缩放到最大状态

        // this.toggleBtn()
      },
      initMap() {
        AMapLoader.load({
          key: "xxxx你的keyxxxx",             // 申请好的Web端开发者Key,首次调用 load 时必填
          version: "2.0",      // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
          "plugins": [
            "AMap.Scale",
            "AMap.HawkEye",
            "AMap.ToolBar",
            "AMap.AutoComplete",
            "AMap.PlaceSearch",
            "AMap.ControlBar",
            "AMap.MouseTool",
            "AMap.DragRoute",
            "AMap.MoveAnimation"],         // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        }).then((AMap) => {
          this.AMap=AMap
          this.map = new AMap.Map("container", {  //设置地图容器id
            zoom: 15.8,   // 初始化地图级别
            center: this.center, //中心点坐标  成都 104.065735, 30.659462
            showIndoorMap: false,
          });

          this.initMarkers(AMap);

          // this.map.on('zoomend', function (e) {
          //   this.zoom =this.map.getZoom();
          //   console.log(this.zoom)
          //
          // }.bind(this));


        }).catch(e => {
          console.log(e);
        })
      },
    },
    //生命周期 - 创建完成(可以访问当前 this 实例)
    created() {
      this.newestPositions()
    },
    //生命周期 - 挂载完成(可以访问 DOM 元素)
    mounted() {
      this.timer = setInterval(this.newestPositionsWithoutInitMap, 120 * 1000);
      this.initMap();
    },
    //生命周期 - 创建之前
    beforeCreate() {
    },
    //生命周期 - 挂载之前
    beforeMount() {
    },
    //生命周期 - 更新之前
    beforeUpdate() {
    },
    //生命周期 - 更新之后
    updated() {
    },
    //生命周期 - 销毁之前
    beforeDestroy() {
      clearInterval(this.timer);
    },
    //生命周期 - 销毁完成
    destroyed() {
    },
    //如果页面有 keep-alive 缓存功能, 这个函数会触发
    activated() {
    },
  }
</script>

<style scoped>
  #container {
    padding: 0px;
    margin: 0px;
    width: 100%;
    height: 800px;
  }
  .input-item {
    height: 2.2rem;
  }

  .input-card {
    display: flex;
    flex-direction: column;
    min-width: 0;
    word-wrap: break-word;
    background-color: #fff;
    background-clip: border-box;
    border-radius: .25rem;
    width: 10rem;
    border-width: 0;
    border-radius: 0.4rem;
    box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
    position: fixed;
    bottom: 12rem;
    right: 2rem;
    -ms-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 0.75rem 1.25rem;
  }
</style>

3.2 使用示例

参照1.2 ,没有任何改变

3.3 抽取效果

在2.3的效果基础上每2分钟刷新一次位置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/514569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Axure教程】中继器表格寻找和标记数据

在系统表格中&#xff0c;我们想在表格中快速找到对应的数据&#xff0c;通常我们会用条件筛选来完成&#xff0c;但是用筛选的方式&#xff0c;其他数据就看不到了&#xff0c;少了两种条件之间的对比。所以如果需要数据对比的情况下&#xff0c;我们更多的是用标记数据的方式…

Unity学习笔记 关于Unity相机的FOV以及水平FOV和垂直FOV之间的转换

前言 关于FOV FOV 是在任何给定时间通过人眼、相机取景器或在显示屏上可见的可观察世界的范围。它指的是整个区域的覆盖范围&#xff0c;而不是单个固定焦点。FOV 还描述了一个人可以看到可见世界的角度。 FOV 越宽&#xff0c;可以看到的可观察世界就越多。它是水平、垂直和对…

vue3中使用外部字体

首先要找一个免费网站&#xff0c;去下载你想用的字体&#xff0c;推荐 DaFont - Download fonts 或者问UI要&#xff0c;ui在设计图的时候也会下载对应的特殊字体的包&#xff0c;所以问她要方便快捷 ~~ 如果是进入网站下载的话&#xff0c;操作步骤如下&#xff1a; 在官网…

MTN模型LOSS均衡相关论文解读

一、综述 MTN模型主要用于两个方面&#xff0c;1.将多个模型合为一个显著降低车载芯片负载。2.将多个任务模型合为一个&#xff0c;有助于不同模型在共享层的特征可以进行互补&#xff0c;提高模型泛化性能的同时&#xff0c;也有可能提高指标。传统的方法是直接不同任务loss相…

谷歌打响全面反击战!官宣AI重构搜索、新模型比肩GPT-4,朝着ChatGPT微软开炮

明敏 丰色 发自 凹非寺 量子位 | 公众号 QbitAI 万众瞩目&#xff0c;谷歌的反击来了。 现在&#xff0c;谷歌搜索终于要加入AI对话功能了&#xff0c;排队通道已经开放。 当然这还只是第一步。 大的还在后面&#xff1a; 全新大语言模型PaLM 2正式亮相&#xff0c;谷歌声称…

vue解决跨域的几种办法

当我们遇到请求后台接口遇到 Access-Control-Allow-Origin 时&#xff0c;那说明跨域了。 跨域是因为浏览器的同源策略所导致&#xff0c;同源策略&#xff08;Same origin policy&#xff09;是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能&#xff0c;同源是指&…

【C#】本地下载附件(Excel模板)

系列文章 【C#】单号生成器&#xff08;编号规则、固定字符、流水号、产生业务单号&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129129787 【C#】日期范围生成器&#xff08;开始日期、结束日期&#xff09; 本文链接&#xff1a;h…

腾讯云发布金融国产化战略、《腾讯云银行核心系统分布式转型白皮书》

5月11日&#xff0c;在腾讯金融云国产化战略峰会上&#xff0c;腾讯云发布金融国产化战略&#xff1a;腾讯云将持续加大技术投入打造新一代国产化精品产品&#xff0c;并依托产品构建全栈领先的国产数字化基座。同时&#xff0c;腾讯云还将携手伙伴&#xff0c;共同构建国产数字…

PD虚拟机增加CentOS虚拟机磁盘空间

mac环境下安装了PD虚拟机&#xff0c;近期由于需求需要&#xff0c;扩容了其中一台CentOS7的磁盘空间。 做以下记录&#xff1a; 1.PD虚拟机操作&#xff1a; 2. CentOS7内部操作&#xff1a; 2.1 lsblk -f 查看 2.2 fdisk -f 查看&#xff0c;物理磁盘已增加容量 2.3 fdis…

leetcode 1035. Uncrossed Lines(不交叉的线)

把数组nums1和nums2的元素排成2行&#xff0c; 从左到右把相同的元素连线&#xff0c;但是任意2条线不能交叉。 比如Example1中&#xff0c;可以连2个4&#xff0c;也可以连2个2&#xff0c;但是不能同时连&#xff0c;因为会交叉。 找出最多的连线数。 思路&#xff1a; 一开…

Leetcode2383. 赢得比赛需要的最少训练时长

Every day a Leetcode 题目来源&#xff1a;2383. 赢得比赛需要的最少训练时长 解法1&#xff1a;模拟 可以分开考虑在比赛开始前&#xff0c;需要最少增加的精力和经验数量。 每次遇到一个对手&#xff0c;当前精力值都需要严格大于当前对手&#xff0c;否则需要增加精力值…

设计测试用例(万能思路 + 六种设计用例方法)(详细 + 图解 + 实例)

目录 一、设计测试用例的万能思路 二、设计用例的方法 1. 等价类 2. 边界值 3. 判定表法 4. 正交法 5. 场景设计法 6. 错误猜测法 一、设计测试用例的万能思路 针对某个物品/功能进行测试。 万能思路&#xff1a;功能测设 界面测试 性能测试 兼容性测试 易用性测试…

NASM 编译器 - 产生机器码“66”,导致无法正确打印

【问题描述】 代码hello-DOS.asm&#xff0c;实现功能&#xff1a;打印“hello world” ; hello-DOS.asm - single-segment, 16-bit "hello world" program ; ; assemble with "nasm -f bin -o hi.com hello-DOS.asm" [BITS 32]org 0x100 ; .com…

el-table多级嵌套列表,菜单使用el-switch代替

需求&#xff1a;根据el-table实现多级菜单复选&#xff0c;并且只要是菜单就不再有复选框&#xff0c;也没有全选按钮&#xff0c;一级菜单使用el-switch代替原有的列复选框&#xff0c;子级如果全部选中&#xff0c;那么父级的el-switch也会被选中&#xff0c;如下图&#xf…

2023年微单相机市场电商数据分析(京东数据查询分析)

5月10日&#xff0c;尼康发布了Z8微单相机&#xff0c;首发价格27999元。规格、性能等都可以看到官方的详细讲解。不过从目前业内人士以及数码爱好者的评价来看&#xff0c;Z8的配置匹配27999元的价格是比较有优势的。 并且有很多人表示&#xff0c;Z8一经推出很有可能会对自身…

6. N 字形变换

将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 "PAYPALISHIRING" 行数为 3 时&#xff0c;排列如下&#xff1a; P A H NA P L S I I GY I R 之后&#xff0c;你的输出需要从左往右逐…

mysql查询列添加序号

添加序号查询结果 # 每次值1 # 值从0开始 SELECT (i:i1) AS 序号,user.* FROM user, (SELECT i:0) AS itable;

【Java多线程编程】解决线程的不安全问题

前言&#xff1a; 当我们进行多线程编程时候&#xff0c;多个线程抢占系统资源就会造成程序运行后达不到想要的需求。我们可以通过 synchronized 关键字对某个代码块或操作进行加锁。这样就能达到多个线程安全的执行&#xff0c;因此我把如何使用 synchronized 进行加锁的操作…

ChatGPT插件推荐,效率提升100倍!

在浏览器上使用ChatGPT时&#xff0c;借助一些插件可以帮助我们更便捷的获取消息&#xff0c;比如&#xff1a; 在搜索引擎搜索东西的同时和ChatGPT对话&#xff1b; 同一个问题同时向ChatGPT、newBing、Claude 等多个模型提问获取结果&#xff1b; 让ChatGPT可以联网获取最新…

实时聊天如何做,让客户眼前一亮(一)

网站上的实时聊天功能应该非常有用&#xff0c;因为它允许客户支持立即帮助用户。在线实时聊天可以快速轻松地访问客户服务部门&#xff0c;而它也代表着企业的门面。 让我们讨论一下如何利用SaleSmartly&#xff08;ss客服&#xff09;在网站中的实时聊天视图如何提供出色的实…