AntDesign表格+模态框编辑+VUX
2019-12-24 本文已影响0人
叶叶阿姨
之前有说过可编辑的表格 今天我说一下不可编辑的表格
里面包含了antDesign的图片上传和编辑器等的添加和修改的方式 也包含了展示的方法等
先放表格代码 直接意会一下吧难得打字啦 偷懒一下下
<template>
<div>
<!-- 表格 -->
<a-table :columns="columns"
:dataSource="data"
:pagination="false"
rowKey="id"
bordered>
<span slot="customTitle">ID</span>
<span slot="img" slot-scope="img">
<a-card hoverable style="width: 130px; height: 100px;">
<img
style="width: 130px; height: 100px;"
alt="example"
:src="`http://192.168.110.56:8001/${img}`"
slot="cover"
/>
</a-card>
</span>
<span slot="labels" slot-scope="labels">
<a-tag v-for="label in labels" :color="'geekblue'" :key="label">{{label}}</a-tag>
</span>
<span slot="operation" slot-scope="text, record">
<a-button class="btn" type="primary" @click="showModal(record.id)">编辑</a-button>
<a-button @click="Delete(record.id)" class="btn del" type="danger">删除</a-button>
</span>
</a-table>
<!-- 编辑弹框 -->
<div>
<a-modal title="编辑" v-model="visible" :footer="null" width="40%" :destroyOnClose="true">
<NewsEditorModel :editor_data="editor_data" :id="edit_id" :offModel="offModel"/>
</a-modal>
</div>
<!-- 分页 -->
<a-pagination
:defaultCurrent="1"
:total = parseInt(this.$store.state.news.news_count)
v-model="current"
@change="onCurrent"
:pageSize="pageSize"
style="margin: 30px 0 0 0;float: right;"
/>
</div>
</template>
<script>
import { searchNews } from "@/api/news";
import NewsEditorModel from "@/components/News/NewsEditorModel";
import { dellNews } from "@/api/news";
import { newsEditor } from "@/api/news";
import { log } from 'util';
const columns = [
{
title: "ID",
dataIndex: "id",
width:"5%",
key: "id"
},
{
title: "封面图",
dataIndex: "img",
width: "12%",
key: "img",
scopedSlots: { customRender: "img" }
},
{
title: "标签",
dataIndex: "labels",
key: "labels",
width: "10%",
scopedSlots: { customRender: "labels" }
},
{
title: "标题",
dataIndex: "title",
width: "20%",
key: "title"
},
{
title: "地域",
dataIndex: "regional",
key: "regional",
width: "8%"
},
{
title: "来源",
width: "12%",
dataIndex: "source",
key: "source"
},
{
title: "浏览量",
dataIndex: "total_views",
key: "total_views",
width: "8%"
},
{
title: "创建时间",
width: "10%",
dataIndex: "time",
key: "time"
},
{
title: "操作",
scopedSlots: { customRender: "operation" }
}
];
const data = [];
export default {
data() {
return {
// 分页
// 每页条数
pageSize: 10,
// 当前页数
current: 1,
count: '',
editor_data: "",
columns,
visible: false,
target: "",
edit_id: "",
formLabelWidth: "100px"
};
},
mounted() {
// 从获取资讯表格的data
this.$store.dispatch("get_news");
},
// 注册组键
components: {
NewsEditorModel
},
methods: {
// 分页
onCurrent(current) {
this.current = current;
let param_q = new URLSearchParams();
param_q.append("page", current);
// 触发请求 请求第当前page的列表data
searchNews(param_q).then(resp => {
const data = resp.data
const count = resp.count
// 把请求到的当前page的列表data添加到vux中,以便渲染
this.$store.commit("News_DATA", {data, count})
});
},
// 编辑弹框
// async await 同步请求
async showModal(id) {
const newData = [...this.data];
const target = newData.filter(item => id === item.id)[0];
this.edit_id = target.id;
// 请求指定id的所数据
await newsEditor(id).then(resp => {
this.editor_data = resp.data;
});
this.visible = true;
},
// 编辑取消
offModel() {
this.visible = false;
},
// 删除
Delete(key) {
this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
// 删除请求
dellNews(key).then(resp => {
this.$store.dispatch("get_news");
}),
this.$message({ type: "success", message: "删除成功!" });
})
.catch(() => {
this.$message({ type: "info", message: "已取消删除" });
});
}
},
computed: {
data() {
return this.$store.getters.news_data;
}
}
};
</script>
<style lang="scss" scoped>
// 按钮公共样式
.btn {
margin-right: 15px;
display: inline-block;
color: white;
padding: 4px 15px;
border-radius: 4px;
border: none;
}
.del {
background-color: #f5222d;
}
.container {
margin: 20px 15px 0 15px;
&_filter-container {
&_botton-class {
margin: 20px 0 10px 0;
p {
/*display: inline-block;*/
right: 85px;
position: absolute;
top: 85px;
span {
color: red;
font-size: 15px;
margin: 0 5px;
}
}
}
}
}
.editable-row-operations a {
margin-right: 8px;
}
.el-select .el-input {
width: 130px;
}
.el-input__inner {
height: 30px !important;
}
</style>
在放编辑弹框里的
<template>
<div>
<a-form ref="form" :model="editor_form" label-width="100px">
<a-form-item label="文章栏目" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="editor_form.article_id" placeholder="请选择">
<a-select-option
placeholder="请选择"
v-for="(item, index) in form.article"
:key="item.index"
:title="item.article_name"
:value="item.article_id"
>{{ item.article_name}}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="细分领域" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="editor_form.niche_id" placeholder="请选择">
<a-select-option
v-for="(item, index) in form.niche"
:key="item.index"
:title="item.niche_name"
:value="item.niche_id"
>{{ item.niche_name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="标签" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-checkbox-group v-model="editor_form.label_id">
<a-checkbox
v-for="item in form.label"
:key="item.label_id"
:value="item.label_id"
>{{ item.label_name }}</a-checkbox>
</a-checkbox-group>
</a-form-item>
<a-form-item label="封面图上传" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-upload
name="file"
listType="picture-card"
class="avatar-uploader"
:showUploadList="false"
action="http://192.168.110.41:8000/quick_poll/api_back_alert_upload/"
:beforeUpload="beforeUpload"
@change="handleChange"
>
<img style="height:20%;" v-if="imageUrl" :src="imageUrl" alt="avatar"/>
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<!-- <div class="ant-upload-text">Upload</div> -->
</div>
</a-upload>
</a-form-item>
<a-form-item label="资讯标题" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-input v-model="editor_form.news_title" placeholder="请输入标题"></a-input>
</a-form-item>
<a-form-item label="地域" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="editor_form.regional_id" placeholder="请选择">
<a-select-option
v-for="(item, index) in form.regional"
:key="item.index"
:title="item.regional_name"
:value="item.regional_id"
>{{ item.regional_name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="来源" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="editor_form.source_id" placeholder="请选择">
<a-select-option
v-for="item in form.source"
:key="item.source_id"
:title="item.source_name"
:value="item.source_id"
>{{ item.source_name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="作者" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="editor_form.author_id" placeholder="请选择">
<a-select-option
v-for="item in form.author"
:key="item.author_id"
:title="item.author_name"
:value="item.author_id"
>{{ item.author_name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="摘要" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-input
type="textarea"
:autosize="{ minRows: 4, maxRows: 6}"
placeholder="请输入内容"
v-model="editor_form.abstract"
></a-input>
</a-form-item>
<a-form-item label="内容" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-card style="height: 500px;">
<quill-editor v-model="editor_form.content" style="height: 210px;">
<div slot="header"></div>
<div></div>
</quill-editor>
</a-card>
</a-form-item>
<a-form-item :wrapper-col="button">
<a-button type="primary" @click="ok(editor_form)">添加</a-button>
<a-button @click="CancelColumn">取消</a-button>
</a-form-item>
</a-form>
</div>
</template>
<script>
import { getNewsAdd } from "@/api/news";
import { editorNews } from "@/api/news";
import { quillEditor } from "vue-quill-editor";
import { postImageData } from "@/api/news";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "editorForm",
// 注册组键
components: {
quillEditor
},
data() {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
},
button: {
span: 14,
offset: 4
},
loading: false,
imageUrl: "",
form: {
article: "",
niche: [],
label: [],
author: [],
source: [],
regional: []
},
editor_form: {
id: "",
article_id: "",
niche_id: "",
label_id: [],
img_name: "",
news_title: "",
regional_id: "",
source_id: "",
author_id: "",
abstract: "",
content: ""
}
};
},
// 获取到绑定值
props: ["id", "editor_data", "offModel"],
// 表单赋值
created() {
this.imageUrl = `http://192.168.110.56:8001/${this.editor_data[0].img}`
this.editor_form.id = this.id;
this.editor_form.article_id = this.editor_data[0].article;
this.editor_form.niche_id = this.editor_data[0].niche;
this.editor_form.label_id = this.editor_data[0].labels;
this.editor_form.img_name = this.editor_data[0].img;
this.editor_form.news_title = this.editor_data[0].title;
this.editor_form.regional_id = this.editor_data[0].regional;
this.editor_form.source_id = this.editor_data[0].source;
this.editor_form.author_id = this.editor_data[0].author;
this.editor_form.abstract = this.editor_data[0].abstract;
this.editor_form.content = this.editor_data[0].content;
},
mounted() {
getNewsAdd().then(resp => {
this.form.article = resp.data.article;
this.form.niche = resp.data.niche;
this.form.label = resp.data.label;
this.form.author = resp.data.author;
this.form.source = resp.data.source;
this.form.regional = resp.data.regional;
});
},
methods: {
ok(editor_form) {
console.log(editor_form, '编辑表单')
const param_q = new URLSearchParams(editor_form);
editorNews(param_q).then(resp => {
this.$store.dispatch("get_news");
console.log(resp, '编辑表单')
});
this.offModel();
this.$message({ type: "success", message: "修改成功!" });
},
CancelColumn() {
this.$message({ type: "info", message: "已取消添加" });
this.offModel();
},
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
// 给表单img_name赋值
this.editor_form.img_name = info.file.response.msg
});
}
},
// 上传文件之前的钩子,参数为上传的文件
beforeUpload(file) {
const isJPG = file.type === 'image/jpeg';
if (!isJPG) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJPG && isLt2M;
},
}
};
</script>
<style lang="scss">
// 图片上传样式
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
在放添加模态框里的
<template>
<div>
<a-form :form="form" :model="addform">
<a-form-item label="文章栏目" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="addform.article_id" placeholder="请选择" >
<a-select-option
placeholder="请选择"
v-for="(item, index) in form.article"
:key="item.index"
:title="item.article_name"
:value="item.article_id"
>{{ item.article_name}}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="细分领域" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="addform.niche_id" placeholder="请选择">
<a-select-option
v-for="(item, index) in form.niche"
:key="item.index"
:title="item.niche_name"
:value="item.niche_id"
>{{ item.niche_name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="标签" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-checkbox-group v-model="addform.label_id">
<a-col :span="20">
<a-checkbox
v-for="item in form.label"
:key="item.label_id"
:value="item.label_id">
{{ item.label_name }}
</a-checkbox>
</a-col>
</a-checkbox-group>
</a-form-item>
<a-form-item label="封面图上传" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-upload
name="file"
listType="picture-card"
class="avatar-uploader"
:showUploadList="false"
action="http://192.168.110.41:8000/quick_poll/api_back_alert_upload/"
:beforeUpload="beforeUpload"
@change="handleChange">
<img style="height:20%;" v-if="imageUrl" :src="imageUrl" alt="avatar"/>
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<!-- <div class="ant-upload-text">Upload</div> -->
</div>
</a-upload>
</a-form-item>
<a-form-item label="资讯标题" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-input v-model="addform.news_title" placeholder="请输入内容"></a-input>
</a-form-item>
<a-form-item label="地域" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="addform.regional_id" placeholder="请选择">
<a-select-option
v-for="(item, index) in form.regional"
:key="item.index"
:title="item.regional_name"
:value="item.regional_id"
>{{ item.regional_name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="来源" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="addform.source_id" placeholder="请选择">
<a-select-option
v-for="item in form.source"
:key="item.source_id"
:title="item.source_name"
:value="item.source_id"
>{{ item.source_name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="作者" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-select v-model="addform.author_id" placeholder="请选择">
<a-select-option
v-for="item in form.author"
:key="item.author_id"
:title="item.author_name"
:value="item.author_id"
>{{ item.author_name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="摘要" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-input
type="textarea"
:autosize="{ minRows: 4, maxRows: 6}"
placeholder="请输入内容"
v-model="addform.abstract"
></a-input>
</a-form-item>
<a-form-item label="内容" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-card style="height: 500px" >
<quill-editor v-model="addform.content" style="height: 210px;">
<div slot="header"></div>
<div></div>
</quill-editor>
</a-card>
</a-form-item>
<a-form-item :wrapper-col="button">
<a-button type="primary" @click="Add(addform)">添加</a-button>
<a-button @click="CancelColumn">取消</a-button>
</a-form-item>
</a-form>
</div>
</template>
<script>
import { getNewsAdd } from "@/api/news";
import { addNews } from "@/api/news";
import { quillEditor } from "vue-quill-editor";
import { postImageData } from "@/api/news";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "addForm",
// 注册组键
components: {
quillEditor
},
data() {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
},
button: {
span: 14,
offset: 4
},
loading: false,
imageUrl: "",
form: {
article: "",
niche: [],
label: [],
author: [],
source: [],
regional: []
},
addform: {
article_id: "",
niche_id: "",
label_id: [],
author_id: "",
source_id: "",
regional_id: "",
img_name: "",
abstract: "",
content: ""
}
};
},
// 获取到绑定值
props: ["offModel"],
mounted() {
getNewsAdd().then(resp => {
this.form.article = resp.data.article;
this.form.niche = resp.data.niche;
this.form.label = resp.data.label;
this.form.author = resp.data.author;
this.form.source = resp.data.source;
this.form.regional = resp.data.regional;
});
},
methods: {
label(value) {
console.log(`selected ${value}`);
},
Add(addform) {
const param_q = new URLSearchParams(addform);
addNews(param_q).then(resp => {
this.$store.dispatch("get_news");
});
this.offModel();
this.$message({ type: "success", message: "添加成功!" });
},
CancelColumn() {
this.$message({ type: "info", message: "已取消添加" });
this.offModel();
},
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
// 给表单img_name赋值
this.addform.img_name = info.file.response.msg
});
}
},
// 上传文件之前的钩子,参数为上传的文件
beforeUpload(file) {
const isJPG = file.type === 'image/jpeg';
if (!isJPG) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJPG && isLt2M;
},
}
};
</script>
<style lang="scss">
// 图片上传样式
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
.label{
}
</style>
ok~ 有什么看不懂的留言 当然有可能我也不知道