Last active
October 19, 2017 01:59
-
-
Save wisetc/1b4ec0f64b535659f416a81dca7e3ca6 to your computer and use it in GitHub Desktop.
vue CRUD component base on element-ui
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="crud"> | |
<div class="crud__ctrl"> | |
<el-button type="primary" @click="create" size="small" icon="plus">新增</el-button> | |
</div> | |
<el-table :data="data" stripe border> | |
<template v-for="(key, index) in Object.keys(columns)"> | |
<el-table-column v-if="(fields[key] || '').options" :label="columns[key]" show-overflow-tooltip> <!-- 如果表格中包含有选项的字段 --> | |
<template scope="scope"> | |
{{ (fields[key].options.find(item => item.value === scope.row[key]) || '').label }} | |
</template> | |
</el-table-column> | |
<el-table-column v-else :label="columns[key]" :prop="key" show-overflow-tooltip></el-table-column> | |
</template> | |
<el-table-column label="操作" width="140" align="center"> | |
<template scope="scope"> | |
<el-button type="warning" size="small" @click="update(scope.row, scope.$index)">修改</el-button> | |
<el-button type="danger" size="small" @click="destroy(scope.row, scope.$index)">删除</el-button> | |
</template> | |
</el-table-column> | |
</el-table> | |
<el-dialog :title="dialog.title[dialog.status]" :size="dialog.size" :close-on-click-modal="false" | |
:visible="editing" :show-close="false" @open="handleOpen"> | |
<el-form class="crud__form" :class="{'crud__form--inline': inline}" ref="form" :model="form" :rules="rules" @keyup.native.13="Submit"> | |
<el-form-item v-for="(key, index) in Object.keys(labels)" :key="index" :label="labels[key]" :prop="key" :label-width="labelWidth"> | |
<el-select v-if="fields[key].options" v-model="form[key]" style="width: 100%;"> | |
<el-option v-for="(o, index) in fields[key].options" :key="index" :label="o.label" :value="o.value" | |
:disabled="fields[key].unique && repeated(key, o.value, (updatingRow || '')[key])"/> | |
</el-select> | |
<el-date-picker v-else-if="fields[key].type === TYPES.datetime" type="datetime" v-model="form[key]"></el-date-picker> | |
<el-input v-else v-model="form[key]" :maxlength="fields[key].length"/> | |
</el-form-item> | |
</el-form> | |
<div slot="footer"> | |
<el-button @click="closeDialog">取消</el-button> | |
<el-button type="primary" @click="Submit">提交</el-button> | |
</div> | |
</el-dialog> | |
</div> | |
</template> | |
<script> | |
import TYPES from './fields' | |
export default { | |
props: { | |
// 表格数据 | |
data: { required: true, type: Array }, | |
// 表单 v-model 对象 | |
form: { required: true, type: Object }, | |
// 表单字段 | |
fields: { required: true, type: Object }, | |
// 表单验证 | |
rules: { required: true, type: Object }, | |
// 对话框 el-dialog 的显示和隐藏状态 | |
editing: { required: true, type: Boolean }, | |
// 对话框 el-dialog 的大小值 | |
size: { default: 'large', type: String }, | |
// 表单元素标签的尺寸 | |
labelWidth: { default: '100px', type: String }, | |
// 表单的显示样式,如果为真,则是行内显示 | |
inline: { default: true, type: Boolean }, | |
// 表格与表单的字段不一致时,传入作为表格的表头 | |
table: { default: () => ({}), type: Object } | |
}, | |
data() { | |
return { | |
dialog: { | |
status: 0, | |
title: { | |
0: '新增', | |
1: '修改' | |
}, | |
size: this.inline ? this.size : 'small' | |
}, | |
// 选项不可重复时,传入当前行判断选项是否为此当前行的属性 | |
updatingRow: null, | |
TYPES | |
} | |
}, | |
computed: { | |
labels() { | |
let labels = {} | |
let fields = this.fields | |
for (let key in fields) { | |
labels[key] = fields[key].label | |
} | |
return labels | |
}, | |
columns() { | |
return Object.keys(this.table).length ? this.table : this.labels | |
} | |
}, | |
methods: { | |
create() { | |
this.dialog.status = 0 | |
this.showDialog() | |
this.$emit('create') | |
}, | |
update(row, index) { | |
this.dialog.status = 1 | |
this.updatingRow = row | |
this.showDialog() | |
this.$emit('update', row, index) | |
}, | |
destroy(row, index) { | |
this.$confirm(`确定要删除?`, '确认', {type: 'warning'}).then(()=> { | |
this.$emit('destroy', row, index) | |
}) | |
}, | |
showDialog() { | |
this.$emit('open') | |
}, | |
closeDialog() { | |
this.$emit('close') | |
}, | |
handleOpen() { | |
if (this.$refs.form) { | |
this.$refs.form.resetFields() | |
} | |
}, | |
Submit() { | |
this.$refs.form.validate(valid => { | |
if (valid) { | |
this.$emit('submit', this.dialog.status) | |
} | |
}) | |
}, | |
repeated(key, value, self) { | |
if (value === self) return false | |
return this.data.find(item => item[key] === value) ? true : false | |
}, | |
} | |
} | |
</script> | |
<style> | |
.crud__ctrl { | |
margin: 8px 0; | |
} | |
.crud__form--inline:after { | |
content: ''; | |
clear: both; | |
display: table; | |
} | |
.crud__form--inline .el-form-item { | |
width: 33%; | |
float: left; | |
padding: 0 8px; | |
box-sizing: border-box; | |
} | |
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fields = ['string', 'text', 'boolean', 'integer', 'float', 'date', 'datetime', 'objectid'] | |
export default fields.reduce((x, y, i) => ( | |
{...x, [y]: i + 1} | |
), {}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default function report(data, type='', callback) { | |
let map = { | |
create: '新增', | |
update: '修改', | |
destroy: '删除' | |
} | |
let msg = map[type] || '操作' | |
if (data.code === 1) { | |
this.$message.success(msg + '成功!') | |
callback(data) | |
} else { | |
this.$message.error(msg + '失败!' + data.msg) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div> | |
<crud :data="data" :form="form" :rules="rules" :fields="mapItems" | |
:editing="editing" @open="handleOpen" @close="handleClose" | |
@create="handleCreate" @update="handleUpdate" @destroy="handleDestroy" @submit="handleSubmit"/> | |
</div> | |
</template> | |
<script> | |
import { RepairStationAPI as api } from '../../api' | |
import CRUD from '../../components/crud' | |
export default { | |
components: { crud: CRUD }, | |
data() { | |
return { | |
data: [], | |
form: {}, | |
editing: false, | |
mapItems: { | |
name: { | |
label: '单位名', | |
length: 50, | |
type: String, | |
rules: [{ required: true, message: '此项不能为空' }] | |
}, | |
shortName: { | |
label: '字母简称', | |
length: 50, | |
type: String, | |
rules: [{ required: true, message: '此项不能为空' }] | |
}, | |
director: { | |
label: '负责人', | |
length: 50, | |
type: String, | |
rules: [{ required: true, message: '此项不能为空' }] | |
}, | |
address: { | |
label: '通讯地址', | |
length: 50, | |
type: String | |
}, | |
tel: { | |
label: '电话', | |
length: 11, | |
type: Number | |
}, | |
fax: { | |
label: '传真', | |
length: 50, | |
type: String | |
}, | |
phone: { | |
label: '手机', | |
length: 11, | |
type: Number | |
}, | |
mail: { | |
label: '邮箱', | |
length: 50, | |
type: String | |
}, | |
site: { | |
label: '网址', | |
length: 50, | |
type: String, | |
}, | |
credit: { | |
label: '信用等级', | |
length: 50, | |
type: String, | |
}, | |
depositBank: { | |
label: '开户银行', | |
length: 50, | |
type: String, | |
}, | |
bankAccount: { | |
label: '银行账号', | |
length: 50, | |
type: Number | |
}, | |
taxId: { | |
label: '税号', | |
length: 50, | |
type: String | |
}, | |
remark: { | |
label: '备注', | |
length: 50, | |
type: String | |
}, | |
} | |
} | |
}, | |
computed: { | |
model() { | |
let model = {} | |
let mapItems = this.mapItems | |
for (let k in mapItems) { | |
model[k] = null | |
} | |
return model | |
}, | |
rules() { | |
let rules = {} | |
let mapItems = this.mapItems | |
for (let k in mapItems) { | |
if (mapItems[k].rules) { | |
rules[k] = mapItems[k].rules | |
} | |
} | |
return rules | |
} | |
}, | |
created() { | |
this.loadData() | |
}, | |
methods: { | |
loadData() { | |
api.list().then(({data}) => { | |
this.data = data.data.data | |
}) | |
}, | |
handleCreate() { | |
this.form = { ...this.model } | |
}, | |
handleUpdate(row, index) { | |
this.form = { ...row } | |
this.handleOpen() | |
}, | |
handleDestroy(row, index) { | |
api.destroy({id: row.id}).then(({data}) => { | |
this.$report(data, 'destroy', this.deleteSuccess) | |
}) | |
}, | |
handleOpen() { | |
this.editing = true | |
}, | |
handleClose() { | |
this.editing = false | |
}, | |
handleSubmit(status) { | |
if (status === 0) { | |
api.create({data: JSON.stringify(this.form)}).then(({data}) => { | |
this.$report(data, 'create', this.createSuccess) | |
}) | |
} else { | |
api.update({data: JSON.stringify(this.form)}).then(({data}) => { | |
this.$report(data, 'update', this.updateSuccess) | |
}) | |
} | |
}, | |
createSuccess(data) { | |
this.handleClose() | |
this.loadData() | |
}, | |
updateSuccess() { | |
this.handleClose() | |
this.loadData() | |
}, | |
deleteSuccess(data) { | |
this.loadData() | |
} | |
} | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment