# vue-cesium-template
**Repository Path**: matao_2018/vue-cesium-template
## Basic Information
- **Project Name**: vue-cesium-template
- **Description**: vue+cesium 项目模板
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 8
- **Forks**: 10
- **Created**: 2020-04-01
- **Last Updated**: 2025-09-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 前端 README
> 其中,\* 表示部分为需严格遵守内容,其余为推荐内容。
>
> 该规范使用的项目模板为 : vue-cesium-template
参考文档:[腾讯代码规范](https://tgideas.qq.com/doc/frontend/spec/common/) [凹凸实验室代码规范](https://guide.aotu.io/docs/html/note.html) [Vue 官方风格指南](https://cn.vuejs.org/v2/style-guide/index.html)
#### 目录结构
```
├── public
│ ├── images // 静态图片资源
│ ├── global.config.js // 全局配置文件
├── src // 生产目录
│ ├── api // 统一暴露的服务接口
│ ├── assets // 所有静态资源文件
│ ├── CustomSource // Cesium 源码内容改造
│ ├── directive // Vue 自定义指令
│ ├── earth // cesium 方法封装
│ ├── router // 路由
│ ├── store // vuex状态管理器
│ ├── styles // 全局样式文件
│ ├── utils // 全局通用工具方法
│ │ ├── common.js // 通用的坐标转换类方法
│ │ ├── dataCenterBus.js // 全局Vue事件总线
│ │ ├── LocalStorage.js // localStorage 封装
│ │ ├── request.js // Axios 封装
│ │ ├── SocketPlugin.js // webSocket 封装
│ │ ├── sysRequest.js // 带登录的 Axios封装
│ │ ├── utils.js // 全局通用工具类方法
│ ├── views // view
│ ├── App.vue // 入口页面
│ └── main.js // 入口 加载组件 初始化等
├── ThirdParty // 第三方其它依赖
├── .browserslistrc // 浏览器兼容配置
├── .eslintignore // eslint 忽略文件配置
├── .eslintrc.js // eslint 配置项
├── babel.config.js // Babel 的配置文件
├── package-lock.json // node_modules目录下所有模块的具体来源和版本号
├── package.json // 当前项目所依赖模块的版本信息
├── README.md // 项目说明文件
├── vue.config.js // 打包配置文件
```
## 1. 项目安装及运行
> 当前项目 node 版本 14.17.1, npm 版本 6.14.13
#### 依赖包安装
> 建议采用 cnpm install, npm 安装后可能出现 报错 “Cannot find module 'imagemin-gifsicle'” ,从 node_modules 删除 image-webpack-loader 文件夹,package.json 中删除 "image-webpack-loader": "^7.0.1", 重新运行 cnpm i image-webpack-loader --save-dev 即可。
```
npm install
```
#### 运行
```
npm run serve
```
#### 打包
```
npm run build
```
#### 格式化
```
npm run lint
```
---
## 2. 代码规范及开发风格指南
### 2.1 代码风格
本项目使用 eslint+prettier 来统一代码风格,并设置为**保存文件时自动根据规则格式化**,eslint 规则采用字节跳动前端代码规范,所有规则均已添加注释
> 在 vscode 中先安装插件 eslint 和 prettier
本项目的风格指南主要是参照`vue`官方的 [风格指南](https://cn.vuejs.org/v2/style-guide/index.html)
### 2.2 文件命名规则 \*
##### Component vue 组件
所有的 Component 文件都是以**大写开头 (PascalCase)**,这也是官方所[推荐的](https://cn.vuejs.org/v2/style-guide/index.html#%E5%8D%95%E6%96%87%E4%BB%B6%E7%BB%84%E4%BB%B6%E6%96%87%E4%BB%B6%E7%9A%84%E5%A4%A7%E5%B0%8F%E5%86%99%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90)。但除了 index.vue
例子:
- `@/src/components/BaseimagePicker.vue`
##### js 文件
所有的`.js`文件都遵循**横线连接 (kebab-case)**
##### views
在`views`文件下,代表路由的`.vue`文件都使用**横线连接 (kebab-case)**,代表路由的文件夹也是使用同样的规则
例子:
- `@/src/views/earth-home/index.vue`
使用横线连接 (kebab-case)来命名`views`主要是出于以下几个考虑。
- 横线连接 (kebab-case) 也是官方推荐的命名规范之一[文档](https://cn.vuejs.org/v2/style-guide/index.html#%E5%8D%95%E6%96%87%E4%BB%B6%E7%BB%84%E4%BB%B6%E6%96%87%E4%BB%B6%E7%9A%84%E5%A4%A7%E5%B0%8F%E5%86%99-%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90)
- `views`下的`.vue`文件代表的是一个路由,所以它需要和`component`进行区分(component 都是大写开头)
- 页面的 url 也都是横线连接的,比如 http://localhost:8181/#/earth-home,所以路由对应的 view 应该要保持统一
- 没有大小写敏感问题
---
### 2.3 CSS 样式
1. 本项目使用 Scss, styles/varibles.scss 中是全局样式的声明,在组件中,全部使用 scoped \*,避免样式污染,需要修改 element 样式部分可使用 /deep/ 或者 >>> 深度作用选择器,或者在组件中新增没有 scoped 的 style 代码块,外层使用类名包裹
**样式穿透**
- less 使用 **/deep/**
```
复制代码
```
- scss 使用 **::v-deep**
```
复制代码
```
- stylus 使用 **>>>**
```
```
2. 通用样式封装:
在 styles/public.scss 进行相关通用样式封装,包含 通用 element 样式、scss 变量、样式@mixin 封装。例如:
```css
//自定义滚动条样式
@mixin scrollbar-custom {
overflow-y: scroll;
&::-webkit-scrollbar {
/*滚动条整体样式*/
width: 4px; /*高宽分别对应横竖滚动条的尺寸*/
height: 15px;
}
&::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 5px;
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background-color: rgba(63, 214, 235, 0.5);
scrollbar-arrow-color: red;
}
&::-webkit-scrollbar-track {
/*滚动条里面轨道*/
border-radius: 10px;
background: transparent;
}
}
```
3. **className 命名规则 \***
我们采用 BEM 思想的变种方式,即:
BEM 也就是块(block)、元素(element)、修饰符(modifier),block 表示一个模块修饰符,如 header。element 表示元素如 item 或者 li、img 这样的元素。modifier 表示修饰符 如 current 、active 这样的状态或者 它具体对应的样式 如 border、bg、color 等。
我们采用三者用下滑线连接的方式表示类,如:**.menu_item_active** , 也可以只用两个单词连接, 如 **.table_border** 或者 **.li_item** 。也可以直接使用 状态类的修饰词 直接做为类名, 如 **.active** 、 **.checked**,这类额外注意不要放在全局导致样式冲突。
> class 一些常用的修饰词
>
> - 布局类:header, footer, container, main, content, aside, page, section
> - 包裹类:wrap, inner
> - 区块类:region, block, box
> - 结构类:hd, bd, ft, top, bottom, left, right, middle, col, row, grid, span
> - 列表类:list, item, field
> - 主次类:primary, secondary, sub, minor
> - 大小类:s, m, l, xl, large, small
> - 状态类:active, current, checked, hover, fail, success, warn, error, on, off
> - 导航类:nav, prev, next, breadcrumb, forward, back, indicator, paging, first, last
> - 交互类:tips, alert, modal, pop, panel, tabs, accordion, slide, scroll, overlay,
> - 星级类:rate, star
> - 分割类:group, seperate, divider
> - 等分类:full, half, third, quarter
> - 表格类:table, tr, td, cell, row
> - 图片类:img, thumbnail, original, album, gallery
> - 语言类:cn, en
> - 论坛类:forum, bbs, topic, post
> - 方向类:up, down, left, right
> - 其他语义类:btn, close, ok, cancel, switch; link, title, info, intro, more, icon; form, label, search, contact, phone, date, email, user; view, loading...
### 2.4 注释规范
#### 2.4.1 单行注释 \*
一般用于简单的描述,如某些状态描述、属性描述等
注释内容前后各一个空格字符,注释位于要注释代码的上面,单独占一行
_推荐:_
```
...
```
_不推荐:_
```
...
...
```
#### 2.4.2 模块注释 \*
一般用于描述模块的名称以及模块开始与结束的位置
注释内容前后各一个空格字符,`` 表示模块开始,`` 表示模块结束,模块与模块之间相隔一行
_推荐写法:_
```
...
...
```
_不推荐写法:_
```
...
...
```
#### 2.4.3 嵌套模块注释
当模块注释内再出现模块注释的时候,为了突出主要模块,嵌套模块不再使用
```
```
而改用
```
```
注释写在模块结尾标签底部,单独一行。
```
```
#### 2.4.4 函数/方法注释 \*
> vscode 中可使用插件 **koroFileHeader**, ctrl+alt+i 生成 文件头部注释,ctrl+alt+t 生成方法注释
**[强制] 函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识。**
解释:
当 `return` 关键字仅作退出函数/方法使用时,无须对返回值作注释标识。
**[强制] 参数和返回值注释必须包含类型信息,且不允许省略参数的说明。**
**[建议] 当函数是内部函数,外部不可访问时,可以使用 `@inner` 标识。**
示例:
```
/**
* 函数描述
*
* @param {string} p1 参数1的说明
* @param {string} p2 参数2的说明,比较长
* 那就换行了.
* @param {number=} p3 参数3的说明(可选)
* @return {Object} 返回值描述
*/
function foo(p1, p2, p3) {
var p3 = p3 || 10;
return {
p1: p1,
p2: p2,
p3: p3
};
}
```
**[强制] 对 Object 中各项的描述, 必须使用 `@param` 标识。**
示例:
```
/**
* 函数描述
*
* @param {Object} option 参数描述
* @param {string} option.url option项描述
* @param {string=} option.method option项描述,可选参数
*/
function foo(option) {
// TODO
}
```
#### 2.4.5 文件注释
参照:
```js
/*
* @Author: mat
* @Date: 2021-03-29 07:57:37
* @LastEditTime: 2021-04-14 14:23:47
* @Description: Cesium 相关工具方法,包含坐标转换、定位等
*/
```
2.4.6 复杂对象注释
参照:
```js
/**
* 服务器
*
* @typedef {Object} namespaceA~Server
* @property {string} host 主机
* @property {number} port 端口
*/
```
### 2.5 Vue 项目中的代码规范
1. v-for 设置 key 值 \*
2. 避免 v-if 和 v-for 用一起 \*
3. 组件使用方式 \*
```vue
```
4. props 的定义尽量详尽, 例如类型、必填项、默认值、校验规则 \*
```js
props: {
status: {
type: String,
required: true,
default: ''
}
}
```
5. 所有的 vue 项目,统一使用路由懒加载。例如:\*
```js
{
path: '/login',
name: 'login',
component: () => import('@/views/home/login')
},
```
6. 组件文件中必须包含 name,name 必须是由多个单词组成,并且是驼峰形式 \*
7. 页面中样式尽量写在``中,避免引起多页面样式被覆盖。 \*
8. 覆盖饿了么组件样式时,统一加上父元素 class。 \*
9. this 复制统一使用 `let that = this`。\*
10. vue 中变量定义声明用 let 或 const。\*
11. 静态资源引用使用绝对路径 , 例如:background: url('/images/weather/menu-bg.png'); \*
12. 全局公用组件及方法的引用 推荐这样:\*
```js
import { addIconMarker, removeAllIconMarker, addBoundInfoBox } from 'E/common'
import { getRadarImgages, getRadarPm25Images, getDataGisImg } from 'A/weather'
config.resolve.alias = {
'@': resolve('src'),
V: resolve('src/views'),
C: resolve('src/components'),
U: resolve('src/utils'),
E: resolve('src/earth'),
A: resolve('src/api'),
}
```
13. 组件选项顺序 \*
```vue
export default { name: '', mixins: [], components: {}, props: {}, data() {}, computed: {}, watch: {}, created() {}, mounted() {}, destroyed() {}, methods: {} }
```
### 2.6 其他规范:
1. **职责单一 ** \*
任何时候尽量是的一个函数就做一件事情,而不是将各种逻辑全部耦合在一起,提高单个函数的复用性和可读性
每个页面都会在加载完成时进行数据的请求并展示到页面
```
created() {
this.init();
},
methods: {
// 将全部的请求行为聚合在init函数中
// 将每个请求单独拆分
init() {
this.getList1()
this.getList2()
},
getList1() {
// to do ...
},
getList2() {
// to do ...
}
}
```
2. **策略模式** \*
策略模式的使用,避免过多的`if else`判断,也可以替代简单逻辑的`switch`
```
const formatDemandItemType = (value) => {
switch (value) {
case 1:
return '基础'
case 2:
return '高级'
case 3:
return 'VIP'
}
}
// 策略模式
const formatDemandItemType2 = (value) => {
const obj = {
1: '基础',
2: '高级',
3: 'VIP',
}
return obj[value]
}
```
## 3. 请求封装 \*
本项目在 **utils/request.js** 中对 **axios** 进行简单封装,在 api 文件夹下对各个模块的接口进行单独声明,在组件中使用时先引入
```
import {dbfslInfo, dbfslEntity} from '@/api/fsjc.js'
```
后使用
```
dbfslInfo().then(res => {
console.log(res)
})
```
如项目中有登录,需要在请求时在请求头添加 token 的,可参考如下封装
```
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
if (store.getters.token) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
config.headers['X-Token'] = getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 20000) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// to re-login
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
confirmButtonText: 'Re-Login',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
```
> 建议: view 中组件的结构可自行组织,建议将可共用的组件放在 components,类似像 BaseimagePicker.vue (底图选择组件)
## 4.Cesium 相关 \*
项目中 考虑 代码结构的低耦合性及复用性,将**Cesium**相关代码 统一在**earth**文件夹下,其中
- **index.js** 包含**cesium** 初始化相关方法
> 初始化、基本数据加载调用、全局事件声明,在 cesium 初始化组件中调用
- **utils.js** 包含**Cesium** 相关工具方法,包含坐标转换、定位等
> 世界坐标、地理坐标、屏幕坐标相互转换,弧度计算,距离计算,定位,WGS84、GCj02 坐标转换,获取视角对应层级,获取中心点坐标,度分秒转换 等相关方法
- **common.js** 包含**Cesium** 相关公用方法封装
> 图标、文字、模型、扫描波、风场、线、原生 entity、自定义信息框、geojson 等数据加载、聚合等相关方法
- **tool 文件夹** 中包含 其余工具类方法: 淹没分析、坡度坡向分析、罗盘 等
- 其余业务相关代码 在 earth 文件夹中新建对应文件夹

## 5. 项目相关的地址配置、地图服务配置放在 global.config.js 中
> 放弃环境变量的方式存储 是因为打包后无法做地址修改,得重新打包。放弃 json 文件配置是因为 json 中不方便书写注释。