<el-upload ref="upload" action="#" :auto-upload="false" list-type="picture-card" :http-request="uploadFile" accept="image/png, image/jpeg" multiple :limit="9">
<i class="el-icon-plus"></i>
</el-upload>
<el-progress :percentage="percent" v-if="percent > 0" />
<el-button @click="submitUpload">发布</el-button>
data
data() {
return {
formData: {},
percent: 0,
}
}
methods
uploadFile(file) {
this.formData.append("image[]", file.file);
console.log(file, "0000000");
},
async submitUpload() {
this.formData = new FormData();
this.$refs.upload.submit();
const res = await CheckUpload(this.formData, this.onProcess);
console.log(res.data);
if (res.status !== 200) {
return this.$message.error("发布失败!");
}
this.$refs.upload.clearFiles();
this.$message.success("发布成功!");
setTimeout(() => {
this.percent = 0;
}, 700);
},
onProcess(e) {
const { loaded, total } = e;
const uploadPrecent = ((loaded / total) * 100) | 0;
console.log(uploadPrecent);
this.percent = uploadPrecent;
},
封装上传api
export const CheckUpload = (formData, callback1) => {
return request({
url: "index/upload",
method: "POST",
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: function (progressEvent) {
if (progressEvent.lengthComputable) {
callback1(progressEvent);
}
},
})
}

完整代码
<template>
<Init>
<div class="title">
<div id="size-select">设备状态分布看板</div>
<el-button @click.prevent.stop="guide" class="el-icon-s-opportunity" type="text"></el-button>
<span id="hamburger-container">当前所有部门的设备状态分布情况</span>
<span style="margin-left: 200px">
<el-popover placement="bottom" width="800" trigger="click">
<div class="top">
<el-form :inline="true" :model="params" label-width="120px" class="formtop">
<div class="side">
<el-form-item>
<el-select v-model="params.large_code" placeholder="请选择设备大类" size="small" clearable>
<el-option v-for="item in $store.state.publicInterface.category" :label="item.title" :value="item.code" />
</el-select>
</el-form-item>
<el-form-item>
<Mytooltip :content="depart_name">
<el-cascader
@change="search_getCascader_name"
change-on-select
v-model="params.departmentId"
filterable
:options="departArray"
ref="cascader"
placeholder="请选择部门"
clearable
:props="optionProps"
size="small"
>
<template slot-scope="{ node, data }">
<span>{{ data.title }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</Mytooltip>
</el-form-item>
<el-form-item>
<el-select
v-model="params.duty_man"
filterable
remote
clearable
placeholder="责任人"
:remote-method="remoteMethod"
:loading="selecloading"
size="small"
>
<el-option v-for="item in options" :key="item.value" :label="item.name" :value="item.name"> </el-option>
</el-select>
</el-form-item>
<el-button @click="handle_filter" type="primary">筛选</el-button>
</div>
</el-form>
</div>
<el-button id="breadcrumb-container" slot="reference" class="el-icon-coin" type="text">筛选</el-button>
</el-popover>
</span>
</div>
<div class="overflow">
<div class="content">
<div class="left" id="header-search">
<div id="echarts"></div>
</div>
<div id="screenfull" class="right">
<div class="item" v-for="(item, index) in matter" :key="index">
<div class="matter">{{ item.title }}</div>
<div class="num" :class="'num_color' + (index + 1)"><countTo :startVal="startVal" :endVal="item.value" :duration="2000" :decimals="0" /></div>
</div>
</div>
</div>
</div>
<el-upload ref="upload" action="#" :auto-upload="false" list-type="picture-card" :http-request="uploadFile" accept="image/png, image/jpeg" multiple :limit="9">
<i class="el-icon-plus"></i>
</el-upload>
<el-progress :percentage="percent" v-if="percent > 0" />
<el-button @click="submitUpload">发布</el-button>
</Init>
</template>
<script>
import * as echarts from "echarts";
import { get_BulletinBoard } from "@/api/dashboard";
import { bulletinBoard, Echarts_bulletinBoard } from "./utils/mapping";
import { CheckUpload, getDepart, getAllPerson } from "@/api/publicInterface.js";
import countTo from "vue-count-to";
import Driver from "driver.js";
import "driver.js/dist/driver.min.css";
import steps from "./steps";
export default {
name: "dashboard",
components: {
countTo,
},
data() {
return {
formData: {},
percent: 0,
startVal: 0,
endVal: null,
matter: [],
normal_num: "",
abnormal_num: "",
echartsData: [],
large_category_code: "",
depart_name: "",
selecloading: false,
options: [],
departArray: [],
params: {
large_code: "",
departmentId: "",
duty_man: "",
},
optionProps: {
checkStrictly: true,
value: "id",
label: "title",
},
driver: null,
};
},
async created() {
this.init();
const { data } = await getDepart();
this.departArray = [...data];
},
mounted() {
this.driver = new Driver({ popoverClass: "driverjs-theme" });
},
watch: {
departmentId() {
if (this.$refs.cascader) {
this.$refs.cascader.dropDownVisible = false;
}
},
deep: true,
},
methods: {
uploadFile(file) {
this.formData.append("image[]", file.file);
console.log(file, "0000000");
},
async submitUpload() {
this.formData = new FormData();
this.$refs.upload.submit();
const res = await CheckUpload(this.formData, this.onProcess);
console.log(res.data);
if (res.status !== 200) {
return this.$message.error("发布失败!");
}
this.$refs.upload.clearFiles();
this.$message.success("发布成功!");
setTimeout(() => {
this.percent = 0;
}, 700);
},
onProcess(e) {
const { loaded, total } = e;
const uploadPrecent = ((loaded / total) * 100) | 0;
console.log(uploadPrecent);
this.percent = uploadPrecent;
},
guide() {
this.driver.defineSteps(steps);
this.driver.start();
},
initEcharts(ajaxdata) {
var myChart = echarts.init(document.getElementById("echarts"));
myChart.setOption(
{
tooltip: {
trigger: "item",
},
legend: {
bottom: "2%",
left: "center",
},
series: [
{
type: "pie",
radius: ["50%", "65%"],
center: ["50%", "43%"],
avoidLabelOverlap: false,
label: {
show: true,
position: "outside",
formatter: "{b}\n{d}%",
fontSize: 12,
fontWeight: "bolder",
},
emphasis: {
position: "outside",
formatter: "{b}\n{d}%",
label: {
show: true,
fontSize: 14,
fontWeight: "600",
},
},
data: ajaxdata,
itemStyle: {
borderRadius: 10,
borderColor: "#fff",
borderWidth: 1.5,
label: {
fontSize: 12,
fontWeight: "bolder",
},
},
},
],
},
true
);
},
async init() {
const { data } = await get_BulletinBoard(this.params);
const matter = bulletinBoard(data);
this.matter = [...matter];
this.$nextTick(() => {
this.initEcharts(Echarts_bulletinBoard(data));
});
},
search_getCascader_name() {
this.$nextTick(() => {
this.depart_name = this.$refs.cascader.presentText;
});
},
remoteMethod(query) {
if (query !== "") {
this.selecloading = true;
this.getRemote(query);
} else {
this.options = [];
}
},
getRemote: _.debounce(function (query) {
getAllPerson({
code_name: query,
})
.then((res) => {
this.selecloading = false;
this.options = res.data;
})
.catch((err) => {
this.selecloading = false;
});
}, 800),
async handle_filter() {
if (this.params.departmentId && Array.isArray(this.params.departmentId)) {
this.params.departmentId = this.params.departmentId.join(",");
}
this.params.page = 1;
this.init();
},
},
};
</script>
<style lang="scss" scoped>
.title {
div {
font-size: 20px;
font-weight: 500;
margin-bottom: 7px;
}
span {
color: #888;
font-size: 15px;
}
}
.overflow {
overflow: auto;
.content {
margin-top: 20px;
height: 420px;
border-radius: 15px;
display: flex;
min-width: 1280px;
.left {
width: 600px;
background-color: #fff;
border-radius: 15px;
display: flex;
flex-direction: column;
margin-right: 12px;
#echarts {
height: 420px;
border-radius: 15px;
display: flex;
justify-content: center;
align-items: center;
}
}
.right {
border-radius: 15px;
display: grid;
width: 100%;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(100px, auto);
grid-column-gap: 20px;
grid-row-gap: 20px;
.item {
border-radius: 15px;
height: 200.5px;
background-color: #fff;
display: flex;
justify-content: start;
flex-direction: column;
align-items: center;
.matter {
font-size: 15px;
color: #888;
padding: 30px 0 40px 0;
}
.green-border {
border: 1px solid yellowgreen;
color: yellowgreen;
}
.red-border {
border: 1px solid red;
color: red;
}
.num_color1,
.num_color2,
.num_color3,
.num_color4,
.num_color5,
.num_color6 {
font-size: 30px;
}
.num_color1 {
color: #93d2f3;
}
.num_color2 {
color: green;
}
.num_color3 {
color: red;
}
.num_color4 {
color: #bd3124;
}
.num_color5 {
color: #fcca00;
}
.num_color6 {
color: #737373;
}
}
}
}
}
.driver-popover.driverjs-theme {
background-color: #fde047;
color: #000;
}
.driver-popover.driverjs-theme .driver-popover-title {
font-size: 20px;
}
.driver-popover.driverjs-theme .driver-popover-title,
.driver-popover.driverjs-theme .driver-popover-description,
.driver-popover.driverjs-theme .driver-popover-progress-text {
color: #000;
}
.driver-popover.driverjs-theme button {
flex: 1;
text-align: center;
background-color: #000;
color: #ffffff;
border: 2px solid #000;
text-shadow: none;
font-size: 14px;
padding: 5px 8px;
border-radius: 6px;
}
.driver-popover.driverjs-theme button:hover {
background-color: #000;
color: #ffffff;
}
.driver-popover.driverjs-theme .driver-popover-navigation-btns {
justify-content: space-between;
gap: 3px;
}
.driver-popover.driverjs-theme .driver-popover-close-btn {
color: #9b9b9b;
}
.driver-popover.driverjs-theme .driver-popover-close-btn:hover {
color: #000;
}
.driver-popover.driverjs-theme .driver-popover-arrow-side-left.driver-popover-arrow {
border-left-color: #fde047;
}
.driver-popover.driverjs-theme .driver-popover-arrow-side-right.driver-popover-arrow {
border-right-color: #fde047;
}
.driver-popover.driverjs-theme .driver-popover-arrow-side-top.driver-popover-arrow {
border-top-color: #fde047;
}
.driver-popover.driverjs-theme .driver-popover-arrow-side-bottom.driver-popover-arrow {
border-bottom-color: #fde047;
}
</style>
<style lang="scss" scoped>
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
row-gap: 1em;
height: 100vh;
margin: 0;
}
.btn {
--background: mediumseagreen;
width: 10em;
padding: 0.5em 0.7em;
cursor: pointer;
background: var(--background);
color: #fff;
border: 0;
border-radius: 30px;
transition: all 0.3s;
}
.btn:focus {
outline: var(--background) solid 1px;
}
.btn:active {
outline-offset: 1px;
outline-width: 4px;
}
.btn:hover {
--background: #24864f;
}
::v-deep .el-upload--picture-card,
::v-deep .el-upload-list--picture-card .el-upload-list__item {
width: 100px !important;
height: 100px !important;
line-height: 100px;
}
</style>