vue3 + vite2 + Cesium

1,505 阅读1分钟

前言:

因为之前没有使用过cesium对webgis也接触的比较少,就写个系列记录一下自己遇到的问题。

为什么不选择vue2而是vue3?

vue2采用数据劫持的方式实现响应式,cesium提供的api中每个实例的属性都非常多
这个时候vue再去对他进行数据劫持就可能会造成页面卡顿而vue3采用多proxy代理实现响应式就不存在这个问题
解决方式是把变量定义在data外部,或者定义在data中并且在变量面前加_告诉vue不需要对这个变量进行劫持

解决办法一

<script>
let viewer = null
export default {
  data () {
    return {}
  },
}
</script>

解决办法二

export default {
  data () {
    return {
      _viewer: null
    }
  },
  methods: {}
}

项目初始化

  1. 首先搭建项目脚手架 npm init vite 然后根据自己的需求选择相应的配置这里选择的是vue3+ts image.png

2.用vscode打开项目下载依赖 npm install

3.安装cesium模块以及 vite-plugin-cesium插件 npm install cesium vite-plugin-cesium

4.在main.ts中配置cesium icon地址 没有的话需要去官网注册cesium.com/ion/signin/

import { createApp } from 'vue'
import App from './App.vue'
import * as Cesium from 'cesium'
import 'cesium/Source/Widgets/widgets.css'
const app = createApp(App)
Cesium.Ion.defaultAccessToken = '你的icon地址'
app.config.globalProperties.$Cesium = Cesium
app.mount('#app')

5.配置vite.config.js这里会报错找不到path模块需要安装type/node

npm install @types/node --save-dev

import { defineConfig } from 'vite'
import { resolve } from 'path'
import vue from '@vitejs/plugin-vue'
import cesium from 'vite-plugin-cesium'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    cesium(),
  ],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src'), // 路径别名
    },
    extensions: ['.js', '.json', '.ts'], // 使用路径别名时想要省略的后缀名,可以自己 增减
  },
})

6.编写cesiumMap组件并且在app.vue中引入,因为这里用的ts所以需要声明viewer变量

//cesiumMap.vue
<template>
    <div id="cesiumContainer">
    </div>
</template>
<script setup lang="ts">
import * as Cesium from 'cesium'
import { onMounted } from 'vue'
const TDTTK = '你的天地图tk'
const initCesium = () => {
  window.viewer =  new Cesium.Viewer('cesiumContainer', {
    baseLayerPicker: false, // 如果设置为false,将不会创建右上角图层按钮。
    geocoder: false, // 如果设置为false,将不会创建右上角查询(放大镜)按钮。
    navigationHelpButton: false, // 如果设置为false,则不会创建右上角帮助(问号)按钮。
    homeButton: false, // 如果设置为false,将不会创建右上角主页(房子)按钮。
    sceneModePicker: false, // 如果设置为false,将不会创建右上角投影方式控件(显示二三维切换按钮)。
    animation: false, // 如果设置为false,将不会创建左下角动画小部件。
    timeline: false, // 如果设置为false,则不会创建正下方时间轴小部件。
    fullscreenButton: false, // 如果设置为false,将不会创建右下角全屏按钮。
    scene3DOnly: false, // 为 true 时,每个几何实例将仅以3D渲染以节省GPU内存。
    shouldAnimate: true, // 默认true ,否则为 false 。此选项优先于设置 Viewer#clockViewModel 。
    // ps. Viewer#clockViewModel 是用于控制当前时间的时钟视图模型。我们这里用不到时钟,就把shouldAnimate设为false
    infoBox: false, // 是否显示点击要素之后显示的信息
    sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  this.Cesium.SceneMode
    requestRenderMode: false, // 启用请求渲染模式,不需要渲染,节约资源吧
    // 地图影像这里选择的是天地图
    imageryProvider: new Cesium.UrlTemplateImageryProvider({
      url: `https://t4.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=${TDTTK}`,
      maximumLevel: 18,
    }),
    selectionIndicator: false, // 关闭绿色选择框
  })
  window.viewer._cesiumWidget._creditContainer.style.display = 'none' //去除cesium按钮
  window.viewer.scene.globe.depthTestAgainstTerrain = true
}
onMounted(() => {
  initCesium()
})
</script>

<style scoped>
  #cesiumContainer {
    height: 100vh;
    width: 100vw;
    overflow: hidden;
  }
</style>
//app.vue
<script setup lang="ts">
import CesiumMap from './components/cesiumMap.vue';
</script>

<template>
  <CesiumMap></CesiumMap>
</template>

<style>
*,*::after,*::before {
  margin: 0;
  padding: 0;
}
</style>

//com.d.ts
declare interface Window {
  viewer: any
}
  1. 大功告成,运行项目 npm run dev 然而报错了!!!

image.png 找到node_modules/cesium/pakage.json 搜索exports字段把报错提示缺少两个模块包给它添加上然后重新运行项目就可以了

"exports": {
    "./package.json": "./package.json",
    ".": {
      "require": "./index.cjs",
      "import": "./Source/Cesium.js"
    },
    "./Source/Widgets/widgets.css": "./Source/Widgets/widgets.css"
  },

8.cesium地球

image.png

写在最后

第一次发文章,下次就是第二次了,后续也会继续记录cesium和vue或者其他前端相关的东西,欢迎各位一起交流学习