# 概述
OA 管理系统是公司内部使用的一个管理系统,它能够能够高效,便捷的协助公司进行管理,有通讯录模块,请加模块,公告模块,任务模块,客户模块等等。通过编写 OA 管理系统,对 ElementUI 的掌握更进一步,对 Vue 框架的使用更加熟悉,且在项目中遇到的问题总结如下。
key=value&key=value import qs from "querystring"; const res = await this.$axios.post( "api/indoor/AddAdmin", qs.stringify({ ...this.addAdmin, token: this.token }) );解决跨域问题
在根目录新建 vue.config.js
module.exports = {
// cli3 代理是从指定的target后面开始匹配的,不是任意位置;配置pathRewrite可以做替换
devServer: {
port: "8080",
open: true,
proxy: {
"/api": {
// /api 的意义在于,声明axios中url已/api开头的请求都适用于该规则,
// 注意是以/api开头,即:axios.post({url: '/api/xxx/xxx'})
target: "https://oa.baixiucn.cn/",
// 此处target的意义在于:造成跨域是因为访
// 问的host与我们的请求头里的origin不一致,所以我们要设置成一致,这个具体请看下文
changeOrigin: true,
pathRewrite: { "^/api": "" },
// 此处是大部分文章都不会明说的的地方,
// 既然我们设置了代理,则所有请求url都已写成/api/xxx/xxx,那请求如何知道我们到底请求的是哪个服务器的数据呢
// 因此这里的意义在于, 以 /api开头的url请求,代理都会知道实际上应该请求那里,
// ‘我是服务器/api’,后面的/api根据实际请求地址决定,即我的请求url:/api/test/test,被代理后请求的则是
// https://我是服务器/api/test/test
},
},
},
};
上传图片问题
-
upload.js
const BASE_URL = "https://oa.baixiucn.cn/"; import axios from "axios"; export default (file) => new Promise((res) => { // 传文件必须放在 FormData 中,FormData对象会自动将这个文件处理之后发给后台 const fromData = new FormData(); // 给 fromData 添加一个属性 fromData.append("file", file); axios({ url: BASE_URL + "api/article/uploadsum1", method: "post", data: fromData, headers: { "Content-Type": "multipart/form-data", }, }) .then((_res) => { // 如果第一项(null)为真就证明失败了,第二项是我要的数据 res([null, BASE_URL + _res]); }) .catch((_err) => { res([_err, null]); }); }); -
pathJoin.js
export default (url) => { if (url.indexOf("http") !== -1) { return url; } else { return "https://oa.baixiucn.cn/" + url; } }; -
main.js
import joinUrl from "@/utils/pathJoin"; Vue.prototype.joinUrl = joinUrl; -
case.vue
<template> <div class="fileBox"> <input type="file" @change="_input" name="file" class="file" /> <img :src="blobURL || joinUrl(userinfoList.avatar)" /> </div> </template> <script> import qs from "querystring"; import upload from "@/utils/upload"; export default { name: "datiDersonali", data() { return { userinfoList: [], editUser: { nickname: "", avatar: null, password: "", email: "", }, file: null, blobURL: null, }; }, methods: { async editEvent() { let image_url_res = ""; if (this.file) { image_url_res = await upload(this.file); if (image_url_res[0]) { alert("头像上传失败,请重新上传!!!"); return; } } const res = await this.$axios.post( "api/Indoor/UpdateAdmin", qs.stringify({ ...this.editUser, token: this.userinfoList.token, avatar: image_url_res[1], }) ); }, async _input(e) { this.file = e.target.files[0]; this.blobURL = URL.createObjectURL(this.file); }, }, }; </script>
扁平化数组
arr.forEach((item) => {
this.flatArr = [...this.flatArr, ...item.data];
});
ElementUI 中 select 多选问题
看 option 中 value 绑定的是什么值,那么 select 绑定的就应该和 value 中要求的值一样
然后将请求回来的数据,修改成 select 中要求的值的类型
这个项目是使用 try_catch 解决的,也可以用其他方案解决
省市区三级联动
-
安装:npm i v-distpicker --save
-
方法:
- province 选择省份 (返回省份的值)
- city 选择城市 (返回城市的值)
- selected 选择最后一项时触发 (返回省市区的值)
-
案例
<template> <el-form-item label="地区"> <v-distpicker :province="user.xtrysf" :city="user.xtrycs" hide-area @province="onChangeProvince" @city="onChangeCity" > <-distpicker> </el-form-item> </template> <script> import vDistpicker from "v-distpicker"; export default { components: { vDistpicker }, methods: { onChangeProvince(data) { this.user.xtrysf = data.value; }, onChangeCity(data) { this.user.xtrycs = data.value; }, // 选择省市区 onSelect onSelected(data) { this.addCompanyCustomer.address.province = data.province.value; this.addCompanyCustomer.address.city = data.city.value; this.addCompanyCustomer.address.area = data.area.value; }, }, }; </script>
Tree 组件
getCheckedNodes 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点所组成的数组
getCheckedKeys 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组
this.$refs.tree.getCheckedNodes()返回目前被选中的节点所组成的数组
const a = res.data;
let arr = [];
function digui(a) {
for (let i = 0; i < a.length; i++) {
if (a[i].child.length !== 0) {
digui(a[i].child);
} else {
arr.push(a[i].id);
}
}
}
digui(a);
this.editList = arr;
图片多选问题
const BASE_URL = "https://oa.baixiucn.cn/";
import axios from "axios";
export default function urploadFile(pathArr) {
return new Promise((res) => {
let index = 0;
const resArr = [];
up(pathArr[index]);
function up(file) {
// 传文件必须放在 FormData 中,FormData对象会自动将这个文件处理之后发给后台
const fromData = new FormData();
// 给 fromData 添加一个属性
fromData.append("file", file);
axios({
url: BASE_URL + "api/article/uploadsum1",
method: "post",
data: fromData,
headers: {
"Content-Type": "multipart/form-data",
},
})
.then((_res) => {
index++;
resArr.push(_res);
if (index >= pathArr.length) {
res([0, resArr]);
return;
} else {
up(pathArr[index]);
}
})
.catch((err) => res([err, 0]));
}
});
}
打包之后的 map 文件问题
可能很多人在做vue项目打包,打包之后js中,会自动生成一些map文件,怎么把它去掉不要呢?
运行 cnpm run build 开始打包后会在项目目录下自动创建dist目录,打包好的文件都在其中
解决办法:去src/config/index.js中改一个参数:
productionSourceMap:false
把这个改为false。不然在最终打包的文件中会出现一些map文件
map文件的作用:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。
有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。
打包之后白屏问题
打包之后,会出现白屏的问题
这是因为找不到文件,需要将引用本地图片的链接改成线上的链接
路由懒加载可能会导致缺少文件的问题,将懒加载去掉换成直接引入的方式