# vue2+element-ui+cesium+leaflet+echarts
**Repository Path**: lw_lp/vue2Map
## Basic Information
- **Project Name**: vue2+element-ui+cesium+leaflet+echarts
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 3
- **Forks**: 0
- **Created**: 2024-03-08
- **Last Updated**: 2025-08-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# vue-cli4
## 简介
这是基于 vue-cli4 实现的开发模板,其中包含项目常用的配置及组件封装,可供快速开发使用。
技术栈:vue-cli4 + webpack4 + element-ui + echarts + axios + less + postcss-px2rem + cesium + leaflet
```js
// 安装依赖
npm install
// 本地启动
npm run dev
// 生产打包
npm run build
```
## rem 适配
具体步骤如下;
1、安装依赖
```
npm install px2rem-loader --save-dev
```
2、在 vue.config.js 进行如下配置
```js
css: {
// css预设器配置项
loaderOptions: {
postcss: {
plugins: [
require('postcss-px2rem')({
remUnit: 100
})
]
}
}
},
```
3、在 main.js 设置 html 跟字体大小
```js
function initRem() {
let cale = window.screen.availWidth > 750 ? 2 : window.screen.availWidth / 375
window.document.documentElement.style.fontSize = `${100 * cale}px`
}
window.addEventListener('resize', function() {
initRem()
})
```
## axios 请求封装
1、设置请求拦截和响应拦截
```js
const PRODUCT_URL = 'https://xxxx.com'
const MOCK_URL = 'http://xxxx.com'
let http = axios.create({
baseURL: process.env.NODE_ENV === 'production' ? PRODUCT_URL : MOCK_URL,
})
// 请求拦截器
http.interceptors.request.use(
(config) => {
// 设置token,Content-Type
var token = sessionStorage.getItem('token')
config.headers['token'] = token
config.headers['Content-Type'] = 'application/json;charset=UTF-8'
// 请求显示loading效果
if (config.loading === true) {
vm.$loading.show()
}
return config
},
(error) => {
vm.$loading.hide()
return Promise.reject(error)
}
)
// 响应拦截器
http.interceptors.response.use(
(res) => {
vm.$loading.hide()
// token失效,重新登录
if (res.data.code === 401) {
// 重新登录
}
return res
},
(error) => {
vm.$loading.hide()
return Promise.reject(error)
}
)
```
2、封装 get 和 post 请求方法
```js
function get(url, data, lodaing) {
return new Promise((resolve, reject) => {
http
.get(url)
.then(
(response) => {
resolve(response)
},
(err) => {
reject(err)
}
)
.catch((error) => {
reject(error)
})
})
}
function post(url, data, loading) {
return new Promise((resolve, reject) => {
http
.post(url, data, { loading: loading })
.then(
(response) => {
resolve(response)
},
(err) => {
reject(err)
}
)
.catch((error) => {
reject(error)
})
})
}
export { get, post }
```
3、把 get,post 方法挂载到 vue 实例上。
```js
// main.js
import { get, post } from './js/ajax'
Vue.prototype.$http = { get, post }
```
## 工具类函数封装
1、添加方法到 vue 实例的原型链上
```js
export default {
install (Vue, options) {
Vue.prototype.util = {
method1(val) {
...
},
method2 (val) {
...
},
}
}
```
2、在 main.js 通过 vue.use()注册
```js
import utils from './js/utils'
Vue.use(utils)
```
本文提供以下函数封装
- 日期格式化
- 时间格式化
- 城市格式化
- 压缩图片
- 图片转成 base64
## vue-router 配置
平时很多人对 vue-router 的配置可配置了 path 和 component,实现了路由跳转即可。其实 vue-router 可做的事情还有很多,比如
- 路由懒加载配置
- 改变单页面应用的 title
- 登录权限校验
- 页面缓存配置
#### 路由懒加载配置
Vue 项目中实现路由按需加载(路由懒加载)的 3 中方式:
```js
// 1、Vue异步组件技术:
{
path: '/home',
name: 'Home',
component: resolve => reqire(['../views/Home.vue'], resolve)
}
// 2、es6提案的import()
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue')
}
// 3、webpack提供的require.ensure()
{
path: '/home',
name: 'Home',
component: r => require.ensure([],() => r(require('../views/Home.vue')), 'home')
}
```
本项目采用的是第二种方式,为了后续 webpack 打包优化。
#### 改变单页面应用的 title
由于单页面应用只有一个 html,所有页面的 title 默认是不会改变的,但是我们可以才路由配置中加入相关属性,再在路由守卫中通过 js 改变页面的 title
```js
router.beforeEach((to, from, next) => {
document.title = to.meta.title
})
```
#### 登录权限校验
在应用中,通常会有以下的场景,比如商城:有些页面是不需要登录即可访问的,如首页,商品详情页等,都是用户在任何情况都能看到的;但是也有是需要登录后才能访问的,如个人中心,购物车等。此时就需要对页面访问进行控制了。
此外,像一些需要记录用户信息和登录状态的项目,也是需要做登录权限校验的,以防别有用心的人通过直接访问页面的 url 打开页面。
此时。路由守卫可以帮助我们做登录校验。具体如下:
1、配置路由的 meta 对象的 auth 属性
```js
const routes = [
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue'),
meta: { title: '首页', keepAlive: false, auth: false },
},
{
path: '/mine',
name: 'mine',
component: () => import('../views/mine.vue'),
meta: { title: '我的', keepAlive: false, auth: true },
},
]
```
2、在路由首页进行判断。当`to.meta.auth`为`true`(需要登录),且不存在登录信息缓存时,需要重定向去登录页面
```js
router.beforeEach((to, from, next) => {
document.title = to.meta.title
const userInfo = sessionStorage.getItem('userInfo') || null
if (!userInfo && to.meta.auth) {
next('/login')
} else {
next()
}
})
```
#### 页面缓存配置
项目中,总有一些页面我们是希望加载一次就缓存下来的,此时就用到 keep-alive 了。keep-alive 是 Vue 提供的一个抽象组件,用来对组件进行缓存,从而节省性能,由于是一个抽象组件,所以在 v 页面渲染完毕后不会被渲染成一个 DOM 元素。
1、通过配置路由的 meta 对象的 keepAlive 属性值来区分页面是否需要缓存
```js
const routes = [
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue'),
meta: { title: '首页', keepAlive: false, auth: false },
},
{
path: '/list',
name: 'list',
component: () => import('../views/list.vue'),
meta: { title: '列表页', keepAlive: true, auth: false },
},
]
```
2、在 app.vue 做缓存判断
```html
```
## 多环境变量配置
首先我们先来了解一下环境变量,一般情况下我们的项目会有三个环境,本地环境(development),测试环境(test),生产环境(production),我们可以在项目根目录下建三个配置环境变量的文件.env.development,.env.test,.env.production
环境变量文件中只包含环境变量的“键=值”对:
```js
NODE_ENV = 'production'
VUE_APP_ENV = 'production' // 只有VUE_APP开头的环境变量可以在项目代码中直接使用
```
除了自定义的 VUE*APP*\*变量之外,还有两个可用的变量:
- NODE_ENV : "development"、"production" 或 "test"中的一个。具体的值取决于应用运行的模式。
- BASE_URL : 和 vue.config.js 中的 publicPath 选项相符,即你的应用会部署到的基础路径。
下面开始配置我们的环境变量
1、在项目根目录中新建.env.\*
- .env.development 本地开发环境配置
```
NODE_ENV='development'
VUE_APP_ENV = 'development'
```
- env.staging 测试环境配置
```
NODE_ENV='production'
VUE_APP_ENV = 'staging'
```
- env.production 正式环境配置
```
NODE_ENV='production'
VUE_APP_ENV = 'production'
```
为了在不同环境配置更多的变量,我们在 src 文件下新建一个 config/index
```js
// 根据环境引入不同配置 process.env.NODE_ENV
const config = require('./env.' + process.env.VUE_APP_ENV)
module.exports = config
```
在同级目录下新建 env.development.js,env.test.js,env.production.js,在里面配置需要的变量。
以 env.development.js 为例
```js
module.exports = {
baseUrl: 'http://localhost:8089', // 项目地址
baseApi: 'https://www.mock.com/api', // 本地api请求地址
}
```
2、配置打包命令
package.json 里的 scripts 不同环境的打包命令
- 通过 npm run serve 启动本地
- 通过 npm run test 打包测试
- 通过 npm run build 打包正式
```js
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build",
"test": "vue-cli-service build --mode test",
}
```
## vue.config.js 配置
vue-cli3 开始,新建的脚手架都需要我们在 vue.config.js 配置我们项目的东西。主要包括
- 打包后文件输出位置
- 关闭生产环境 souecemap
- 配置 rem 转化 px
- 配置 alias 别名
- 去除生产环境 console
- 跨域代理设置
此外,还有很多属于优化打包的配置,后面会一一道来。
```js
module.exports = {
// 部署应用包时的基本URL,默认为'/'
publicPath: './',
// 将构建好的文件输出到哪里,本司要求
outputDir: 'dist/static',
// 放置生成的静态资源(js、css、img、fonts)的目录。
assetsDir: 'static',
// 指定生成的 index.html 的输出路径
indexPath: 'index.html',
// 是否使用包含运行时编译器的 Vue 构建版本。
runtimeCompiler: false,
// 默认情况下 babel-loader 会忽略所有 node_modules 中的文件。如果你想要通过 Babel 显式转译一个依赖,可以在这个选项中列出来。
transpileDependencies: [],
// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false,
// 配置css
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
sourceMap: true,
// css预设器配置项
loaderOptions: {
postcss: {
// options here will be passed to postcss-loader
plugins: [
require('postcss-px2rem')({
remUnit: 100,
}),
],
},
},
// 启用 CSS modules for all css / pre-processor files.
modules: false,
},
// 是一个函数,允许对内部的 webpack 配置进行更细粒度的修改。
chainWebpack: (config) => {
// 配置别名
config.resolve.alias
.set('@', resolve('src'))
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'))
.set('views', resolve('src/views'))
config.optimization.minimizer('terser').tap((args) => {
// 去除生产环境console
args[0].terserOptions.compress.drop_console = true
return args
})
},
// 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
parallel: require('os').cpus().length > 1,
devServer: {
host: '0.0.0.0',
port: 8088, // 端口号
https: false, // https:{type:Boolean}
open: false, // 配置自动启动浏览器 open: 'Google Chrome'-默认启动谷歌
// 配置多个代理
proxy: {
'/api': {
target: 'https://www.mock.com',
ws: true, // 代理的WebSockets
changeOrigin: true, // 允许websockets跨域
pathRewrite: {
'^/api': '',
},
},
},
},
}
```
## 基础组件封装
## webpack 可视化分析
从这里开始,我们开始进行 webpack 优化打包。首先我们来分析一下 webpack 打包性能瓶颈,找出问题所在,然后才能对症下药。此时就用到 webpack-bundle-analyzer 了。
1、安装依赖
```js
npm install webpack-bundle-analyzer -D
```
2、在 vue.config.js 配置
```js
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(new BundleAnalyzerPlugin())
}
}
```
打包后,我们可以看到这样一份依赖图
从以上的界面中,我们可以得到以下信息:
- 打包出的文件中都包含了什么,以及模块之间的依赖关系
- 每个文件的大小在总体中的占比,找出较大的文件,思考是否有替换方案,是否使用了它包含了不必要的依赖?
- 是否有重复的依赖项,对此可以如何优化?
- 每个文件的压缩后的大小。
## gZip 加速优化
所有现代浏览器都支持 gzip 压缩,启用 gzip 压缩可大幅缩减传输资源大小,从而缩短资源下载时间,减少首次白屏时间,提升用户体验。
gzip 对基于文本格式文件的压缩效果最好(如:CSS、JavaScript 和 HTML),在压缩较大文件时往往可实现高达 70-90% 的压缩率,对已经压缩过的资源(如:图片)进行 gzip 压缩处理,效果很不好。
```js
const CompressionPlugin = require('compression-webpack-plugin')
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new CompressionPlugin({
// gzip压缩配置
test: /\.js$|\.html$|\.css/, // 匹配文件名
threshold: 10240, // 对超过10kb的数据进行压缩
deleteOriginalAssets: false, // 是否删除原文件
})
)
}
}
```
## 使用 SvgIcon 组件
svg 优点:
- 图标易于实时修改,可以带动画
- 可以使用标砖的 prop 和默认值来将图标保持在一个典型的尺寸并随时按需改变他们
- 图标是内联的,所以不需要额外的 HTTP 请求
- 可以动态地使得图标可访问
通常我们项目都是使用 iconfont 阿里巴巴图标矢量库,但是操作比较麻烦,每次更新都要重新下载链接。另外我们可以使 svg-sprite-loader 实现。
1、新增 SvgIcon 组件
```vue
```
2、全局注册组件并导入 svg
```js
import SvgIcon from './SvgIcon.vue'
import Vue from 'vue'
// 注册到全局
Vue.component('svg-icon', SvgIcon)
const requireAll = (requireContext) => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req)
```
3、在 main.js 中引入
```js
import './components/icon'
```
4、配置 vue.config.js
```js
module.exports = {
chainWebpack: (config) => {
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
svgRule.exclude.add(/node_modules/)
svgRule
.test(/\.svg$/)
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
})
const imagesRule = config.module.rule('images')
imagesRule.exclude.add(resolve('src/icons'))
config.module.rule('images').test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
},
}
```
## cesium如果因为mock.js加载报错
1. 解决:找到路径:node_modules/mockjs/dist/mock.js文件,将原生XHR改为下述代码
```js
// 原生 XHR
if (!this.match) {
this.custom.xhr.send(data)
return
}
// 改为
if (!this.match) {
this.custom.xhr.responseType = this.responseType
this.custom.xhr.send(data)
return
}
```
## echarts
1. 引入
```js
import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts
```
2.调用
```js
const myChart = this.$echarts.init(document.getElementById('chart'))
myChart.setOption({ ... })
```