Commit c97fa6d2d5fabf1aa82066cb8427f9a7f14b9214
1 parent
9b4ae7da
Exists in
master
and in
3 other branches
feat: 新增Scheme组件
Showing
1 changed file
with
239 additions
and
0 deletions
Show diff stats
| @@ -0,0 +1,239 @@ | @@ -0,0 +1,239 @@ | ||
| 1 | +<style lang="scss"> | ||
| 2 | +.zee-scheme { | ||
| 3 | + &__header { | ||
| 4 | + margin-bottom: 10px; | ||
| 5 | + } | ||
| 6 | + &__filter { | ||
| 7 | + border: 1px solid #ebeef5; | ||
| 8 | + padding-top: 10px; | ||
| 9 | + border-radius: 4px; | ||
| 10 | + margin-bottom: 10px; | ||
| 11 | + } | ||
| 12 | + &__action { | ||
| 13 | + display: flex; | ||
| 14 | + flex-wrap: wrap; | ||
| 15 | + align-items: center; | ||
| 16 | + line-height: 1; | ||
| 17 | + justify-content: flex-start; | ||
| 18 | + .el-button + .el-button { | ||
| 19 | + margin-left: 0; | ||
| 20 | + } | ||
| 21 | + .el-button { | ||
| 22 | + margin-right: 10px; | ||
| 23 | + margin-bottom: 10px; | ||
| 24 | + } | ||
| 25 | + } | ||
| 26 | + &__dialog-button { | ||
| 27 | + display: flex; | ||
| 28 | + align-items: center; | ||
| 29 | + justify-content: center; | ||
| 30 | + padding-top: 10px; | ||
| 31 | + } | ||
| 32 | + &__footer { | ||
| 33 | + margin-top: 10px; | ||
| 34 | + text-align: right; | ||
| 35 | + } | ||
| 36 | +} | ||
| 37 | +</style> | ||
| 38 | + | ||
| 39 | +<template> | ||
| 40 | + <div class="zee-scheme"> | ||
| 41 | + <div v-if="$scopedSlots.header || $slots.header" class="zee-scheme__header"> | ||
| 42 | + <slot name="header" :filterModel="filterModel" v-bind="_slotScope"></slot> | ||
| 43 | + </div> | ||
| 44 | + <div class="zee-scheme__filter"> | ||
| 45 | + <z-filter v-if="filter" :value="_filterModel" :list="list | noRulesFilter" :size="size" @input="onFilterInput"></z-filter> | ||
| 46 | + </div> | ||
| 47 | + <div v-if="action" class="zee-scheme__action"> | ||
| 48 | + <slot v-if="hadSlot('action')" name="action" v-bind="_slotScope"></slot> | ||
| 49 | + <template v-else> | ||
| 50 | + <el-button :size="size" type="primary" @click="openNew">新增</el-button> | ||
| 51 | + <slot name="button" :size="size" v-bind="_slotScope"></slot> | ||
| 52 | + </template> | ||
| 53 | + </div> | ||
| 54 | + <div class="zee-scheme__table"> | ||
| 55 | + <z-table v-model="tableData" :list="list" :tableProps="{ border: true }" :size="size"> | ||
| 56 | + <template #column-end> | ||
| 57 | + <el-table-column prop="$operation" label="操作" :width="140" fixed="right"> | ||
| 58 | + <template slot-scope="slotScope"> | ||
| 59 | + <el-button type="text" icon="el-icon-edit" title="编辑" @click="openEdit(slotScope)"></el-button> | ||
| 60 | + </template> | ||
| 61 | + </el-table-column> | ||
| 62 | + </template> | ||
| 63 | + </z-table> | ||
| 64 | + </div> | ||
| 65 | + <div class="zee-scheme__footer"> | ||
| 66 | + <el-pagination | ||
| 67 | + @size-change="handleSizeChange" | ||
| 68 | + @current-change="handleCurrentChange" | ||
| 69 | + :current-page="currentPage" | ||
| 70 | + :page-sizes="pageSizes" | ||
| 71 | + :page-size="pageSize" | ||
| 72 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 73 | + :total="total" | ||
| 74 | + > | ||
| 75 | + </el-pagination> | ||
| 76 | + </div> | ||
| 77 | + <el-dialog :visible.sync="dialogVisible" :title="dialogTitle" destroy-on-close append-to-body :close-on-click-modal="false" @closed="onDialogClosed"> | ||
| 78 | + <div v-loading="dialogLoading"> | ||
| 79 | + <slot v-if="hadSlot('dialog-title')" slot="title" name="dialog-title" :dialogType="dialogType" v-bind="_slotScope"></slot> | ||
| 80 | + <template v-if="dialogRender"> | ||
| 81 | + <slot v-if="hadSlot(`dialog-${dialogType}`)" :name="`dialog-${dialogType}`" :model="_formModel" v-bind="_slotScope"></slot> | ||
| 82 | + <z-form v-else ref="form" :value="_formModel" :list="list" label-width="80px" :span="12" @input="onFormInput" @validate="onFormValidate"></z-form> | ||
| 83 | + <div class="zee-scheme__dialog-button" v-if="['new', 'edit'].includes(dialogType)"> | ||
| 84 | + <el-button :size="size" type="primary" @click="handleConfirm">确定</el-button> | ||
| 85 | + <el-button :size="size" plain @click="closeDialog">取消</el-button> | ||
| 86 | + </div> | ||
| 87 | + </template> | ||
| 88 | + </div> | ||
| 89 | + </el-dialog> | ||
| 90 | + </div> | ||
| 91 | +</template> | ||
| 92 | + | ||
| 93 | +<script> | ||
| 94 | +import { cloneDeep } from '../form/util'; | ||
| 95 | + | ||
| 96 | +export default { | ||
| 97 | + name: 'Scheme', | ||
| 98 | + props: { | ||
| 99 | + list: Array, | ||
| 100 | + filter: { | ||
| 101 | + type: Boolean, | ||
| 102 | + default: true, | ||
| 103 | + }, | ||
| 104 | + action: { | ||
| 105 | + type: Boolean, | ||
| 106 | + default: true, | ||
| 107 | + }, | ||
| 108 | + size: { | ||
| 109 | + type: String, | ||
| 110 | + default: 'mini', | ||
| 111 | + }, | ||
| 112 | + formModel: Object, | ||
| 113 | + filterModel: Object, | ||
| 114 | + }, | ||
| 115 | + data() { | ||
| 116 | + return { | ||
| 117 | + filterForm: {}, | ||
| 118 | + editForm: {}, | ||
| 119 | + dialogVisible: false, | ||
| 120 | + dialogRender: true, | ||
| 121 | + dialogType: 'none', | ||
| 122 | + dialogLoading: false, | ||
| 123 | + dialogTitle: '', | ||
| 124 | + dialogCloseCallback: undefined, | ||
| 125 | + currentPage: 1, | ||
| 126 | + pageSize: 10, | ||
| 127 | + total: 127, | ||
| 128 | + pageSizes: [10, 20, 50], | ||
| 129 | + tableData: [ | ||
| 130 | + { name: '张三', age: 16, driver: { name: '王五', bank: { name: '中国银行' } } }, | ||
| 131 | + { name: '李四', age: 24 }, | ||
| 132 | + ], | ||
| 133 | + }; | ||
| 134 | + }, | ||
| 135 | + filters: { | ||
| 136 | + noRulesFilter(val = []) { | ||
| 137 | + let list = cloneDeep(val); | ||
| 138 | + const clearRules = list => { | ||
| 139 | + list.forEach(item => { | ||
| 140 | + if (item.list) { | ||
| 141 | + clearRules(item.list); | ||
| 142 | + } else { | ||
| 143 | + delete item.rules; | ||
| 144 | + } | ||
| 145 | + }); | ||
| 146 | + }; | ||
| 147 | + clearRules(list); | ||
| 148 | + return list; | ||
| 149 | + }, | ||
| 150 | + }, | ||
| 151 | + computed: { | ||
| 152 | + _filterModel() { | ||
| 153 | + return this.filterModel || this.filterForm || {}; | ||
| 154 | + }, | ||
| 155 | + _formModel() { | ||
| 156 | + return this.formModel || this.editForm || {}; | ||
| 157 | + }, | ||
| 158 | + _slotScope() { | ||
| 159 | + return { | ||
| 160 | + openDialog: this.openDialog, | ||
| 161 | + closeDialog: this.closeDialog, | ||
| 162 | + }; | ||
| 163 | + }, | ||
| 164 | + }, | ||
| 165 | + methods: { | ||
| 166 | + onFilterInput(val) { | ||
| 167 | + this.filterForm = val || {}; | ||
| 168 | + this.$emit('update:filterModel', val || {}); | ||
| 169 | + }, | ||
| 170 | + onFormInput(val) { | ||
| 171 | + this.editForm = val || {}; | ||
| 172 | + this.$emit('update:formModel', val || {}); | ||
| 173 | + }, | ||
| 174 | + onFormValidate(valid, model) { | ||
| 175 | + if (valid) { | ||
| 176 | + console.log(model); | ||
| 177 | + } | ||
| 178 | + }, | ||
| 179 | + // 表单按钮确定 | ||
| 180 | + handleConfirm() { | ||
| 181 | + this.$refs.form && this.$refs.form.validate(); | ||
| 182 | + }, | ||
| 183 | + // 表单按钮取消 | ||
| 184 | + handleCancel() { | ||
| 185 | + this.closeDialog(); | ||
| 186 | + }, | ||
| 187 | + // 查询是否有某个插槽 | ||
| 188 | + hadSlot(name) { | ||
| 189 | + return !!this.$slots[name] || !!this.$scopedSlots[name]; | ||
| 190 | + }, | ||
| 191 | + // 打开新增弹出框 | ||
| 192 | + openNew() { | ||
| 193 | + this.openDialog('new', '新增'); | ||
| 194 | + }, | ||
| 195 | + // 打开编辑弹出框 | ||
| 196 | + openEdit({ row }) { | ||
| 197 | + this.dialogLoading = true; | ||
| 198 | + setTimeout(() => { | ||
| 199 | + this.editForm = { ...row }; | ||
| 200 | + this.dialogLoading = false; | ||
| 201 | + }, 300); | ||
| 202 | + this.openDialog('edit', '编辑'); | ||
| 203 | + }, | ||
| 204 | + // 打开弹出框 | ||
| 205 | + openDialog(type, title) { | ||
| 206 | + this.dialogVisible = true; | ||
| 207 | + this.dialogRender = true; | ||
| 208 | + this.dialogType = type; | ||
| 209 | + this.dialogTitle = title; | ||
| 210 | + this.dialogCloseCallback = undefined; | ||
| 211 | + }, | ||
| 212 | + // 关闭弹出框 | ||
| 213 | + closeDialog(callback) { | ||
| 214 | + this.dialogVisible = false; | ||
| 215 | + this.dialogCloseCallback = callback instanceof Event ? undefined : callback; | ||
| 216 | + }, | ||
| 217 | + // 清空表单 | ||
| 218 | + clearEditForm() { | ||
| 219 | + this.editForm = {}; | ||
| 220 | + }, | ||
| 221 | + // 弹出框关闭 | ||
| 222 | + onDialogClosed() { | ||
| 223 | + this.clearEditForm(); | ||
| 224 | + this.dialogRender = false; | ||
| 225 | + this.dialogType = 'none'; | ||
| 226 | + this.dialogCloseCallback && this.dialogCloseCallback(); | ||
| 227 | + }, | ||
| 228 | + // 分页-每页个数 | ||
| 229 | + handleSizeChange(val) { | ||
| 230 | + this.pageSize = val; | ||
| 231 | + this.currentPage = 1; | ||
| 232 | + }, | ||
| 233 | + // 分页-当前页数 | ||
| 234 | + handleCurrentChange(val) { | ||
| 235 | + this.currentPage = val; | ||
| 236 | + }, | ||
| 237 | + }, | ||
| 238 | +}; | ||
| 239 | +</script> |