├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── antdUse.js ├── api │ └── report.js ├── app.less ├── assets │ └── logo.png ├── components │ ├── batchInput │ │ └── index.vue │ ├── c-menu │ │ └── index.vue │ ├── c-modal │ │ └── index.vue │ ├── c-table │ │ └── index.vue │ ├── editModel │ │ └── index.vue │ ├── largeSelect │ │ └── index.vue │ ├── largeTable │ │ └── index.vue │ └── searchModel │ │ └── index.vue ├── layouts │ ├── basicLayout.vue │ └── pageLayout.vue ├── main.js ├── router │ ├── README.md │ ├── index.js │ └── menu.js ├── store │ ├── index.js │ └── modules │ │ └── app.js ├── utils │ ├── exportExcel.js │ ├── request.js │ └── util.js └── views │ ├── login.vue │ ├── report.vue │ ├── role.vue │ └── user.vue ├── vue.config.js ├── 便签.html ├── 安装记录.html └── 涉及的vue3.0的升级.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-cli3 一个vue3.0的自定义脚手架 2 | 3 | ### 包含 路由懒加载、vuex、axios及其token校验、菜单及按钮级权限控制、开发环境服务转发配置、公共组件库、 4 | ### 登录登出、antd、less全局文件配置 等功能 5 | 6 | ### 目录结构 7 | dist 打包后文件 8 | public 静态文件 9 | src 根目录 10 | --api 接口 11 | --assets 图片、字体、文件等资源 12 | --components 公共组件 13 | --constants 公共常量 14 | --layouts 布局 15 | --router 路由 16 | --store vuex 17 | --utils 公共方法 18 | --views 页面 19 | package.json 包配置文件 20 | vue.config.js 开发环境服务配置文件 -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ], 5 | plugins: [ 6 | ["import", { "libraryName": "ant-design-vue", "libraryDirectory": "es", "style": true }], 7 | "@vue/babel-plugin-jsx" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-vue3", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "@ant-design/icons-vue": "^6.0.1", 12 | "ant-design-vue": "^2.2.8", 13 | "axios": "^0.24.0", 14 | "core-js": "^3.6.5", 15 | "dayjs": "^1.10.7", 16 | "less": "^4.1.2", 17 | "less-loader": "^4.1.0", 18 | "moment": "^2.29.1", 19 | "vue": "^3.0.0", 20 | "vue-router": "^4.0.12", 21 | "vuex": "^4.0.2", 22 | "xlsx": "^0.17.3" 23 | }, 24 | "devDependencies": { 25 | "@vue/cli-plugin-babel": "~4.5.0", 26 | "@vue/cli-plugin-eslint": "~4.5.0", 27 | "@vue/cli-service": "~4.5.0", 28 | "@vue/compiler-sfc": "^3.0.0", 29 | "babel-eslint": "^10.1.0", 30 | "babel-plugin-import": "^1.13.3", 31 | "eslint": "^6.7.2", 32 | "eslint-plugin-vue": "^7.0.0", 33 | "style-resources-loader": "^1.4.1", 34 | "vue-cli-plugin-style-resources-loader": "^0.1.5" 35 | }, 36 | "eslintConfig": { 37 | "root": true, 38 | "env": { 39 | "node": true 40 | }, 41 | "extends": [ 42 | "plugin:vue/vue3-essential", 43 | "eslint:recommended" 44 | ], 45 | "parserOptions": { 46 | "parser": "babel-eslint" 47 | }, 48 | "rules": {} 49 | }, 50 | "browserslist": [ 51 | "> 1%", 52 | "last 2 versions", 53 | "not dead" 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aaron-China/vue-cli3/b4b813ee36a90ed81be7e1c008592749d962d9b1/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 22 | 23 | 65 | -------------------------------------------------------------------------------- /src/antdUse.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /** 3 | * 按需加载需要的antd组件 4 | */ 5 | import { 6 | Layout, 7 | Avatar, 8 | Input, 9 | InputNumber, 10 | Button, 11 | Radio, 12 | Checkbox, 13 | Select, 14 | Form, 15 | Row, 16 | Col, 17 | Modal, 18 | Table, 19 | Tabs, 20 | Dropdown, 21 | Breadcrumb, 22 | Spin, 23 | Menu, 24 | Drawer, 25 | Tooltip, 26 | Tag, 27 | Divider, 28 | DatePicker, 29 | TimePicker, 30 | Upload, 31 | Popconfirm, 32 | message, 33 | notification, 34 | configProvider, 35 | } from "ant-design-vue"; 36 | 37 | const antdUse = (app) => { 38 | app.use(Layout); 39 | app.use(Avatar); 40 | app.use(Input); 41 | app.use(InputNumber); 42 | app.use(Button); 43 | app.use(Radio); 44 | app.use(Checkbox); 45 | app.use(Select); 46 | app.use(Form); 47 | app.use(Row); 48 | app.use(Col); 49 | app.use(Modal); 50 | app.use(Table); 51 | app.use(Tabs); 52 | app.use(Dropdown); 53 | app.use(Breadcrumb); 54 | app.use(Spin); 55 | app.use(Menu); 56 | app.use(Drawer); 57 | app.use(Tooltip); 58 | app.use(Tag); 59 | app.use(Divider); 60 | app.use(DatePicker); 61 | app.use(TimePicker); 62 | app.use(Upload); 63 | app.use(Popconfirm); 64 | app.use(configProvider); 65 | 66 | app.config.globalProperties.$message = message; 67 | app.config.globalProperties.$notification = notification; 68 | }; 69 | 70 | export default antdUse; 71 | -------------------------------------------------------------------------------- /src/api/report.js: -------------------------------------------------------------------------------- 1 | import { axios } from '@/utils/request' 2 | 3 | export function getList (d) { 4 | // return axios({ 5 | // url: `/report`, 6 | // method: 'post', 7 | // data: d 8 | // }) 9 | return new Promise(function(resolve, reject) { 10 | let list = [ 11 | {id: 1, factoryNo: '001', factoryName: '华为', materialCode: '3Z668A', materialName: '钣金门', bomLevel: 2, version: 'N167', qty: 30}, 12 | {id: 2, factoryNo: '002', factoryName: '谷歌', materialCode: '3Z228A', materialName: '玻璃门', bomLevel: 3, version: 'N167', qty: 150}, 13 | {id: 3, factoryNo: '001', factoryName: '华为', materialCode: 'WS2452', materialName: '钣金门2', bomLevel: 1, version: 'N167', qty: 230}, 14 | {id: 4, factoryNo: '002', factoryName: '谷歌', materialCode: '2Z838A', materialName: '散热器', bomLevel: 2, version: 'N167', qty: 76}, 15 | {id: 5, factoryNo: '003', factoryName: '中芯国际', materialCode: 'QJ8623', materialName: '小J骨架', bomLevel: 2, version: 'N167', qty: 99}, 16 | {id: 6, factoryNo: '004', factoryName: '宁德时代', materialCode: '255FE3', materialName: '小J面板', bomLevel: 1, version: 'N167', qty: 30}, 17 | {id: 7, factoryNo: '004', factoryName: '宁德时代', materialCode: '90JY65', materialName: '支撑臂', bomLevel: 2, version: 'N167', qty: 52}, 18 | {id: 8, factoryNo: '001', factoryName: '华为', materialCode: '74GER4', materialName: '冷凝器', bomLevel: 3, version: 'N167', qty: 16}, 19 | ]; 20 | if(d.factoryNo) { 21 | list = list.filter(item => item.factoryNo === d.factoryNo) 22 | } 23 | if(d.materialCode) { 24 | list = list.filter(item => item.materialCode.indexOf(d.materialCode) > -1 ) 25 | } 26 | resolve({ 27 | code: 200, 28 | records: list, 29 | current: 1, 30 | size: 20, 31 | total: 8 32 | }) 33 | }); 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/app.less: -------------------------------------------------------------------------------- 1 | @normal: #3F66E0; 2 | @edit: #00C7B8; 3 | @rest: #FBA908; 4 | @delete: #EC2424; 5 | @other: #09BCE4; 6 | @edit: #00C7B8; 7 | @active: #00f6f0; -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aaron-China/vue-cli3/b4b813ee36a90ed81be7e1c008592749d962d9b1/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/batchInput/index.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 105 | -------------------------------------------------------------------------------- /src/components/c-menu/index.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 144 | 145 | 203 | -------------------------------------------------------------------------------- /src/components/c-modal/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 64 | -------------------------------------------------------------------------------- /src/components/c-table/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 113 | 114 | 140 | -------------------------------------------------------------------------------- /src/components/editModel/index.vue: -------------------------------------------------------------------------------- 1 | 147 | 148 | 261 | 262 | 263 | -------------------------------------------------------------------------------- /src/components/largeSelect/index.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 170 | 171 | 190 | -------------------------------------------------------------------------------- /src/components/largeTable/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 209 | 210 | 259 | -------------------------------------------------------------------------------- /src/components/searchModel/index.vue: -------------------------------------------------------------------------------- 1 | 172 | 173 | 266 | 267 | 281 | -------------------------------------------------------------------------------- /src/layouts/basicLayout.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 123 | 124 | 153 | -------------------------------------------------------------------------------- /src/layouts/pageLayout.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 20 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import dayjs from 'dayjs' 3 | import App from './App.vue' 4 | import './antdUse' 5 | import router from './router' 6 | import store from './store' 7 | import antdUse from './antdUse' 8 | import 'dayjs/locale/zh-cn'; 9 | import './app.less' 10 | 11 | // 创建应用上下文 12 | const app = createApp(App) 13 | app.config.productionTip 14 | dayjs.locale('zh-cn'); 15 | // 原型上添加全局字段方式变了 16 | app.config.globalProperties.$dayjs = dayjs 17 | // 引入路由、vuex、 antd 18 | antdUse(app) 19 | app.use(router) 20 | app.use(store) 21 | 22 | // 挂载dom 23 | app.mount('#app') 24 | 25 | -------------------------------------------------------------------------------- /src/router/README.md: -------------------------------------------------------------------------------- 1 | path String url地址 2 | name String 路由标识 3 | title String 标题 4 | hidden Boolean 是否显示在菜单中, 默认false 显示 5 | meta Object 一些额外参数,比如需要多语言、描述等等,结合需求设定 6 | redirect String 重定向地址 7 | children Array 子菜单 8 | component BOM 页面 9 | 10 | ```javascript 11 | export default new Router({ 12 | mode: 'history', 13 | base: process.env.BASE_URL, 14 | scrollBehavior: () => ({ y: 0 }), 15 | routes: [ 16 | { 17 | path: '/', 18 | name: 'main', 19 | hidden: true, 20 | title: 'main', 21 | meta: { 22 | international: 'home' 23 | }, 24 | redirect: '/home', 25 | children: [ 26 | { 27 | path: '/home', 28 | name: 'home', 29 | title: '首页', 30 | meta: { 31 | international: 'home' 32 | }, 33 | // 懒加载 34 | component: () => import('@views/home.vue') 35 | }, 36 | ] 37 | } 38 | ] 39 | }) 40 | ``` 41 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router' 2 | import { ROUTE } from './menu.js' 3 | 4 | const route = createRouter({ 5 | history: createWebHistory(process.env.BASE_URL), 6 | scrollBehavior: () => ({ y: 0 }), 7 | routes: ROUTE 8 | }) 9 | 10 | export default route 11 | -------------------------------------------------------------------------------- /src/router/menu.js: -------------------------------------------------------------------------------- 1 | import BasicLayout from '@layouts/basicLayout' 2 | import PageLayout from '@layouts/pageLayout' 3 | export const ROUTE = [ 4 | { 5 | path: '/', 6 | name: 'main', 7 | redirect: '/report', 8 | component: BasicLayout, 9 | children: [ 10 | { 11 | path: '/report', 12 | name: 'report', 13 | title: '报表中心', 14 | component: () => import('@views/report.vue') 15 | }, 16 | { 17 | path: '/setting', 18 | name: 'setting', 19 | title: '配置中心', 20 | component: PageLayout, 21 | redirect: '/setting/user', 22 | children: [ 23 | { 24 | path: '/setting/user', 25 | name: 'user', 26 | title: '用户管理', 27 | component: PageLayout, 28 | redirect: '/setting/user/add', 29 | children: [ 30 | { 31 | path: '/setting/user/add', 32 | name: 'add', 33 | title: '增加', 34 | component: () => import('@views/user.vue') 35 | }, 36 | { 37 | path: '/setting/user/edit', 38 | name: 'edit', 39 | title: '修改', 40 | component: () => import('@views/user.vue') 41 | }, 42 | { 43 | path: '/setting/user/delete', 44 | name: 'delete', 45 | title: '删除', 46 | component: () => import('@views/user.vue') 47 | }, 48 | ] 49 | }, 50 | { 51 | path: '/setting/role', 52 | name: 'role', 53 | title: '角色管理', 54 | component: () => import('@views/role.vue') 55 | } 56 | ] 57 | } 58 | ] 59 | }, 60 | { 61 | path: '/login', 62 | name: 'login', 63 | title: '登陆', 64 | hidden: true, 65 | component: () => import('@views/login.vue') 66 | }, 67 | { 68 | path: '/:catchAll(.*)', 69 | redirect: '/404', 70 | hidden: true 71 | } 72 | ] 73 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import { createStore } from 'vuex' 2 | import app from './modules/app.js' 3 | 4 | const store = createStore({ 5 | modules: { 6 | app 7 | }, 8 | state: () => ({}), 9 | mutations: {}, 10 | actions: {}, 11 | getters: {} 12 | }) 13 | export default store -------------------------------------------------------------------------------- /src/store/modules/app.js: -------------------------------------------------------------------------------- 1 | const app = { 2 | namespaced: 'app', 3 | state: () => ({ 4 | token: '3mnuehn457873nberuwen', 5 | user: {}, 6 | factoryList: [ 7 | {value: '001', label: '华为'}, 8 | {value: '002', label: '谷歌'}, 9 | {value: '003', label: '中芯国际'}, 10 | {value: '004', label: '宁德时代'} 11 | ], 12 | // 所有权限. type 类型 区分菜单和按钮 path权限所在的菜单路径 key 是权限关键字,按钮才有 13 | permission: [], 14 | auth: {}, // 按钮权限 15 | }), 16 | mutations: { 17 | setToken: (state, d) => { 18 | state.token = d 19 | }, 20 | setUser: (state, d) => { 21 | state.user = d.user 22 | state.permission = d.permission 23 | state.auth = d.auth 24 | } 25 | }, 26 | actions: {} 27 | } 28 | export default app -------------------------------------------------------------------------------- /src/utils/exportExcel.js: -------------------------------------------------------------------------------- 1 | import XLSX from 'xlsx'; 2 | 3 | /* 4 | 备注:直接传入表格的 columns 和 data即可 5 | 6 | header: [{dataIndex: 'site', title: '地点'}] string Array 标题 7 | body: [{time: '3点', site: '青岛'}] object Array 数据 8 | name: '数据导出' string 文件名 9 | */ 10 | export function expoerExcel(header = [], body = [], name = '') { 11 | // 处理标题 12 | const dataSource = [], r1 = []; 13 | header.forEach(item => { 14 | r1.push(item.title) 15 | }) 16 | dataSource.push(r1) 17 | 18 | // 处理数据 19 | body.forEach(b => { 20 | let r = []; 21 | header.forEach(h => { 22 | r.push(b[h.dataIndex]) 23 | }) 24 | dataSource.push(r) 25 | }) 26 | 27 | const worksheet = XLSX.utils.aoa_to_sheet(dataSource); 28 | const new_workbook = XLSX.utils.book_new(); 29 | XLSX.utils.book_append_sheet(new_workbook, worksheet, 'sheet1'); 30 | XLSX.writeFile(new_workbook, `${name || '导出报表'}.xlsx`); 31 | } -------------------------------------------------------------------------------- /src/utils/request.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import router from '@router/index.js' 3 | import store from '@store/index.js' 4 | import notification from 'ant-design-vue/es/notification' 5 | 6 | // 创建 axios 实例 7 | const service = axios.create({ 8 | baseURL: '/', // api base_url 9 | withCredentials: true, 10 | timeout: 60000, // 超时时间:6分钟 注意和nginx配置保持一致 11 | maxBodyLength: 31457280, // 请求体最大长度 单位B,上限30MB 注意和nginx配置保持一致 12 | maxContentLength: 5242880, // 响应的最大长度,单位 B ,5MB,针对文件或者表格数据大量返回 注意和nginx配置保持一致 13 | }) 14 | 15 | const err = (error) => { 16 | if (error.response) { 17 | const data = error.response.data 18 | if (error.response.status === 401) { // 登录失效 19 | router.push({path: '/login'}) 20 | } else if (error.response.status === 402) { // 缺少权限 21 | notification.error({ 22 | message: '您没有权限查看当前信息', 23 | description: '请联系管理员获取数据权限', 24 | duration: null 25 | }) 26 | } else if (error.response.status === 403) { 27 | notification.error({ 28 | message: 'Forbidden', 29 | description: data.message 30 | }) 31 | } else if (error.response.status === 504) { // 请求超时 32 | notification.error({ 33 | message: '提示', 34 | description: '请求时间较长,请稍后查看', 35 | duration: null 36 | }); 37 | } 38 | } else { 39 | // 请求超时 40 | notification.error({ 41 | message: '提示', 42 | description: '请求时间较长,请稍后查看', 43 | duration: null 44 | }); 45 | } 46 | return Promise.reject(error) 47 | } 48 | 49 | // 请求拦截,设置token 50 | service.interceptors.request.use((config) => { 51 | config.headers['Access-Token'] = store.state.app.token || '' 52 | return config 53 | }, err) 54 | 55 | // 处理响应 56 | service.interceptors.response.use((response) => { 57 | return response.data 58 | }, err) 59 | 60 | function requests(options = {}) { 61 | return service.request({ ...options }) 62 | } 63 | 64 | export { requests as axios } 65 | -------------------------------------------------------------------------------- /src/utils/util.js: -------------------------------------------------------------------------------- 1 | // 遍历路由,获取左侧主菜单, 精简字段,并按照权限过滤 2 | export const filterMenu = (l, p) => { 3 | let arr = []; 4 | for(let i = 0; i < l.length; i++) { 5 | // 校验权限,权限存储底层路由即可,父级菜单自动通过 6 | let able = p.some(item => item.path.indexOf(l[i].path) === 0) 7 | if (!l[i].hidden && able) { 8 | let obj = {...l[i]}; 9 | delete obj.component 10 | if (l[i].children && l[i].children.length) { 11 | obj.children = filterMenu(l[i].children, p) 12 | } 13 | arr.push(obj) 14 | } 15 | } 16 | return arr 17 | } 18 | 19 | // url传参,处理参数 20 | export function makeQuery (obj = {}) { 21 | let arr = [], str = ''; 22 | for (let key in obj) { 23 | if (obj[key] || obj[key] === 0 || obj[key] === false) { 24 | arr.push(`${key}=${obj[key]}`) 25 | } 26 | } 27 | str = arr.join('&') 28 | return str ? `?${str}` : '' 29 | } 30 | 31 | // 表单自定义校验,校验长度 32 | export function checklength(_, value) { 33 | if (value) { 34 | const arr = value.split(',') 35 | if (arr.length > 500) { 36 | return Promise.reject(new Error('最大支持500条数据')); 37 | } else { 38 | return Promise.resolve(); 39 | } 40 | } else { 41 | return Promise.resolve(); 42 | } 43 | } 44 | // 表单自定义校验,校验重复性 45 | export function checkRepeat (_, value) { 46 | if (value) { 47 | const arr = value.split(',') 48 | if ((new Set(arr)).size != arr.length) { 49 | return Promise.reject(new Error('存在重复信息')); 50 | } else { 51 | return Promise.resolve(); 52 | } 53 | } else { 54 | return Promise.resolve(); 55 | } 56 | } -------------------------------------------------------------------------------- /src/views/login.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 98 | 99 | 125 | -------------------------------------------------------------------------------- /src/views/report.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 248 | 250 | -------------------------------------------------------------------------------- /src/views/role.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 100 | 101 | 103 | -------------------------------------------------------------------------------- /src/views/user.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | 20 | 22 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const webpack = require('webpack') 3 | function resolve (dir) { 4 | return path.join(__dirname, dir) 5 | } 6 | 7 | // https://cli.vuejs.org/zh/config/#css-loaderoptions 8 | module.exports = { 9 | pluginOptions: { 10 | 'style-resources-loader': { 11 | preProcessor: 'less', 12 | patterns: [path.resolve(__dirname, "src/app.less")] // 引入全局样式变量 13 | } 14 | }, 15 | css: { 16 | loaderOptions: { 17 | less: { 18 | javascriptEnabled: true 19 | } 20 | } 21 | }, 22 | chainWebpack: (config) => { 23 | config.resolve.alias 24 | .set('@', resolve('src')) 25 | .set('@api', resolve('src/api')) 26 | .set('@assets', resolve('src/assets')) 27 | .set('@layouts', resolve('src/layouts')) 28 | .set('@static', resolve('src/static')) 29 | .set('@components', resolve('src/components')) 30 | .set('@router', resolve('src/router')) 31 | .set('@utils', resolve('src/utils')) 32 | .set('@store', resolve('src/store')) 33 | .set('@views', resolve('src/views')) 34 | }, 35 | // 服务转发 36 | devServer: { 37 | port: 8003, 38 | proxy: { 39 | '/WebSocketConfig/': { 40 | target: 'ws://test.com', 41 | changeOrigin: true, 42 | ws: true, // 开启sockjs 43 | }, 44 | '/api/': { 45 | target: 'http://test.com', 46 | changeOrigin: true, 47 | ws: false, // 关闭sockjs 48 | }, 49 | }, 50 | }, 51 | 52 | // disable source map in production 53 | productionSourceMap: false, 54 | lintOnSave: false, 55 | // babel-loader no-ignore node_modules/* 56 | transpileDependencies: [], 57 | } 58 | -------------------------------------------------------------------------------- /便签.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | vue-cli地址 11 | vue-cli3地址 12 | 136 | 137 | -------------------------------------------------------------------------------- /安装记录.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 35 | 36 | -------------------------------------------------------------------------------- /涉及的vue3.0的升级.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 62 | 63 | --------------------------------------------------------------------------------