Vue3+Cesium三维可视化项目(一)

背景

将Vue2.0 + Ceium项目升级到Vue3.0,在此记录下整体升级的过程以及遇到的问题。

目标

用Vue3.0配套技术栈搭建项目框架并重构项目

技术栈:Vue2.0 + Webpack + JavaScript + Sass + Element ui + Vuex + Axios + Vue-router + Cesium

升级后:Vue3.0 + Vite  + TypeScript + Sass + Element plus + Pinia + + Axios + Vue-router + Cesium

准备工作

  • 升级node版本

由于Vite 需要 Node.js 版本 14.18+,16+。而且有些模板需要依赖更高的 Node 版本才能正常运行,包管理器可能会发出警告,请升级你的 Node 版本。推荐全局安装nvm对多个node版本进行管理,自行搜索教程,不多介绍了。

  • 创建脚手架项目

通过 vite快速创建 

npm create vite@latest

选择Vue 和 TypeScript

  • VSCode插件安装

安装volar插件支持vue3开发,同时禁用vetur。

安装ESLint插件

安装prettier插件

开发环境搭建

  • 代码规范(ESlint + prettier)

随着前端得项目的规模越来越大,一个项目多人同时协作开发的场景越来越多,代码的规范都做统一约束,提高协作开发效率。我在项目中采用ESlint + prettier来规范代码风格。

  • 安装ESlint
npm add -D eslint

初始化ESLint配置

npx eslint --init   根据自己的需求选择默认配置,初始化后根目录会生成一个.eslintrc.js文件,下面是我的基本配置

module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended",
        "plugin:vue/vue3-essential"
    ],
    "overrides": [
        {
            "env": {
                "node": true
            },
            "files": [
                ".eslintrc.{js,cjs}"
            ],
            "parserOptions": {
                "sourceType": "script"
            }
        }
    ],
    "parserOptions": {
        "ecmaVersion": "latest",
        "parser": "@typescript-eslint/parser",
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint",
        "vue"
    ],
    "rules": {
    }
}
module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended",
        "plugin:vue/vue3-essential"
    ],
    "overrides": [
        {
            "env": {
                "node": true
            },
            "files": [
                ".eslintrc.{js,cjs}"
            ],
            "parserOptions": {
                "sourceType": "script"
            }
        }
    ],
    "parserOptions": {
        "ecmaVersion": "latest",
        "parser": "@typescript-eslint/parser",
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint",
        "vue"
    ],
    "rules": {
    }
}
安装vite-plugin-eslint

npm add -D vite-plugin-eslint

安装eslint-parser

npm add -D @babel/core 
npm add -D @babel/eslint-parser 

配置vite.config.ts

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import eslintPlugin from 'vite-plugin-eslint';


import { join } from 'path'

function resolve(dir: string) {
  return join(__dirname, dir)
}

// https://vitejs.dev/config/
export default defineConfig({
	base: './', // 打包路径
  server: {
    port: 8888, // 服务端口号
    open: false, // 服务启动时是否自动打开浏览器
    cors: true // 允许跨域
  },
	plugins: [
		vue(),
		eslintPlugin({
			include: ['src/**/*.ts', 'src/**/*.vue', 'src/*.ts', 'src/*.vue'],
		}),
	],
	resolve: {
		// 配置路径别名
		alias: {
			'@': resolve('src')
		},
	}
}); 

问题:找不到path模块,设置别名无效

解决:安装@types/node模块

npm install @types/node --save-dev

tsconfig.json中compilerOptions下添加配置 

"paths": {

      "@/*": ["./src/*"]
}

  • 安装prettier
npm add -D prettier
npm add -D eslint-config-prettier 兼容eslint的插件
npm add -D eslint-plugin-prettier eslint的prettier 

根目录下新建 .prettierrc.js 文件,下面是我的默认配置

module.exports = {
  /**
   * 换行宽度,当代码宽度达到多少时换行
   * @default 150
   * @type {number}
   */
  printWidth: 150,
  /**
   * 缩进的空格数量
   * @default 2
   * @type {number}
   */
  tabWidth: 2,
  /**
   * 是否使用制表符代替空格
   * @default false
   * @type {boolean}
   */
  useTabs: false,
  /**
   * 是否在代码块结尾加上分号
   * @default true
   * @type {boolean}
   */
  semi: true,
  /**
   * 是否使用单引号替代双引号
   * @default false
   * @type {boolean}
   */
  singleQuote: true,
  /**
   * 对象属性的引号处理
   * @default "as-needed"
   * @type {"as-needed"|"consistent"|"preserve"}
   */
  quoteProps: 'as-needed',
  /**
   * jsx中是否使用单引号替代双引号
   * @default false
   * @type {boolean}
   */
  jsxSingleQuote: true,
  /**
   * 在jsx中使用是否单引号代替双引号
   * @default false
   * @type {boolean}
   */
  /**
   * 末尾是否加上逗号
   * @default "es5"
   * @type {"es5"|"none"|"all"}
   */
  trailingComma: 'none',
  /**
   * 在对象,数组括号与文字之间加空格 "{ foo: bar }"
   * @default true
   * @type {boolean}
   */
  bracketSpacing: true,
  /**
   * 把多行HTML (HTML, JSX, Vue, Angular)元素的>放在最后一行的末尾,而不是单独放在下一行(不适用于自关闭元素)。
   * @default false
   * @type {boolean}
   */
  bracketSameLine: false,
  /**
   * 当箭头函数只有一个参数是否加括号
   * @default "always"
   * @type {"always"|"avoid"}
   */
  arrowParens: 'always',
  /**
   * 为HTML、Vue、Angular和Handlebars指定全局空格敏感性
   * @default "css"
   * @type {"css"|"strict"|"ignore"}
   */
  htmlWhitespaceSensitivity: 'ignore',
  /**
   * 是否缩进Vue文件中的<script>和<style>标记内的代码。有些人(比如Vue的创建者)不使用缩进来保存缩进级别,但这可能会破坏编辑器中的代码折叠。
   * @default "always"
   * @type {"always"|"avoid"}
   */
  vueIndentScriptAndStyle: false,
  /**
   * 文件结束符
   * @default "lf"
   * @type {"lf"|"crlf"|"cr"|"auto"}
   */
  endOfLine: 'crlf',
  /**
   * 因为使用了一些折行敏感型的渲染器(如GitHub comment)而按照markdown文本样式进行折行
   */
  proseWrap: 'never',
  // 是否使用根目录下的EditorConfig配置文件
  useEditorConfig: false,
  /**
   * HTML\VUE\JSX每行只有单个属性
   * @default true
   * @type {boolean}
   */
  singleAttributePerLine: false,
  disableLanguages: ['html']
}
  • 引入Element Plus
安装 npm install element-plus --save

在main.ts中全局引入,如果需要按需引入,请参考官方文档

// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElementPlus)
app.mount('#app')
  • 集成Vue-router
安装  npm install vue-router@4

创建src/router/index.ts文件

import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";

const routes: Array<RouteRecordRaw> = [
  {
    path: '/home',
    name: 'Home',
    component: () => import('@/components/HelloWorld.vue')
  },
  {
    path: '/',
    redirect: { name: 'Home' }
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router;

在main.ts中引入

import { createApp } from 'vue';

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './style.css';
import App from './App.vue';

import router from '@/router/index';

const app = createApp(App);

app.use(ElementPlus);
app.use(router);

app.mount('#app');
集成Pinia
安装 npm install pinia

创建src/store/index.ts文件 

import { createPinia } from 'pinia';

const pinia = createPinia();

export default pinia;

在main.ts中引入

import { createApp } from 'vue';

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './style.css';
import App from './App.vue';

import router from '@/router/index';
import pinia from '@/store/index';

const app = createApp(App);

app.use(ElementPlus);
app.use(router);
app.use(pinia);

app.mount('#app');

集成Axios
安装  npm install axios

新建文件src/utils/service/request.js,创建axios拦截器,这里我暂时我用的JS,后续再改吧...

import axios from 'axios';
import qs from 'qs';
import { ElMessage } from 'element-plus';

// 创建axios实例
const service = axios.create({
  baseURL: '',
  timeout: 60000,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  }
});

// 请求拦截器
service.interceptors.request.use(
  (requestConfig) => {
    // 防止GET请求缓存,追加时间戳
    if (requestConfig.method?.toUpperCase() === 'GET') {
      requestConfig.params = { ...requestConfig.params, t: new Date().getTime() / 1000 };
    }
    if (Object.values(requestConfig.headers).includes('application/x-www-form-urlencoded')) {
      requestConfig.data = qs.stringify(requestConfig.data);
    }

    const token = sessionStorage.getItem("token"); // || projectConfig.accessToken;
    if (token) {
      requestConfig.headers.Authorization = "Bearer " + token;
    }

    return requestConfig;
  },
  error => {
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  response => {
    if (response.status !== 200) {
      return Promise.reject(new Error(response.statusText || 'Error'));
    }

    const resData = response.data;
    if (resData.code === 200) {
      return resData;
    } 

    ElMessage.error(resData.message);

    return Promise.reject(new Error(resData.message || 'Error'));
  },
  error => {
    ElMessage.error(error.message);
    return Promise.reject(error)
  }
)

export default service;

挂载到全局

import { createApp } from 'vue';

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './style.css';
import App from './App.vue';

import router from '@/router/index';
import store from '@/store/index';
import service from '@/utils/service/request';

const app = createApp(App);

app.use(ElementPlus);
app.use(router);
app.use(store);

app.config.globalProperties.$axios = service;

app.mount('#app');

组件中引用

<template>
  <h1>测试</h1>
</template>

<script setup lang="ts">
  import { getCurrentInstance } from 'vue';
  const currentInstance: any = getCurrentInstance();
  const { proxy } = currentInstance;

  const data = {}

  proxy.$axios({
      url: '',
      method: 'post',
      data
    })
    .then((res: any) => {
      console.log(res);
  });
  proxy.$axios({
      url: '',
      method: 'get',
      params: data
    })
    .then((res: any) => {
      console.log(res);
  });
</script>

<style lang="scss" scoped>
  .read-the-docs {
    color: #888;
  }
</style>

集成CSS预编译器

我在项目中使用的是sass,Vite 已经集成好了相关的loader ,不需要再做额外的配置

安装 npm install sass -D

使用的话在style标签中添加 lang="scss"属性

<style lang="scss"></style>
集成Cesium

安装cesium

npm install cesium@1.67.0

在main.ts 定义全局变量 CESIUM_BASE_URL:

declare global {
  interface Window {
    CESIUM_BASE_URL: string
  }
}

把 node_modules/cesium/Build/CesiumUnminified/ 这个未压缩版本的文件夹下内容, AssetsWidgetsWorkersThirdParty 四个文件夹拷贝到 public/static/Cesium/ 下

组件中使用

<template>
  <div id="cesiumContainer" ref="viewerDivRef" class="viewer"></div>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import { TileMapServiceImageryProvider, Viewer, buildModuleUrl } from 'cesium'
import 'cesium/Build/CesiumUnminified/Widgets/widgets.css'

const viewerDivRef = ref();
window.CESIUM_BASE_URL = '/static/webgl/Cesium/'

onMounted(() => {
  new Viewer(viewerDivRef.value, {
    imageryProvider: new TileMapServiceImageryProvider({
      url: '/static/webgl/Cesium/Assets/Textures/NaturalEarthII',
    })
  })
})
</script>

<style lang="scss" scoped>
  #cesiumContainer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.viewer-main {
  float: left;
  width: 100%;
  height: 100%;
  position: relative;
}

</style>

效果

总结

以上就是从Vue2到Vue3+TypeScript+Element plus + Vue-router + Axios + Sass + Cesium的开发环境的准备工作,后续会继续记录用Vue3语法重构Vue2.0项目。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue.js是一个流行的JavaScript框架,用于构建用户界面。Cesium是一个开源的地理信息系统 (GIS) 库,用于创建地球上的三维地图和可视化效果。结合Vue.jsCesium可以实现在Web应用中展示三维地图和地理数据的功能。 要在Vue.js中使用Cesium,你可以按照以下步骤进行操作: 1. 首先,确保你已经安装了Vue.jsCesium。你可以通过npm或yarn来安装它们: ```bash npm install vue npm install cesium ``` 2. 在你的Vue.js应用中创建一个组件来容纳Cesium地图。你可以在组件的模板中添加一个div元素作为地图容器: ```html <template> <div id="cesiumContainer"></div> </template> ``` 3. 在组件的脚本部分,你可以导入Cesium的相关模块,并在组件的生命周期钩子函数中初始化Cesium地图: ```javascript <script> import Cesium from 'cesium/Cesium'; export default { mounted() { this.viewer = new Cesium.Viewer('cesiumContainer'); }, beforeDestroy() { this.viewer.destroy(); } } </script> ``` 4. 最后,在你的应用中使用这个组件: ```html <template> <div> <cesium-map></cesium-map> </div> </template> <script> import CesiumMap from '@/components/CesiumMap.vue'; export default { components: { CesiumMap } } </script> ``` 这样,你就可以在Vue.js应用中使用Cesium来展示三维地图了。当然,你还可以根据你的需求进一步定制和扩展这个功能。希望这能帮到你!如果你有其他问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值