業務上有共性的功能模塊,可以提煉爲單獨的組件,用的時候只需要聲明和引入即可。
組件代碼
<template>
<div class="el-form-item el-form-item--mini">
<el-form-item
:prop="areaItemName.areaProvince"
:label="title"
class="inline-item city">
<el-select
v-model.number="areaForm.areaProvince"
:loading="cityLoading"
@change="cityChange"
placeholder="請選擇"
clearable
:style="{ width: itemCfg.inputWidth }">
<el-option
v-for="cty in cityList"
:key="cty.prcName"
:label="cty.prcName"
:value="cty.prcId">
<template v-if="cityLoading" slot="prefix">
<i class="el-icon-loading"></i>
</template>
</el-option>
</el-select>
</el-form-item>
<el-form-item
:prop="areaItemName.areaCity"
label-width="20px"
class="inline-item street">
<el-select
v-model.number="areaForm.areaCity"
:loading="streetLoading"
@change="streetChange"
placeholder="請選擇"
clearable
:style="{ width: itemCfg.inputWidth }">
<el-option
v-for="cty in streetList"
:key="cty.prcName"
:label="cty.prcName"
:value="cty.prcId">
<template v-if="streetLoading" slot="prefix">
<i class="el-icon-loading"></i>
</template>
</el-option>
</el-select>
</el-form-item>
<el-form-item
:prop="areaItemName.areaArea"
label-width="20px"
class="inline-item village">
<el-select
v-model.number="areaForm.areaArea"
:loading="villageLoading"
placeholder="請選擇"
clearable
:style="{ width: itemCfg.inputWidth }">
<el-option
v-for="cty in villageList"
:key="cty.prcName"
:label="cty.prcName"
:value="cty.prcId">
</el-option>
<template v-if="villageLoading" slot="prefix">
<i class="el-icon-loading"></i>
</template>
</el-select>
</el-form-item>
</div>
</template>
<script>
import {getProvinces} from "@/api/common.js";
import {getChildrenOfProvincial} from "@/api/common.js";
export default {
name: "City",
props: {
title: String,
areaForm: {
type: Object,
default: () => {
return {
areaProvince: "",
areaCity: "",
areaArea: "",
};
}
},
itemCfg: {//基礎配置
type: Object,
default: () => {
return {
inputWidth: "110px",//默認input寬度
labelWidth: "" //label寬度
};
}
},
// 配置字段名稱
areaItemName: {
type: Object,
default: () => {
return {
areaProvince: "areaProvince",
areaCity: "areaCity",
areaArea: "areaArea",
};
}
}
},
computed: {},
created() {
this.resetFormItemVal();
getProvinces().then(res => {
this.cityList = res.data;
this.cityLoading = false;
});
;
},
data() {
return {
cityLoading: false,
streetLoading: false,
villageLoading: false,
cityList: [],
streetList: [],
villageList: []
};
},
methods: {
toNum(val) {
if (val && !isNaN(val)) {
return Number(val);
} else {
return "";
}
},
resetFormItemVal() {
this.areaForm.areaProvince = this.toNum(this.areaForm.areaProvince);
this.areaForm.areaCity = this.toNum(this.areaForm.areaCity);
this.areaForm.areaArea = this.toNum(this.areaForm.areaArea);
},
async cityChange(data) {
try {
this.streetLoading = true;
this.villageList = this.streetList = [];
this.areaForm.areaArea = this.areaForm.areaCity = null;
this.streetLoading = false;
if (!data || data === '') {
this.streetLoading = false;
return;
}
getChildrenOfProvincial({"type": 1, "parentId": data, "sign": "asdasda"}).then(res => {
this.streetList = res.data;
this.streetLoading = false;
});
} catch (error) {
this.streetLoading = false;
}
},
async streetChange(data) {
try {
this.villageLoading = true;
this.villageList = [];
this.areaForm.areaArea = null;
this.villageLoading = false;
if (!data || data === '') {
this.villageLoading = false;
return;
}
getChildrenOfProvincial({"type": 1, "parentId": data, "sign": "asdasda"}).then(res => {
this.villageList = res.data;
this.villageLoading = false;
});
} catch (error) {
this.villageLoading = false;
}
},
}
};
</script>
common.js
import request from "@/utils/request";
export function getArea(data) {
return request({
url: "/api/company/findCompanyList",
method: "post",
data
});
}
export function getProvinces() {
return request({
url: "/api/company/findProvinces",
method: "post"
});
}
export function getChildrenOfProvincial(data) {
return request({
url: "/api/company/findChildrenOfProvincial",
method: "post",
data
});
}
let subFormFields = ["cityCompanyId", "branchCompanyId", "serviceCenterId", "areaArea", "areaCity", "areaProvince"];
/**
* 封裝組件form參數字段
* @param postData
* @param areaCondition
* @param cityCondition
* @returns {*}
*/
export function initForm(postData, area, city) {
let areaCondition, cityCondition;
if (area) {
areaCondition = area.areaForm;
}
if (city)
cityCondition = city.areaForm
if (postData)
for (let i = 0; i < subFormFields.length; i++) {
delete postData[subFormFields[i]];
}
if (areaCondition)
for (var key in areaCondition) {
if (areaCondition[key])
postData[key] = areaCondition[key];
}
if (cityCondition)
for (key in cityCondition) {
if (cityCondition[key])
postData[key] = cityCondition[key];
}
return postData
}
request.js
import axios from "axios";
import store from "@/store";
import {Message, MessageBox} from "element-ui";
var Base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function (e) {
var t = "";
var n, r, i, s, o, u, a;
var f = 0;
e = Base64._utf8_encode(e);
while (f < e.length) {
n = e.charCodeAt(f++);
r = e.charCodeAt(f++);
i = e.charCodeAt(f++);
s = n >> 2;
o = (n & 3) << 4 | r >> 4;
u = (r & 15) << 2 | i >> 6;
a = i & 63;
if (isNaN(r)) {
u = a = 64
} else if (isNaN(i)) {
a = 64
}
t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
}
return t
},
_utf8_encode: function (e) {
e = e.replace(/rn/g, "n");
var t = "";
for (var n = 0; n < e.length; n++) {
var r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r)
} else if (r > 127 && r < 2048) {
t += String.fromCharCode(r >> 6 | 192);
t += String.fromCharCode(r & 63 | 128)
} else {
t += String.fromCharCode(r >> 12 | 224);
t += String.fromCharCode(r >> 6 & 63 | 128);
t += String.fromCharCode(r & 63 | 128)
}
}
return t
}
}
var Convert = {
convert: function (data) {
var userInfo = {};
if (data) {
data = eval("(" + data + ")")
userInfo["userId"] = data["global_user_id"];
userInfo["displayName"] = data["display_name"];
userInfo["loginName"] = data["login_name"];
}
return JSON.stringify(userInfo);
}
}
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
// crossDomain: true,
timeout: 60000,// request timeout
headers: {
"uInfo": Base64.encode(!localStorage ? "{}" : Convert.convert(localStorage.getItem("uInfo")))
} //用戶json信息
});
service.interceptors.response.use(
response => {
const res = response.data;
// if the custom code is not 20000, it is judged as an error.
if (res.result !== 0) {
Message({
message: res.message || "Error",
type: "error",
duration: 5 * 1000
});
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.result === 50008 || res.result === 50012 || res.result === 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);
Message({
message: error.message,
type: "error",
duration: 5 * 1000
});
return Promise.reject(error);
}
);
export default service;
表單引用
<el-form :inline="true" :model="query" class="demo-form-inline">
<City title="省市區" ref="city"></City>
.....
<el-form-item>
<el-button type="primary" @click="loadData">查詢</el-button>
</el-form-item>
</el-form>
<script>
import City from "@/components/City.vue";
export default {
name: "userList",
components: {City},
loadData() {
this.tbLoading = true;
let postData = this.query;
postData.currentPage = this.currentPage;
postData.pageSize = this.pageSize;
postData = initForm(postData,this.$refs.city)
searchData(postData)
.then(res => {
.....
})
.finally(() => {
this.tbLoading = false;
});
},