人妻精品在线观看一区二区三区,蜜臀av精品一区二区三区网站,中文一区二区三区亚洲欧美,熟女人妇精品一区二区,人妻av在线观看视频,欧美日韩国产三级精品网站,黄色免费网站直接进入,超碰公开福利正在播放,国产毛片乡下农村妇女毛片

聊聊vue3中怎么使用高德地圖api-世界今亮點(diǎn)

來源:php中文網(wǎng) | 2023-03-09 19:56:47 |


【資料圖】

在我們使用高德地圖的時(shí)候,官方給我們推薦了很多案例,demo,但是這些案例都是使用原生方法接入,并沒有提供vue或者reactdemo,vue2的 接入網(wǎng)上也很多人都有寫過,下面本篇文章就來看看 vue3怎么使用常用的高德地圖api,希望對(duì)大家有所幫助!

前置工作

首先安裝包并引入
npm i @amap/amap-jsapi-loader --save
import AMapLoader from "@amap/amap-jsapi-loader"

使用官方介紹的方式進(jìn)行加

vue2vue3是有區(qū)別的,這里我們使用的是 vue3,但這里 vue3的方式還是選項(xiàng)式,不是組合式的,我自己寫的時(shí)候使用的是組合式的,且集成了ts, 我后面發(fā)布完整 .vue文件的時(shí)候 會(huì)去掉標(biāo)簽上的 ts,因?yàn)轭愋瓦€沒有完善,等后面完善了再貼更改以后得。為什么要使用 shallowRef官方也給出了說明原因。 【相關(guān)推薦:vuejs視頻教程、web前端開發(fā)】

示例模塊

這里我直接把我前面,寫過的 地圖業(yè)務(wù)需求的業(yè)務(wù)邏輯拿過來的,沒有使用框架,直接在一個(gè) html 文件當(dāng)中引入,鏈接大家可以點(diǎn)擊下面進(jìn)行查看:高德地圖jsApi的使用高德地圖jsApi的點(diǎn)和線配置高德地圖jsApi的右鍵設(shè)置高德地圖jsApi的點(diǎn)位新增高德地圖jsApi的圖例使用vue3的時(shí)候,實(shí)例化的方式, this的問題, 以及插入字符串模板的時(shí)候 事件響應(yīng)的方式都需要更改,還是很麻煩的

模塊的引入

首先導(dǎo)入的方式,和官網(wǎng)一樣,后面我會(huì)貼完整代碼, 這里我們使用 plugins加載插件, 其他配置如 Loca, 直接進(jìn)行配置, 這里需要注意版本問題, 寫成 ‘2.0’ 是不行的,初始化函數(shù)在 onmounted生命周期中執(zhí)行。AMap存儲(chǔ)這里我做了很多存儲(chǔ),大家知道 .value的語法是 vue3獲取 ref的語法,我下面使用到的 都是ref,后面完整代碼可以查看, 這里掛載的時(shí)候直接存一下,因?yàn)楹芏喙ぞ叻椒ǘ紩?huì)只用到他,這里后期業(yè)務(wù)邏輯我會(huì)抽離到 pinia中去,所以不需要在初始化函數(shù)中寫全部的業(yè)務(wù)邏輯。模版樣式不生效問題, 我們?cè)谑褂玫臅r(shí)候, 就像我之前寫的文章,點(diǎn)位新增的時(shí)候,我們會(huì)插入 content 字符串模版,替換點(diǎn)樣式,這里有兩種方案修改樣式,一種是 插入 DOM,不使用字符串,然后在 DOM 上通過 style直接修改樣式,另一種就是使用模版的時(shí)候直接給 class類名,但是這種樣式如果我們給 vuestyle加了 scoped就不會(huì)生效,這里大家可以自己靈活選擇用哪種,我這里暫時(shí)先使用模版的方式,去掉了 scoped。圖例, 圖例這里除了導(dǎo)入的時(shí)候,需要配置一下,使用上來說變化不大,樣式的修改還是復(fù)用了我之前的邏輯。
import AMapLoader from "@amap/amap-jsapi-loader"const initMap = () => {  AMapLoader.load({    key: "b59c490f61a694b9d7576dd864f74d6e", // 申請(qǐng)好的Web端開發(fā)者Key,首次調(diào)用 load 時(shí)必填    version: "2.0", // 指定要加載的 JSAPI 的版本,缺省時(shí)默認(rèn)為 1.4.15    plugins: ["AMap.Scale", "AMap.ToolBar", "AMap.MouseTool"], // 需要使用的的插件列表,如比例尺"AMap.Scale"等    Loca:{      version:"2.0.0"    }  })    .then((res) => {            AMap.value = res      // 上來就顯示的中心點(diǎn)  北京 116.397, 39.918      var lnglat = new res.LngLat(105, 38)      map.value = new res.Map("container", {        //設(shè)置地圖容器id        viewMode: "3D", //是否為3D地圖模式        zoom: 5, //初始化地圖級(jí)別        center: lnglat, //初始化地圖中心點(diǎn)位置      })      map.value.clearMap() // 清除地圖覆蓋物      // 地圖是否可拖拽和縮放      map.value.setStatus({        dragEnable: true, // 是否可拖拽        zoomEnable: true, // 是否可縮放      })      initWindow()      // 添加一些分布不均的點(diǎn)到地圖上,地圖上添加三個(gè)點(diǎn)標(biāo)記,作為參照      coordData.forEach(function (marker) {        setMarker(marker)      })      let renderLine = setLine(coordData)      // 設(shè)置線      let polyline = renderLine.reduce((prev, item, index) => {        let weight = item.type === 1 ? 5 : 3        let color = item.type === 1 ? headColors[0] : headColors[1]        prev.push(setLines(item.current, color, weight))        return prev      }, [])      map.value.add([...polyline]) // 繪制線      //創(chuàng)建右鍵菜單      menuInstance.value = new ContextMenu(map.value)      let loca = new Loca.Container({          map:map.value,      });      window._loca = loca;      // 圖例, 圖例可以實(shí)例化多個(gè),使用定位來設(shè)置位置      let lengend = new Loca.Legend({          loca: loca,          title: {              label: "管道類型",              fontColor: "rgba(255,255,255,1)",              fontSize: "16px"          },          style: {              backgroundColor: "rgba(255,255,255,0.2)",              left: "20px",              bottom: "40px",              fontSize: "12px"          },          dataMap: [              { label: "省級(jí)管道", color: headColors[1] },              { label: "縣級(jí)管道", color: headColors[0] },          ],      });      //修改圖例排列方式      document.getElementsByClassName("amap-loca loca-controls")[0].setAttribute("id", "testid")        var lis = document.querySelectorAll("#testid li");        for (var i = 0; i < lis.length; i++) {          console.log(lis[i]);          lis[i].setAttribute("class", "test"          );      }    })    .catch((e) => {      console.log("error", e)    })}onMounted(() => {  initMap()})

右鍵菜單

右鍵菜單, 右鍵菜單這里官方給我們的示例是使用一個(gè) 函數(shù) 進(jìn)行實(shí)例化,里面使用了 this, 所以這個(gè)我單獨(dú)拿出來,首先我們看一下官方的 demo

這里使用了一個(gè)函數(shù),但這個(gè)函數(shù)還不是類,但是他卻在里面使用了this,實(shí)話來講,這種寫法確實(shí)不是很優(yōu)秀,可擴(kuò)展性很差,不夠健壯,但沒辦法,誰讓我們用了人家的東西呢是吧, 在 vue3中這么用就不可以了,首先 vue3里面使用 this就不是官方建議的, 另外這里面還修改了函數(shù)原型上的方法,其實(shí)我得代碼里面一共有兩種右鍵菜單,如下:

一種是在指定點(diǎn)位上打開,另一種是在非點(diǎn)位的空白處打開,指定點(diǎn)位處打開的其實(shí)叫信息窗體,只不過是通過右鍵的方式觸發(fā),那個(gè)沒有上面這個(gè)右鍵菜單麻煩。

首先來說 this問題, 這里的 this實(shí)際上就是把我們的實(shí)例化對(duì)象掛載到上面而已,vue3中沒辦法像 vue2那樣使用 this, 但也提供給我們了 api來獲取當(dāng)前組件的實(shí)例化對(duì)象, 然后我沒用使用函數(shù), 使用了一個(gè)類,類構(gòu)造這個(gè)方法, 模版也不適用字符串模版,因?yàn)檫@里字符串模版的事件綁定寫死了,我們使用 DOM來動(dòng)態(tài)綁定事件,代碼如下:
const { ctx } = getCurrentInstance()const _this = ctx//自定義菜單類class ContextMenu {  constructor(map) {    var me = _this    //地圖中添加鼠標(biāo)工具M(jìn)ouseTool插件    _this.mouseTool = new AMap.value.MouseTool(map)    _this.contextMenuPositon = null    const fragment = document.createElement("div") // 使用 DOM 方式, 方便添加事件    fragment.className = "info context_menu"    const p = document.createElement("p")    p.addEventListener("click", this.delMarkerMenu)    p.textContent = "移除上次選中信息"    fragment.appendChild(p)    //通過content自定義右鍵菜單內(nèi)容    _this.contextMenu = new AMap.value.ContextMenu({      isCustom: true,      content: fragment,    })    //地圖綁定鼠標(biāo)右擊事件——彈出右鍵菜單    map.on("rightclick", function (e) {      me.contextMenu.open(map, e.lnglat)      me.contextMenuPositon = e.lnglat //右鍵菜單位置    })  }  delMarkerMenu() {    // 右鍵菜單上次選中點(diǎn)的信息    clearPoint()    _this.mouseTool.close()    _this.contextMenu.close()  }}

完整代碼

<!-- * @Description: 地圖 * @Autor: codeBo * @Date: 2023-03-06 16:10:10 * @LastEditors: gjzxlihaibo@163.com * @LastEditTime: 2023-03-07 14:59:08--><template>  <div id="root">    <div>      <h3>添加選點(diǎn)請(qǐng)輸入坐標(biāo)</h3>      <label>        經(jīng)度:        <input />      </label>      <label>        緯度:        <input />      </label>      <button>輸入完成</button>      <button>清空輸入</button>    </div>    <div id="container"></div>  </div></template><script setup>import { onMounted, reactive, ref, getCurrentInstance } from "vue"import AMapLoader from "@amap/amap-jsapi-loader"import { shallowRef } from "vue"import { coordData } from "./data"const map = shallowRef(null)const { ctx } = getCurrentInstance()const _this = ctxconst menuInstance = ref() // menu 實(shí)例let AMap = ref() // map 實(shí)例let currentPonit = ref<HTMLElement | null>(null) // 存儲(chǔ)當(dāng)前選中點(diǎn) DOMlet currentData = reactive({}) // 當(dāng)前選重點(diǎn)信息let sourceInfoWindow = ref()const headColors = ["#3366bb", "#6622FF"]// 工具方法// 修改DOM 類名function changeStyle(res, data) {  if (currentPonit.value !== null) {    currentPonit.value.classList.remove("active")  }  currentPonit.value = res.children[0]  currentData = data  currentPonit.value.classList.add("active")}// 清除點(diǎn)信息function clearPoint() {  if (currentPonit.value) {    currentPonit.value.classList.remove("active")  }  currentPonit.value = null  currentData = {}}// 設(shè)置線信息function setLines(lnglat, color, weight) {  return new AMap.value.Polyline({    path: lnglat,    // showDir:true ,// 設(shè)置線方向    strokeColor: color, // 線顏色    strokeWeight: weight, // 線寬    strokeOpacity: 0.6, // 透明度  })}function markerClick(e) {  console.log("sourceInfoWindow.value", sourceInfoWindow.value, e.target)  sourceInfoWindow.value.setContent(e.target.contents)  sourceInfoWindow.value.open(map.value, e.target.getPosition())}function setInput(e, name) {  let text =    e.target.parentElement.parentElement.children[0].innerText.split(      "供給點(diǎn)",    )[0]  let current = coordData.filter((item) => {    return item.name === text  })  window.localStorage.setItem(text + name, e.target.value)}const initWindow = () => {  // 信息窗體  let infoWindow = new AMap.value.InfoWindow({    offset: new AMap.value.Pixel(0, -10),    retainWhenClose: true,  })  sourceInfoWindow.value = infoWindow  infoWindow.on("open", function (...arg) {    let inputOut = document.getElementById("inputOut")    let inputPro = document.getElementById("inputPro")    inputOut.addEventListener("change", (e) => {      setInput(e, "inputOut")      window.location.reload()    })    inputPro.addEventListener("change", (e) => {      setInput(e, "inputPro")      window.location.reload()    })  })}// 抽離點(diǎn)位信息設(shè)置function setMarker(marker) {  //創(chuàng)建右鍵菜單  var contextMenu = new AMap.value.ContextMenu()  //右鍵放大  contextMenu.addItem(    "放大一級(jí)",    function () {      map.value.zoomIn()    },    0,  )  //右鍵縮小  contextMenu.addItem(    "縮小一級(jí)",    function () {      map.value.zoomOut()    },    1,  )  contextMenu.addItem("設(shè)置起點(diǎn)", function () {    console.log("設(shè)置起點(diǎn)", marker, markerd.dom)    changeStyle(markerd.dom, marker)    contextMenu.close() // 關(guān)閉右鍵菜單  })  contextMenu.addItem("與起點(diǎn)連線", function () {    if (!currentPonit) {      alert("請(qǐng)選擇起點(diǎn)")      contextMenu.close()      return    } else {      // 這里其實(shí)可以根據(jù)數(shù)據(jù)判定線類型了,因?yàn)榈诙€(gè)選中點(diǎn)的信息+和第一個(gè)選中點(diǎn)的信息都有了,但是過濾方法會(huì)比較復(fù)雜      let path = [currentData.position, marker.position]      const polyline1 = setLines(path, "#3366bb", 5)      map.value.add([polyline1])      clearPoint()    }    contextMenu.close() // 關(guān)閉右鍵菜單  })  let content = "<div></div>"  var markerd = new AMap.value.Marker({    map: map.value,    // icon: marker?.icon,    content,    offset: new AMap.value.Pixel(-8, -8),    visible: true, // 點(diǎn)標(biāo)記是否可見    position: [marker.position[0], marker.position[1]],  })  let inputO = window.localStorage.getItem(marker.name + "inputOut")  let inputP = window.localStorage.getItem(marker.name + "inputPro")  // 左鍵點(diǎn)擊的信息窗體, 寬度會(huì)在碰觸到容器邊緣的時(shí)候自適應(yīng)的縮小  markerd.contents = `    <div>${marker.name}供給點(diǎn)</div>    <div>出口壓力:<input id="inputOut" value="${      inputO ?? marker?.pointData?.out    }"/>kPa</div>    <div>供給量:<input id="inputPro" value="${      inputP ?? marker?.pointData?.provide    }" />m3</div>    <div>位置:經(jīng)度${marker.position[0]},緯度${marker.position[1]}</div>`  markerd.data = marker  markerd.on("click", markerClick)  if (marker.name === "新疆") {    // 觸發(fā)上面的點(diǎn)擊事件    markerd.emit("click", { target: markerd })  }  //綁定鼠標(biāo)右擊事件——彈出右鍵菜單  markerd.on("rightclick", function (e) {    contextMenu.open(map.value, e.lnglat)  })  return markerd}//自定義菜單類class ContextMenu {  constructor(map) {    var me = _this    //地圖中添加鼠標(biāo)工具M(jìn)ouseTool插件    _this.mouseTool = new AMap.value.MouseTool(map)    _this.contextMenuPositon = null    const fragment = document.createElement("div") // 使用 DOM 方式, 方便添加事件    fragment.className = "info context_menu"    const p = document.createElement("p")    p.addEventListener("click", this.delMarkerMenu)    p.textContent = "移除上次選中信息"    fragment.appendChild(p)    //通過content自定義右鍵菜單內(nèi)容    _this.contextMenu = new AMap.value.ContextMenu({      isCustom: true,      content: fragment,    })    //地圖綁定鼠標(biāo)右擊事件——彈出右鍵菜單    map.on("rightclick", function (e) {      me.contextMenu.open(map, e.lnglat)      me.contextMenuPositon = e.lnglat //右鍵菜單位置    })  }  delMarkerMenu() {    // 右鍵菜單上次選中點(diǎn)的信息    clearPoint()    _this.mouseTool.close()    _this.contextMenu.close()  }}// 過濾線方法function setLine(arr) {  return arr.reduce((prev, item) => {    if (item?.line) {      prev.push(...item.line)    }    return prev  }, [])}const initMap = () => {  AMapLoader.load({    key: "b59c490f61a694b9d7576dd864f74d6e", // 申請(qǐng)好的Web端開發(fā)者Key,首次調(diào)用 load 時(shí)必填    version: "2.0", // 指定要加載的 JSAPI 的版本,缺省時(shí)默認(rèn)為 1.4.15    plugins: ["AMap.Scale", "AMap.ToolBar", "AMap.MouseTool"], // 需要使用的的插件列表,如比例尺"AMap.Scale"等    Loca:{      version:"2.0.0"    }  })    .then((res) => {            AMap.value = res      // 上來就顯示的中心點(diǎn)  北京 116.397, 39.918      var lnglat = new res.LngLat(105, 38)      map.value = new res.Map("container", {        //設(shè)置地圖容器id        viewMode: "3D", //是否為3D地圖模式        zoom: 5, //初始化地圖級(jí)別        center: lnglat, //初始化地圖中心點(diǎn)位置      })      map.value.clearMap() // 清除地圖覆蓋物      // 地圖是否可拖拽和縮放      map.value.setStatus({        dragEnable: true, // 是否可拖拽        zoomEnable: true, // 是否可縮放      })      initWindow()      // 添加一些分布不均的點(diǎn)到地圖上,地圖上添加三個(gè)點(diǎn)標(biāo)記,作為參照      coordData.forEach(function (marker) {        setMarker(marker)      })      let renderLine = setLine(coordData)      // 設(shè)置線      let polyline = renderLine.reduce((prev, item, index) => {        let weight = item.type === 1 ? 5 : 3        let color = item.type === 1 ? headColors[0] : headColors[1]        prev.push(setLines(item.current, color, weight))        return prev      }, [])      map.value.add([...polyline]) // 繪制線      //創(chuàng)建右鍵菜單      menuInstance.value = new ContextMenu(map.value)      let loca = new Loca.Container({          map:map.value,      });      window._loca = loca;      // 圖例, 圖例可以實(shí)例化多個(gè),使用定位來設(shè)置位置      let lengend = new Loca.Legend({          loca: loca,          title: {              label: "管道類型",              fontColor: "rgba(255,255,255,1)",              fontSize: "16px"          },          style: {              backgroundColor: "rgba(255,255,255,0.2)",              left: "20px",              bottom: "40px",              fontSize: "12px"          },          dataMap: [              { label: "省級(jí)管道", color: headColors[1] },              { label: "縣級(jí)管道", color: headColors[0] },          ],      });      //修改圖例排列方式      document.getElementsByClassName("amap-loca loca-controls")[0].setAttribute("id", "testid")        var lis = document.querySelectorAll("#testid li");        for (var i = 0; i < lis.length; i++) {          console.log(lis[i]);          lis[i].setAttribute("class", "test"          );      }    })    .catch((e) => {      console.log("error", e)    })}onMounted(() => {  initMap()})</script><style>#container {  width: 1350px;  height: 900px;}#root {  display: flex;  width: 100%;}#root > div:first-child {  width: 200px;  margin-right: 10px;  padding: 5px;  box-shadow: 2px 2px 2px 2px #333;}#root > div:first-child {  display: flex;  flex-direction: column;}.context_menu {  position: relative;  min-width: 12rem;  padding: 0;  background-color: white;}.context_menu p {  cursor: pointer;  padding: 0.25rem 1.25rem;}.context_menu p:hover {  background: #ccc;}.btn {  width: 80px;  margin-top: 10px;}.marker-route {  width: 15px;  height: 15px;  background-color: #22ddb8;  border-radius: 10px;}.active {  background-color: #f76809;}.content {  background-color: rgba(0, 0, 0, 0.3);  padding: 1px;  color: white;  display: flex;  align-items: center;}.content span {  display: block;  width: 20px;  height: 20px;  background-color: #3366bb;  margin: 0 10px;}.content p {  margin-right: 10px;}.test {  height: 30px;  box-sizing: content-box;  padding: 2px 10px;  line-height: 30px;  display: inline;  float: left;}.test a {  color: #333 !important;}.test span {  width: 80px !important;  margin-left: 10px;  border-radius: 10px;}.amap-info-content {  background-color: rgba(255, 255, 255, 0.6);}.test_container {  background-color: rgba(255, 255, 255, 0.6);  display: flex;  width: 180px;  flex-direction: column;  padding: 10px 18px 10px 10px;  line-height: 1.4;  overflow: auto;  justify-content: center;  align-items: center;  border: 1px solid rgba(0, 0, 0, 0.2);}.input_inner {  margin-right: 5px;  border: 1px solid #333;  border-radius: 2px;  width: 30px;}</style>
這里的業(yè)務(wù)邏輯還不完善, 輸入部分的交互邏輯沒有完成, 這個(gè)文件直接引入自己的項(xiàng)目,安裝一下上面說過的依賴, 就可以使用,不過這里數(shù)據(jù)源需要自己根據(jù)自己的數(shù)據(jù)來構(gòu)造就可以了,我引入的事 data中的一組假數(shù)據(jù),在這里給大家兩組看一下
export const coordData = [  {    name: "黑龍江",    position: [127, 47],    pointData: {      out: 100,      provide: 10,    },    line: [      {        current: [          [127, 47],          [126, 43],        ],        type: 1,      },    ],  },  {    name: "吉林",    position: [126, 43],    pointData: {      out: 120,      provide: 11,    },    line: [      {        current: [          [126, 43],          [113, 41],        ],        type: 1,      },    ],  }, ]
后面我會(huì)把業(yè)務(wù)邏輯抽離到 pinia中, 并且完善ts類型, 大家對(duì)哪一部分有疑問或者更好的解決方案可以留言一起學(xué)習(xí)~

(學(xué)習(xí)視頻分享:vuejs入門教程、編程基礎(chǔ)視頻)

以上就是聊聊vue3中怎么使用高德地圖api的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!

關(guān)鍵詞: