# 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({ ... }) ```