vue2+echarts5:2D地图打点、下钻

news2024/12/28 19:36:05

准备

要实现地图可点击、下钻,为了使地图有3D效果,原本用map3D需要下载依赖echarts-gl,由于存在地图下钻后在区域内无法展示完整地图,改用2D地图

"echarts": "^5.4.2",
// "echarts-gl": "^2.0.9",

效果展示

结尾附上源码
在这里插入图片描述

实现

注册地图

地图需要有dom才能挂载,需要将挂载方法写在mounted
挂载完成后,传入配置项渲染地图、如果有事件也在此时配置
其中ongetZr().on的区别为,前者是内容区的点击事件,即地图区域,后者为整个区域,包含地图和dom区域的空白部分区域。

this.chart = echarts.init(this.$refs.chart, '', {
        renderer: this.type,
      })
      this.chart.setOption(this.chartOption)
      this.chart.on('click', this.handleClick)
      this.chart.on('mousemove', this.handleMousemove)
      this.chart.getZr().on('mousemove', this.handleMouseout)

下钻

echarts5中不再内置地图数据,在项目中使用的是阿里云的数据。

axios
        .get(url)
        .then((res) => {})

注意,在本地获取数据没有问题,但当发布到测试环境或者生产环境可能会返回数据403,需要在index.html中添加一行代码配置

<meta name="referrer" content="no-referrer" />

在点击事件中添加方法,重新获取数据配置项,渲染数据

打点

打点使用的是静态的点scatter,还可以使用自带动态效果的点effectScatter(目前只支持涟漪效果)
此项目中有一个问题是可能会出现经纬度相同的点,处理数据代码如下:

let arr = data.filter((child) => child.lat === item.lat && child.lng === item.lng)
          if (arr.length > 0) {
            item.childs = arr.map((item) => {
              return {
                value: [item.lng, item.lat, item.projectName, item.stage],
                lineData: [item.useMaterialNumber || 0, item.freeMaterialNumber || 0, item.demandMaterialNumber || 0],
                iconList,
                ...item,
              }
            })
          } else {
            item.childs = []
          }

阴影效果

设置多层geo添加阴影和边框,注意多层会导致地图渲染卡顿,尽量减少使用。

南海诸岛

由于地图数据返回的南海诸岛展开九段线,会导致中国地图渲染效果不理想,可以给地图设置map:'china',会自带南海诸岛缩略图,然后中国地图数据采用去掉九段线的数据

源码

map.vue

<template>
  <div>
    <div class="echartMapTestView">
      <chart-view
        class="map-view"
        :chart-option="mapOpt"
        height="856px"
        width="856px"
        :mapName="mapName"
        @click="handleMapClick"
        @backType="backType"
      />
    </div>
  </div>
</template>

<script>
// import { mapRequest } from '@/api/cockpit'
import * as echarts from 'echarts'
import axios from 'axios'
import chartView from './chartView.vue'
import { getProvincesCode, getCityCode, getMapList } from '@/api/cockpit.js'
import { yellowIcon, blueIcon, greenIcon, defaultIcon } from './icon.js'
const chinaData = require('./china.json')
let iconObj = {
  useMaterialNumber: greenIcon,
  freeMaterialNumber: yellowIcon,
  demandMaterialNumber: blueIcon,
  defaultIcon: defaultIcon,
}
export default {
  name: 'echartMapTestView',
  components: {
    chartView,
  },
  data() {
    return {
      mapType: 'country', // 当前地图层级 province 省 city:城市
      mapOpt: {},
      mapName: '中国',
      provinceCodeList: [],
      cityCodeList: [],
      provinceData: {
        name: '',
        code: null,
      }, // 当前选中的省份code
      mapPopData: [], // 地图数据
      domImg: require('@/assets/images/cockpit/860img.png'),
      domImg600: require('@/assets/images/cockpit/600img.png'),
      iconInterval: null, //icon切换定时器
      iconIndex: 0, //展示的icon索引
      mapCode: null,
      mapList: [],
      mapJson: null,
    }
  },
  created() {
    this.getCountryData()
  },
  mounted() {
    this.$nextTick(() => {
      this.intervalInitMap(100000, '中国', 'country')
    })
  },
  beforeDestroy() {
    this.clearIconInterval()
  },
  methods: {
    // 地图点击事件
    handleMapClick(params) {
      const { name, seriesType } = params
      // 如果点击的是地图上的marker不下钻

      if (seriesType !== 'map') return
      if (this.mapType == 'country') {
        let curName = name
        if (name == '台湾省') {
          curName = '台湾'
        } else if (name == '北京市') {
          curName = '北京'
        } else if (name == '上海市') {
          curName = '上海'
        } else if (name == '重庆市') {
          curName = '重庆'
        } else if (name == '天津市') {
          curName = '天津'
        }
        let index = this.provinceCodeList.findIndex((item) => item.name == curName)
        if (index > -1) {
          this.provinceData.name = name
          this.provinceData.code = this.provinceCodeList[index].id
          this.intervalInitMap(this.provinceCodeList[index].id, name, 'province')
        } else {
          this.provinceData = {
            name: '',
            code: null,
          }
        }
      } else if (this.mapType == 'province') {
        this.handleCity(name)
      }
    },
    handleCity(name) {
      getCityCode(this.provinceData.code).then((res) => {
        if (res && res.length > 0) {
          let index = res.findIndex((item) => item.name == name)
          if (index > -1) {
            this.intervalInitMap(res[index].id, name, 'city')
          }
        }
      })
    },

    intervalInitMap(url, name, type) {
      this.clearIconInterval()
      this.initMap(url, name, type, true)
      this.startInterval()
    },

    async initMap(url, name, type, newMap) {
      let curUrl = `https://geo.datav.aliyun.com/areas_v3/bound/${url}_full.json`
      if (url == '710000') {
        curUrl = `https://geo.datav.aliyun.com/areas_v3/bound/${url}.json`
      }
      const data = await getMapList({
        city: type == 'city' ? url : '',
        province: type == 'country' ? '' : this.provinceData.code,
      })
      let formateArr = []
      if (data && data.length) {
        data.forEach((item) => {
          let iconList = []
          if (item.useMaterialNumber) iconList.push('useMaterialNumber')
          if (item.freeMaterialNumber) iconList.push('freeMaterialNumber')
          if (item.demandMaterialNumber) iconList.push('demandMaterialNumber')
          if (!iconList.length) iconList.push('defaultIcon')

          let arr = data.filter((child) => child.lat === item.lat && child.lng === item.lng)
          if (arr.length > 0) {
            item.childs = arr.map((item) => {
              return {
                value: [item.lng, item.lat, item.projectName, item.stage],
                lineData: [item.useMaterialNumber || 0, item.freeMaterialNumber || 0, item.demandMaterialNumber || 0],
                iconList,
                ...item,
              }
            })
          } else {
            item.childs = []
          }

          if (item.childs.length) {
            let sarr = formateArr.filter((child) => child.lat === item.lat && child.lng === item.lng)
            if (!sarr.length) {
              let obj = JSON.parse(JSON.stringify(item))
              let curData = {
                value: [item.lng, item.lat, item.projectName, item.stage],
                // lineData: [item.useMaterialNumber || 0, item.freeMaterialNumber || 0, item.demandMaterialNumber || 0],
                iconList,
                ...obj,
              }
              formateArr.push(curData)
            }
          } else {
            let obj = JSON.parse(JSON.stringify(item))
            let curData = {
              value: [item.lng, item.lat, item.projectName, item.stage],
              // lineData: [item.useMaterialNumber || 0, item.freeMaterialNumber || 0, item.demandMaterialNumber || 0],
              iconList,
              ...obj,
            }
            formateArr.push(curData)
          }
        })
      }

      this.mapList = formateArr.length > 0 ? [...formateArr] : []
      axios
        .get(curUrl)
        .then((res) => {
          this.mapCode = url
          this.mapName = name
          this.mapType = type
          const mapData = res.data
          this.mapJson = mapData
          const jsonMap = { mark: this.mapName, json: mapData }

          this.mapOpt = this.getSimpleMap(jsonMap, formateArr, newMap)
        })
        .catch(() => {})
    },

    getSimpleMap(jsonMap, data, newMap) {
      let mapName = jsonMap.mark == '中国' ? 'china' : jsonMap.mark
      let mapData = jsonMap.mark == '中国' ? chinaData : jsonMap.json
      if (!echarts.getMap(jsonMap.mark)) {
        echarts.registerMap(mapName, mapData)
      }
      const defaultConfig = {
        tooltip: {
          // 窗口外框
          trigger: 'item',
          formatter: () => {
            return ''
          },
        },
        geo: [
          {
            map: mapName,
            type: 'map',
            layoutCenter: ['50%', '50%'],
            layoutSize: '100%',
            zoom: 0.9,
            // top: 'top',
            // left: 20,
            roam: false,
            itemStyle: {
              borderColor: '#00C4A7',
              borderWidth: 4,
              areaColor: {
                image: this.domImg, //
                repeat: 'repeat', // // 是否平铺,可以是 'repeat-x', 'repeat-y', 'no-repeat'
              },
              shadowColor: 'rgb(13,92,79)',
              shadowOffsetX: 2,
              shadowOffsetY: 4,
            },
            regions: [
              //单独设置南海展示
              {
                name: '南海诸岛',
                value: 0,
                itemStyle: {
                  borderWidth: 0,
                  shadowColor: 'rgb(13,92,79)',
                  shadowOffsetX: 2,
                  shadowOffsetY: 2,
                },
              },
            ],
            emphasis: {
              disabled: true,
              tooltip: {
                show: false,
              },
            },
          },
          {
            map: mapName,
            type: 'map',
            layoutCenter: ['50%', '50%'],
            layoutSize: '100%',
            zoom: 0.9,
            // top: 'top',
            // left: 20,
            roam: false,
            zlevel: -2,
            tooltip: {
              show: false,
            },
            itemStyle: {
              areaColor: {
                image: this.domImg, //
                repeat: 'repeat', // // 是否平铺,可以是 'repeat-x', 'repeat-y', 'no-repeat'
              },
              shadowColor: 'rgb(14,102,88)',
              shadowOffsetX: 4,
              shadowOffsetY: 6,
            },
            regions: [
              {
                name: '南海诸岛',
                value: 0,
                itemStyle: {
                  shadowColor: 'rgb(14,102,88)',
                  shadowOffsetX: 3,
                  shadowOffsetY: 3,
                },
              },
            ],
          },
          {
            map: mapName,
            type: 'map',
            layoutCenter: ['50%', '50%'],
            layoutSize: '100%',
            zoom: 0.9,
            tooltip: {
              show: false,
            },
            // top: 'top',
            // left: 20,
            roam: false,
            zlevel: -3,
            itemStyle: {
              areaColor: {
                image: this.domImg, //
                repeat: 'repeat', // // 是否平铺,可以是 'repeat-x', 'repeat-y', 'no-repeat'
              },
              shadowColor: 'rgb(20,140,121)',
              shadowOffsetX: 5,
              shadowOffsetY: 10,
            },
            regions: [
              {
                name: '南海诸岛',
                value: 0,
                itemStyle: {
                  shadowColor: 'rgb(20,140,121)',
                  shadowOffsetX: 4,
                  shadowOffsetY: 4,
                },
              },
            ],
          },
          {
            map: mapName,
            type: 'map',
            tooltip: {
              show: false,
            },
            layoutCenter: ['50%', '50%'],
            layoutSize: '100%',
            zoom: 0.9,
            // top: 'top',
            // left: 20,
            roam: false,
            zlevel: -5,
            itemStyle: {
              areaColor: {
                image: this.domImg, //
                repeat: 'repeat', // // 是否平铺,可以是 'repeat-x', 'repeat-y', 'no-repeat'
              },
              shadowColor: 'rgb(36,185,161)',
              shadowOffsetX: 6,
              shadowOffsetY: 14,
            },
            regions: [
              {
                name: '南海诸岛',
                value: 0,
                itemStyle: {
                  shadowColor: 'rgb(25,178,154)',
                  shadowOffsetX: 5,
                  shadowOffsetY: 5,
                },
              },
            ],
          },
        ],

        series: [
          {
            type: 'map',
            map: mapName, // 自定义扩展图表类型
            animation: false,
            // 点击选中后的效果
            top: 'top',
            left: 'left',
            zoom: 0.9,
            select: {
              //不设置会有默认颜色
              label: {
                show: false,
              },
              // 清除点击选中后的背景色
              itemStyle: {
                color: null,
              },
            },
            itemStyle: {
              // 地图样式
              borderColor: 'rgba(255,255,255,0.25)',
              borderWidth: 1,
              areaColor: {
                image: this.domImg, //
                repeat: 'repeat', // // 是否平铺,可以是 'repeat-x', 'repeat-y', 'no-repeat'
              },
            },
            label: {
              show: false,
              color: '#FFFFFF',
              fontSize: 12,
              fontWeight: 400,
            },
            emphasis: {
              // 鼠标移入动态的时候显示的默认样式
              label: {
                show: true,
                color: '#FFFFFF',
                fontSize: 15,
                fontWeight: 600,
              },
              itemStyle: {
                areaColor: {
                  //鼠标悬浮背景色
                  type: 'linear',
                  x: 0,
                  y: 0,
                  x2: 0,
                  y2: 1,
                  colorStops: [
                    {
                      offset: 0,
                      color: 'rgba(30, 139, 114,0.8)', // 0% 处的颜色
                    },
                    {
                      offset: 1,
                      color: 'rgba(30, 139, 114,0.2)', // 100% 处的颜色
                    },
                  ],
                  global: false, // 缺省为 false
                },
                borderColor: '#FFFFFF',
                borderWidth: 2,
              },
            },
            layoutCenter: ['50%', '50%'],
            layoutSize: '100%',
          },
          {
            type: 'scatter',
            coordinateSystem: 'geo',
            symbol: (value, param) => {
              return iconObj[param.data.iconList[this.iconIndex % param.data.iconList.length]]
            },
            symbolSize: [26, 30],
            label: {
              show: false,
            },
            itemStyle: {
              color: 'rgba(255, 178, 76, 1)',
            },
            tooltip: {
              // 窗口外框
              trigger: 'item',
              position: 'top',
              padding: 0,
              borderWidth: 0,
              borderColor: '#FFFFFF',
              backgroundColor: 'rgba(30, 139, 114, 0.8)', //调整tooltip背景透明度
              opacity: 0.8,
              formatter: (params) => {
                // const { data } = params
                const childs = params.data.childs
                const str = `
                <div>
                  ${childs
                    .map((data) => {
                      return `
                              
                              <div style="padding:12px;
                        color: #fff;text-align:left;">
                        <div style="font-size: 18px;font-weight: 400;line-height: 21px;color: #FFFFFF;">
                          ${data.value[2]}
                        </div>
                        <div style="font-size: 12px;font-weight: 400;color: #FFFFFF;padding-top:4px;padding-bottom:8px;border-bottom:${
                          data.lineData[0] || data.lineData[1] || data.lineData[2] ? '1px solid #ffffff' : 'none'
                        }">项目阶段:${data.value[3]}</div>

                        <div style="display:${data.lineData[0] || data.lineData[1] || data.lineData[2] ? 'flex' : 'none'}" >
                          ${data.lineData
                            .map((item, index) => {
                              return `
                              
                              <div style="margin-top:8px;margin-bottom:16px;width:${item + '%'};height:8px;background:${
                                index == 0 ? '#6CE6C9' : index == 1 ? '#E7AF1D' : '#3987FF'
                              }"></div>
                              `
                            })
                            .join('')}
                        </div>

                        <div style="display:${data.lineData[0] || data.lineData[1] || data.lineData[2] ? 'flex' : 'none'};flex-wrap: wrap;" >
                          ${data.lineData
                            .map((item, index) => {
                              return `<div style="width:50%;display:flex;align-items:center">
                                <div style="width:4px;height:10px;background:${index == 0 ? '#6CE6C9' : index == 1 ? '#E7AF1D' : '#3987FF'}"></div>
                                <div style="margin-left:8px">
                                  <div style="color: #D8FDF9;font-size: 12px;">${
                                    index == 0 ? '使用中物资量' : index == 1 ? '闲置物资量' : '新需物资量'
                                  }</div>
                                  <div style="color: #FFFFFF;font-size: 16px;">${item || '--'}</div>
                                </div>
                          </div>`
                            })
                            .join('')}

                        </div>
                    </div>
                              `
                    })
                    .join('')}


                </div>
                
                    `
                return str
              },
            },
            data: data,
            showEffectOn: 'render',
            rippleEffect: {
              show: false,
              brushType: 'fill',
              number: 1,
            },
            zlevel: 9,
          },
        ],
      }
      const opt = Object.assign({}, defaultConfig)
      const { legend, tooltip, series, geo, grid } = opt
      const chartOpt = {
        grid,
        legend,
        tooltip,
        geo,
        series,
        newMap: newMap,
        animation: false,
      }
      return chartOpt
    },
    // 返回上一级
    backType() {
      if (this.mapType == 'province') {
        this.intervalInitMap(100000, '中国', 'country')
      } else if (this.mapType == 'city') {
        this.intervalInitMap(this.provinceData.code, this.provinceData.name, 'province')
      }
    },
    getCountryData() {
      getProvincesCode().then((res) => {
        if (res && res.length > 0) {
          this.provinceCodeList = [...res]
        }
      })
    },
    startInterval() {
      this.iconInterval = setInterval(() => {
        if (this.iconIndex < 2) {
          this.iconIndex = this.iconIndex + 1
        } else {
          this.iconIndex = 0
        }
        this.mapOpt = this.getSimpleMap({ mark: this.mapName, json: this.mapJson }, this.mapList, false)
      }, 5000)
    },
    clearIconInterval() {
      if (this.iconInterval) {
        clearInterval(this.iconInterval)
        this.iconInterval = null
      }
    },
  },
}
</script>

<style lang="scss" scoped>
.echartMapTestView {
  padding: 10px;
  width: 100%;
  // height: 1000px;
  margin-top: -40px;
  .map-view {
    height: 100%;
  }
}
</style>

chartView.vue


<!--
    图表
    @params: width 宽度
    @params: height 高度
    @params: autoResize 是否自动调整大小
    @params: chartOption 图表的配置
-->
<template>
  <div class="chart" :style="{ height: height, width: width }">
    <div ref="chart" class="test-bg" :style="{ height: height, width: width }"></div>
    <div class="float-content">
      <span class="area-name">当前地区:{{ mapName }}</span>
      <div class="back-content" v-if="mapName != '中国'">
        <img src="@/assets/images/cockpit/undo.svg" /><span class="back-btn" @click="backType"> 返回上一级</span>
      </div>
    </div>
  </div>
</template>
<script>
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
import * as echarts from 'echarts/core'
// 引入柱状图图表,图表后缀都为 Chart
import { BarChart } from 'echarts/charts'
// 引入提示框,标题,直角坐标系组件,组件后缀都为 Component
import { TitleComponent, TooltipComponent, GridComponent } from 'echarts/components'
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from 'echarts/renderers'

// 注册必须的组件
echarts.use([TitleComponent, TooltipComponent, GridComponent, BarChart, CanvasRenderer])

export default {
  name: 'ChartView',
  props: {
    width: {
      type: String,
      default: '100%',
    },
    mapName: {
      type: String,
      default: '全国',
    },
    height: {
      type: String,
      default: '350px',
    },
    autoResize: {
      type: Boolean,
      default: true,
    },
    chartOption: {
      type: Object,
      required: true,
    },
    type: {
      type: String,
      default: 'canvas',
    },
    playHighlight: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      chart: null,
      // 动画定时器
      iconDataIndex: null,
      areaDataIndex: null,
    }
  },
  watch: {
    chartOption: {
      deep: true,
      handler(newVal) {
        this.setOptions(newVal)
      },
    },
  },
  mounted() {
    this.initChart()
    if (this.autoResize) {
      window.addEventListener('resize', this.resizeHandler)
    }
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    if (this.autoResize) {
      window.removeEventListener('resize', this.resizeHandler)
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    resizeHandler() {
      this.chart.resize()
    },
    initChart() {
      this.chart = echarts.init(this.$refs.chart, '', {
        renderer: this.type,
      })
      this.chart.setOption(this.chartOption)
      this.chart.on('click', this.handleClick)
      this.chart.on('mousemove', this.handleMousemove)
      this.chart.getZr().on('mousemove', this.handleMouseout)
    },
    handleClick(params) {
      this.$emit('click', params)
    },
    handleMousemove(params) {
      if (params.seriesType == 'scatter') {
        this.iconDataIndex = params.dataIndex
        this.areaDataIndex = null
      } else if (params.seriesType == 'map') {
        this.iconDataIndex = null
        // 切换地图悬浮切换高亮部分
        if (this.areaDataIndex !== null && this.areaDataIndex != params.dataIndex) {
          this.chart.dispatchAction({
            type: 'downplay',
            seriesIndex: 0,
            dataIndex: this.areaDataIndex,
          })
        }

        this.areaDataIndex = params.dataIndex
      }
    },
    handleMouseout(event) {
      if (!event.target) {
        if (this.iconDataIndex !== null) {
          this.chart.dispatchAction({
            type: 'hideTip',
            seriesIndex: 1,
            dataIndex: this.iconDataIndex,
          })
        } else if (this.areaDataIndex !== null) {
          this.chart.dispatchAction({
            type: 'downplay',
            seriesIndex: 0,
            dataIndex: this.areaDataIndex,
          })
        }

        this.iconDataIndex = null
        this.areaDataIndex = null
      }
    },
    setOptions(option) {
      this.clearChart()
      this.resizeHandler()
      if (this.chart) {
        this.chart.setOption(option)
        if (option.newMap) return
        if (this.iconDataIndex !== null) {
          this.chart.dispatchAction({
            type: 'showTip',
            seriesIndex: 1,
            dataIndex: this.iconDataIndex,
          })
        } else if (this.areaDataIndex !== null) {
          this.chart.dispatchAction({
            type: 'highlight',
            seriesIndex: 0,
            dataIndex: this.areaDataIndex,
          })
        }
      }
    },
    refresh() {
      this.setOptions(this.chartOption)
    },
    clearChart() {
      this.chart && this.chart.clear()
    },
    backType() {
      this.$emit('backType')
    },
  },
}
</script>
<style scoped lang="scss">
.chart {
  position: relative;
}

.test-bg {
  background-image: url('@/assets/images/cockpit/white-bg.png');
  background-size: cover;
  // background-color: aquamarine;
}
.float-content {
  position: absolute;
  bottom: 0;
  left: 0;
  z-index: 999;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  .area-name {
    font-size: 28px;
    font-weight: 600;
    font-style: italic;
    color: #086c61;
    line-height: 40px;
  }
  .back-btn {
    font-size: 16px;
    font-family: Microsoft YaHei-Regular, Microsoft YaHei;
    font-weight: 400;
    color: #06645a;
    line-height: 19px;
  }
  .back-content {
    margin-left: 20px;
    display: flex;
    align-content: center;
    cursor: pointer;
    img {
      width: 16px;
      height: 16px;
    }
  }
}
</style>

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

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

相关文章

ChatGpt基于第三方API2D服务封装的SpringBoot starter

前置条件&#xff1a; 看下API2D官网&#xff0c;第三方API2D服务对接流程&#xff1a; 其对接文档地址 https://api2d.com/wiki/doc 一:创建一个空的Maven项目 完成后整的项目层级图如下 1.pom.xml 中添加相关依赖包 <?xml version"1.0" encoding"UTF-…

《C语言初阶篇》听说你还不会for循环的变种写法?一文教你彻底搞懂循环语句!

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《快速入门C语言》《C语言初阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言&#x1f4ac; for 语句的介绍&#x1f4ad; for循环默认可以控制几条语句&#xff1f;&#x1f4ad; for语…

vite基于vue3项目,打包之后的文件夹增加一个额外的文件夹

vite将项目打包之后&#xff0c;自动会生成一个dist文件&#xff0c;里边只有/assets,index.html,favicon.ico.这三个文件。 现在需求是打包之后&#xff0c;dist文件夹下多怎加一个healthcheck的文件夹。 功能实现&#xff1a; 使用复制的方法&#xff0c;将healthcheck文件…

[C++] 为什么头文件最好只做声明

文章目录 问题阐述问题分析和解决方法参考 问题阐述 问题描述&#xff1a; 当编译大的复杂的工程时&#xff0c;经常会遇到一个函数在头文件定义的时候&#xff0c;会导致冲突的问题&#xff1b;下图给出显性原因分析&#xff1b; 问题分析和解决方法 参考 C/C中在头文件中定义…

我爱学QT-把QT程序打包成windows文件

学习链接&#xff1a; 把QT程序打包成Windows软件_哔哩哔哩_bilibili 什么是打包和部署&#xff1f; 因为我们要把写好的程序发给用户来用&#xff0c;我们写好的源码也不能随便给别人。 怎么打包和部署&#xff1f; 1.把工程切换到release模式 这样点 &#xff0c;然后编译…

阿里大模型——通义千问

目录 前段时间世界人工智能大会在上海举行&#xff0c;我去参观感受了一下&#xff0c;整个感受是有点名不副实的&#xff0c;参展的有各种银行、车企、还有中国电信、联通三个运营商都来凑热闹了。 但是也有Google、华为、阿里、腾讯、商汤这样的大厂。现场也可以体验一些大厂…

ESP32开发板引脚介绍【附有引脚使用实例】

ESP32开发板引脚介绍 文章目录 ESP32开发板引脚介绍&#x1f468;‍&#x1f3eb;内容1&#xff1a;背景&#x1f468;‍⚖️内容2&#xff1a;限制类引脚&#x1f468;‍&#x1f4bb;内容3&#xff1a;ESP32 周边设备&#x1f349;文末备注 &#x1f468;‍&#x1f3eb; &am…

shell编程基础(第11篇:重定向)

前言 编写shell脚本程序时&#xff0c;总会使用重定向技术&#xff0c;用来永久保存程序的输出到文件中&#xff0c;或者用来从文件中提取文本到程序中&#xff0c;都支持哪些重定向呢&#xff1f; 温习3个文件描述符 1、标准输入&#xff0c;标准规定通常是键盘&#xff0c;数…

【Ajax】笔记-POST请求(原生)

POST请求 html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>AJAX POST 请求</title><…

PFD 鉴相器设计

鉴相器一般用两个D触发器&#xff0c;一个与非门和一个延迟单元 假设两个D触发器脉冲信号完全相同&#xff0c;查看D触发器输出端可以看到&#xff0c;在脉冲信号到来之后&#xff0c;D触发器输出端电压随脉冲信号升高&#xff0c;两个DFF输出同时为高时&#xff0c;与非门输出…

国科生活小程序使用须知

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、子账号是什么&#xff1f;二、子账号怎么用&#xff1f;三、怎么创建子账号&#xff1f;四、账单怎么看&#xff1f;使用须知联系开发者 前言 国科生活小程…

代码随想录算法学习心得 44 | 309.最佳买卖股票的时机含冷冻期、714.买卖股票的最佳时机含手续费、最近买卖股票时机总结...

一、最佳买卖股票的时机含冷冻期 链接&#xff1a;力扣 描述&#xff1a;给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买…

【Java】一篇文章彻底吃透抽象类和接口 |超详细,建议收藏

博主简介&#xff1a;努力学习的预备程序媛一枚~博主主页&#xff1a; 是瑶瑶子啦所属专栏: Java岛冒险记【从小白到大佬之路】 文章目录 一、抽象类1.1&#xff1a;抽象类的概念1.2&#xff1a;抽象类的定义1.3&#xff1a;抽象类的特性1.4&#xff1a;抽象类的作用和意义 二、…

捕获FormData实现极简的上传图片到服务器-实战

1.postman设置请求和查看响应结果 说明&#xff1a;上图中通过传入参数名为avatar,参数值为file格式&#xff0c;请求方式为post,采用form-data格式传入服务器。响应结果。 2.html5网页实现 <input type"file" class"upload_inp" /><button cla…

java堆溢出和栈溢出

一、堆溢出 import java.util.ArrayList; import java.util.List;public class Demo_071202 {public static void main(String[] args) {List<Test> listnew ArrayList<>();while (true){list.add(new Test());}}static class Test{} }设置JVM初始堆空间和最大堆…

告别传统MQ:Kafka是一个分布式事件流平台,这到底意味着什么呢?

1、引言 在大数据时代&#xff0c;实时数据处理和流式数据分析变得越来越重要。为了应对大规模数据的高吞吐量和低延迟处理需求&#xff0c;出现了各种分布式流处理平台。其中&#xff0c;Apache Kafka作为一种高性能、可扩展的分布式消息系统&#xff0c;成为了广泛应用于实时…

并发编程 - EDA 实操

文章目录 需求CodeUser定义不同类型的EventChat Channel(Handler)Chat User线程小结需求 借助我们开发的EDA小框架,模拟一个简单的聊天应用程序。 Code User 我们定义一个User对象,代表聊天室的参与者 package com.artisan

【每日一题】931 . 最小下降路径总和

【每日一题】931 . 最小下降路径总和 931 . 最小下降路径总和题目描述解题思路 931 . 最小下降路径总和 题目描述 给你一个n x n方形队列&#xff0c; matrix请你找出并返回matrix下降路径 的最小和。 下降路径可以从第一行中的任意元素开始&#xff0c;并从每一行中选择一个…

函数基础

一、初识函数 函数&#xff0c;可以当做是一大堆功能代码的集合。 def 函数名():函数内编写代码......函数名()例如&#xff1a; # 定义名字叫info的函数 def info():print("第一行")print("第二行")print("第n行...")info()运用函数的场景&a…

uniApp之同步资源失败,未得到同步资源的授权,请停止运行后重新运行,并注意手机上的授权提示、adb、shell、package、uninstall

文章目录 背景解决思路执行查找第三方应用的指令执行卸载指令 背景 一开始正常编译运行&#xff0c;由于应用页面有些许奇怪的错误&#xff0c;便想着卸载&#xff0c;重新运行安装调试基座。卸载后&#xff0c;运行还是会出现&#xff0c;明明已经把应用卸载了&#xff0c;还是…