对于后台管理系统,有很多弹框的功能,这时候,我们就可以将弹框封装成一个公共组件进行复用。
1. 新建弹窗组件页
在公共组件文件夹(components)下建一个弹框组件文件夹(EditboxForm)
<template>
<div>
<transition name="slide">
<div class="editBoxFrom" v-show="editBoxFromShow">
<div class="editBox" :class="fromClassName" :style="{width:editBoxWidth}">
<slot name="closeBtn"></slot>
<!--标题-->
<div class="title">
<slot name="title"></slot>
</div>
<!--内容-->
<slot name="center"></slot>
<!--确认按钮-->
<div class="tableBtn">
<slot name="tableBtn"></slot>
</div>
</div>
</div>
</transition>
<div class="editBoxBg" v-if="editBoxFromShow">
</div>
</div>
</template>
<script>
export default {
name: 'EditboxForm',
inheritAttrs: false,
props: {
//是否显示
editBoxShow: {
type: Boolean,
default: function() {
return false
}
},
//是否有传class,默认为空
className: {
type:String,
default: function() {
return ''
}
},
widthData:{
type:Number,
default: function() {
return 360
}
},
},
data() {
return {
editBoxFromShow: this.editBoxShow,
fromClassName: this.className,
editBoxWidth:this.widthData+'px'//设置弹框的宽度
}
},
mounted() {
},
watch: {
editBoxShow(val) {
this.editBoxFromShow = val
},
className(val) {
this.fromClassName = val
},
widthData(val) {
this.editBoxWidth = val+'px'
},
}
}
</script>
<style scoped>
.editBoxBg {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 2000;
background-color: rgba(0, 0, 0, .6);
display: flex;
justify-content: center;
align-items: center;
}
.editImgBg {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 2010;
background-color: rgba(0, 0, 0, .6);
display: flex;
justify-content: center;
align-items: center;
}
/*高度不固定垂直居中*/
.editBoxFrom {
position: fixed;
z-index: 2001;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.editBox {
width: 360px;
max-height: 80%;
overflow: hidden;
overflow-y: auto;
background: #fff;
position: relative;
border: 1px solid #D7D7D7;
padding: 10px 15px;
.closeBtn {
position: absolute;
right: 10px;
top: 10px;
color: $themeColor;
height: 35px;
line-height: 35px;
cursor: pointer;
font-size: 16px;
}
.title {
border-bottom: 1px solid #D7D7D7;
font-weight: 700;
font-size: 18px;
height: 35px;
line-height: 35px;
text-align: center;
margin-bottom: 10px;
}
.el-select {
width: 100%;
}
.editBoxTable {
table-layout: fixed;
}
.editBoxTable td {
padding: 5px 0;
word-wrap: break-word;
vertical-align: middle;
}
.editBoxTable tr td:first-child {
width: 130px;
}
.tdCenter {
text-align: center;
}
.tableBtn {
border-top: 1px solid #D7D7D7;
}
}
.imgDivBg {
width: 80%;
height: 80%;
margin: 0px auto;
position: relative;
// background: #fff;
.imgDivClose {
height: 20px;
width: 20px;
text-align: center;
background: #fff;
line-height: 20px;
border-radius: 20px;
border: 1px solid $themeColor;
position: absolute;
top: -10px;
right: -10px;
cursor: pointer;
}
.imgDiv {
width: 100%;
height: 100%;
text-align: center;
}
.imgDiv img {
max-width: 100%;
max-height: 100%;
}
.imgDiv video {
// height: 100%;
// width: 100%;
}
}
.slide-enter-active {
animation-name: slideOutDown;
animation-duration: 1s;
animation-fill-mode: both;
}
.slide-leave-active {
animation-name: slideInUp;
animation-duration: 1s;
animation-fill-mode: both;
}
@keyframes slideInUp {
0% {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(-100%);
}
}
@keyframes slideOutDown {
0% {
opacity: 0;
transform: translateY(-100%);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
2.在公共组件文件夹(components)下建一个install.js文件
// 组件全局注册
import Vue from 'vue'
// 这些都是自己建的组件库
import EditboxForm from './EditboxForm'//弹框
// 组件库
const Components = [
EditboxForm,
]
// 注册全局组件
Components.map((com) =>{
Vue.component(com.name, com)
})
export default Vue
3.在main.js中引入公共组件
import './components/install'
4.在自己需要有弹窗的页面,挂载弹框(这个是我项目的整个页面,逻代码比较多,可以仔细研究一下是可以看懂的)
<template>
<div class="sys-page">
<div class="page-content">
<app-search>
<el-form
:inline="true"
:model="queryParams"
class="searchForm customerAccountManage"
>
<el-form-item>
<el-button type="primary" @click="addNotice">新增</el-button>
</el-form-item>
</el-form>
</app-search>
<table-mixin
v-loading="tableData.loading"
:pagination="pagination"
:startRow="startRow"
:endRow="endRow"
:currentPage="queryParams.pageNum"
:paginationTotal="total"
:pageSize="queryParams.pageSize"
@currentPageChange="currentPageChange"
>
<el-table :data="tableData.body" @selection-change="selectionChange" border style="width: 100%"
max-height="700">
<el-table-column
type="selection"
width="40"
align="center"
>
</el-table-column>
<el-table-column
prop="serialNo"
label="编号"
align="center"
width="100"
>
<template slot-scope="scope">
{{scope.$index+1 +(queryParams.pageNum-1)*10}}
</template>
</el-table-column>
<el-table-column
prop="createTime"
label="添加时间"
align="center"
width="220"
></el-table-column>
<el-table-column
prop="content"
label="公告内容"
align="center"
min-width="220"
>
</el-table-column>
<el-table-column
prop="state"
label="状态"
align="center"
min-width="220"
>
<template slot-scope="scope">
<div v-if="scope.row.state == 0">未上架</div>
<div v-if="scope.row.state == 1">已上架</div>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="160"
fixed="right"
>
<template slot-scope="scope">
<el-button type="text" size="large" @click="putShelf(scope.row)" v-if="scope.row.state == 0"
>上架</el-button
>
<el-button type="text" size="large" @click="offShelf(scope.row)" v-if="scope.row.state == 1"
>下架</el-button
>
<el-button type="text" size="large" @click="editNotice(scope.row)" v-if="scope.row.state == 0"
>修改</el-button
>
</template>
</el-table-column>
</el-table>
</table-mixin>
</div>
<!-- Vue动态组件, 提供了一个特殊的元素<comment>用来动态地挂载不同的组件,使用is特性来选择要挂载的组件。引入弹框组件的地方-->
<comment
:is="editboxName"
@cancel="cancel"
:propData="propData"
@saveBox="saveBox"
></comment>
</div>
</template>
<script>
import { mapState } from "vuex";
import addNotice from "./noticeMgmt/noticeCommon";
import putShelf from "../starCollectionMgmt/common/putShelf.vue";
export default {
name: "homepageNotice",
components: {
addNotice,
putShelf,
},
data() {
return {
queryParams: {
pageNum: this.common.pageNum, //当前页
pageSize: this.common.pageSize, //每页显示条数
},
total: 0, //总条数
startRow: 0,
endRow: 0,
tableData: {
loading: false,
body: [],
},
pagination: false,
editboxName: "",
propData: {},
multipleSelection: [],
setId:'',//商家id
content:''//内容修改
};
},
computed: {
...mapState({
roleType(state) {
return state.auth.roleType;
},
}),
},
mounted() {
this.getTableData();
},
methods: {
//获取所有选择的项
selectionChange(val) {
this.multipleSelection = val;
},
// 获取table数据
async getTableData() {
let queryParams = this.queryParams;
await this.$api.operateMgmt
.announcementBanner(queryParams)
.then((res) => {
if (res.code == 200) {
this.tableData.loading = false;
let resData = res.data;
this.tableData.body = resData.records;
this.total = resData.total;
if (this.total > 0) {
this.pagination = true;
} else {
this.pagination = false;
}
this.startRow = resData.startRow;
this.endRow = resData.endRow;
} else {
this.common.messageTipCode(res, "error");
}
});
},
//删除Banner
deleteBtn(row) {
console.log(row);
this.$confirm("确定要删除该活动Banner嘛, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.deleteBanner(row);
})
.catch(() => {});
},
//删除Banner接口
deleteBanner(row) {
this.$api.announcementBanner.deleteBanner({ id: row.id }).then((res) => {
let that = this;
if (res.code == 200) {
this.$message({
message: "删除banner成功",
duration: this.common.duration,
type: "success",
onClose: function () {
// window.location.reload();
that.getTableData();
},
});
} else {
this.common.messageTipCode(res, "error");
}
});
},
//首页下架
offShelf(row) {
this.$confirm("确定在首页下架该藏品嘛, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.batchsoldOut(row)
})
.catch(() => {});
},
// 首页下架接口
async batchsoldOut(row) {
let params = {
id: row.id,
state: "0",
}
console.log(params)
await this.$api.operateMgmt.standDown(params)
.then((res) => {
let that = this;
if (res.code == 200) {
this.$message({
message: "下架成功",
duration: this.common.duration,
type: "success",
onClose: function () {
//window.location.reload();
that.getTableData();
},
});
} else {
this.common.messageTipCode(res, "error");
}
});
},
//首页上架
putShelf(row) {
this.editboxName = "putShelf";
this.propData.id = row.id
this.propData.from='homepageNotice'
},
//新增通知
addNotice() {
this.propData = {
type: 1,
};
this.editboxName = "addNotice";
},
//编辑通知
editNotice(row) {
this.propData = {
type: 2,
id:row.id,
content:row.content
};
this.editboxName = "addNotice";
},
//点击查询按钮
searchTableData() {
this.queryParams.pageNum = this.common.pageNum;
this.queryParams.pageSize = this.common.pageSize;
this.tableData.loading = true;
this.getTableData();
},
//设置时间格式
dateFormatTime(row, column, cellValue, index) {
const daterc = row[column.property];
if (daterc != null) {
return this.common.formatDateTime(daterc, "yyyy-MM-dd hh:mm:ss");
}
},
//设置日期格式
dateFormat(row, column, cellValue, index) {
const daterc = row[column.property];
if (daterc != null) {
return this.common.formatDateTime(daterc, "yyyy-MM-dd");
}
},
//保存后关闭弹窗
saveBox() {
this.multipleSelection = [];
this.editboxName = "";
this.getTableData();
},
//关闭弹窗
cancel() {
let that = this;
setTimeout(function () {
that.editboxName = "";
}, that.common.durationBox);
},
//当前显示页
currentPageChange(pageNum) {
this.queryParams.pageNum = pageNum;
this.getTableData();
},
},
};
</script>
5.可以在自己所写表格页面文件夹里新建一个弹框页面。例如新增和修改弹框(这个页面根据自己所需要的弹框写的,只需要将插槽一一对应,写出自己的弹框样式即可)。
<template>
<div class="platformVerify">
<editbox-form :editBoxShow="editBoxShow">
<div slot="title" v-if='verifyData.type==2'>
编辑
</div>
<div slot="title" v-else>
添加
</div>
<div slot="center">
<table width="100%" class="editBoxTable">
<tr>
<td>
公告内容
</td>
<td>
<el-input type="textarea" :rows="2" placeholder="请输入公告内容" v-model="content">
</el-input>
</td>
</tr>
</table>
</div>
<ul slot="tableBtn">
<li @click="save(verifyData.type)" v-preventReClick="this.common.duration">
提交
</li>
<li class="cancel" @click="cancel">
取消
</li>
</ul>
</editbox-form>
</div>
</template>
<style type="text/css">
.platformVerify .editBoxBg .editBox {
width: 460px;
}
.platformVerify th {
background: #F2F2F2;
height: 40px;
line-height: 40px;
}
.platformVerify td {
text-align: center;
}
.platformVerify .first td {
text-align: left;
}
.platformVerify .editBoxTable {
margin-bottom: 10px;
}
.platformVerify .el-select .el-input__inner {
padding: 0 10px;
}
</style>
<script>
export default {
name: 'noticeCommon',
props: {
propData: {
default: function() {
return {}
}
},
},
data() {
return {
verifyData: this.propData,
editBoxShow: false,
content:'',//公告内容
}
},
mounted() {
this.editBoxShow = true
this.getcontent()
},
methods: {
getcontent(){
if(this.verifyData.type==2){
this.content=this.verifyData.content
}
},
save(type) {
if(event.target.disabled) {
if(document.getElementsByClassName('el-message--warning').length) return
this.common.messageTip("操作太频繁", 'warning');
return
} else {
if(!this.content) {
this.common.messageTip("请输入公告内容", 'error');
return
}
if(type==1){
let verifyData = {
content:this.content
}
this.$api.operateMgmt.newlyIncreased(verifyData).then(res => {
if(res.code == 200) {
let that = this
this.$message({
message: "提交成功",
duration: this.common.duration,
type: 'success',
onClose: function() {
that.$emit('saveBox')
}
});
} else {
let that = this
this.$message({
message: res.message,
duration: this.common.duration,
type: 'error',
onClose: function() {
that.$emit('saveBox')
}
});
}
})
}
if(type==2){
let verifyData = {
content:this.content,
id: this.propData.id,
}
this.$api.operateMgmt.updataIncreased(verifyData).then(res => {
if(res.code == 200) {
let that = this
this.$message({
message: "提交成功",
duration: this.common.duration,
type: 'success',
onClose: function() {
that.$emit('saveBox')
}
});
} else {
let that = this
this.$message({
message: res.message,
duration: this.common.duration,
type: 'error',
onClose: function() {
that.$emit('saveBox')
}
});
}
})
}
}
},
cancel() {
this.editBoxShow = false
this.$emit('cancel')
},
},
watch: {
propData(val) {
console.log(val,1213)
this.verifyData = val
},
}
}
</script>
这个里面也有新增和修改公用一个弹框组件的逻辑,(进行传不同的type实现的)可以研究一下。