index.vue 6.53 KB
<style lang="scss">
.zee-scheme {
  &__header {
    margin-bottom: 10px;
  }
  &__filter {
    border: 1px solid #ebeef5;
    padding-top: 10px;
    border-radius: 4px;
    margin-bottom: 10px;
  }
  &__action {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    line-height: 1;
    justify-content: flex-start;
    .el-button + .el-button {
      margin-left: 0;
    }
    .el-button {
      margin-right: 10px;
      margin-bottom: 10px;
    }
  }
  &__dialog-button {
    display: flex;
    align-items: center;
    justify-content: center;
    padding-top: 10px;
  }
  &__footer {
    margin-top: 10px;
    text-align: right;
  }
}
</style>

<template>
  <div class="zee-scheme">
    <div v-if="$scopedSlots.header || $slots.header" class="zee-scheme__header">
      <slot name="header" :filterModel="filterModel" v-bind="_slotScope"></slot>
    </div>
    <div class="zee-scheme__filter">
      <z-filter v-if="filter" :value="_filterModel" :list="list | noRulesFilter" :size="size" @input="onFilterInput"></z-filter>
    </div>
    <div v-if="action" class="zee-scheme__action">
      <slot v-if="hadSlot('action')" name="action" v-bind="_slotScope"></slot>
      <template v-else>
        <el-button :size="size" type="primary" @click="openNew">新增</el-button>
        <slot name="button" :size="size" v-bind="_slotScope"></slot>
      </template>
    </div>
    <div class="zee-scheme__table">
      <z-table v-model="tableData" :list="list" :tableProps="{ border: true }" :size="size">
        <template #column-end>
          <el-table-column prop="$operation" label="操作" :width="140" fixed="right">
            <template slot-scope="slotScope">
              <el-button type="text" icon="el-icon-edit" title="编辑" @click="openEdit(slotScope)"></el-button>
            </template>
          </el-table-column>
        </template>
      </z-table>
    </div>
    <div class="zee-scheme__footer">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="pageSizes"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
      >
      </el-pagination>
    </div>
    <el-dialog :visible.sync="dialogVisible" :title="dialogTitle" destroy-on-close append-to-body :close-on-click-modal="false" @closed="onDialogClosed">
      <div v-loading="dialogLoading">
        <slot v-if="hadSlot('dialog-title')" slot="title" name="dialog-title" :dialogType="dialogType" v-bind="_slotScope"></slot>
        <template v-if="dialogRender">
          <slot v-if="hadSlot(`dialog-${dialogType}`)" :name="`dialog-${dialogType}`" :model="_formModel" v-bind="_slotScope"></slot>
          <z-form v-else ref="form" :value="_formModel" :list="list" label-width="80px" :span="12" @input="onFormInput" @validate="onFormValidate"></z-form>
          <div class="zee-scheme__dialog-button" v-if="['new', 'edit'].includes(dialogType)">
            <el-button :size="size" type="primary" @click="handleConfirm">确定</el-button>
            <el-button :size="size" plain @click="closeDialog">取消</el-button>
          </div>
        </template>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { cloneDeep } from '../form/util';

export default {
  name: 'Scheme',
  props: {
    list: Array,
    filter: {
      type: Boolean,
      default: true,
    },
    action: {
      type: Boolean,
      default: true,
    },
    size: {
      type: String,
      default: 'mini',
    },
    formModel: Object,
    filterModel: Object,
  },
  data() {
    return {
      filterForm: {},
      editForm: {},
      dialogVisible: false,
      dialogRender: true,
      dialogType: 'none',
      dialogLoading: false,
      dialogTitle: '',
      dialogCloseCallback: undefined,
      currentPage: 1,
      pageSize: 10,
      total: 127,
      pageSizes: [10, 20, 50],
      tableData: [
        { name: '张三', age: 16, driver: { name: '王五', bank: { name: '中国银行' } } },
        { name: '李四', age: 24 },
      ],
    };
  },
  filters: {
    noRulesFilter(val = []) {
      let list = cloneDeep(val);
      const clearRules = list => {
        list.forEach(item => {
          if (item.list) {
            clearRules(item.list);
          } else {
            delete item.rules;
          }
        });
      };
      clearRules(list);
      return list;
    },
  },
  computed: {
    _filterModel() {
      return this.filterModel || this.filterForm || {};
    },
    _formModel() {
      return this.formModel || this.editForm || {};
    },
    _slotScope() {
      return {
        openDialog: this.openDialog,
        closeDialog: this.closeDialog,
      };
    },
  },
  methods: {
    onFilterInput(val) {
      this.filterForm = val || {};
      this.$emit('update:filterModel', val || {});
    },
    onFormInput(val) {
      this.editForm = val || {};
      this.$emit('update:formModel', val || {});
    },
    onFormValidate(valid, model) {
      if (valid) {
        console.log(model);
      }
    },
    // 表单按钮确定
    handleConfirm() {
      this.$refs.form && this.$refs.form.validate();
    },
    // 表单按钮取消
    handleCancel() {
      this.closeDialog();
    },
    // 查询是否有某个插槽
    hadSlot(name) {
      return !!this.$slots[name] || !!this.$scopedSlots[name];
    },
    // 打开新增弹出框
    openNew() {
      this.openDialog('new', '新增');
    },
    // 打开编辑弹出框
    openEdit({ row }) {
      this.dialogLoading = true;
      setTimeout(() => {
        this.editForm = { ...row };
        this.dialogLoading = false;
      }, 300);
      this.openDialog('edit', '编辑');
    },
    // 打开弹出框
    openDialog(type, title) {
      this.dialogVisible = true;
      this.dialogRender = true;
      this.dialogType = type;
      this.dialogTitle = title;
      this.dialogCloseCallback = undefined;
    },
    // 关闭弹出框
    closeDialog(callback) {
      this.dialogVisible = false;
      this.dialogCloseCallback = callback instanceof Event ? undefined : callback;
    },
    // 清空表单
    clearEditForm() {
      this.editForm = {};
    },
    // 弹出框关闭
    onDialogClosed() {
      this.clearEditForm();
      this.dialogRender = false;
      this.dialogType = 'none';
      this.dialogCloseCallback && this.dialogCloseCallback();
    },
    // 分页-每页个数
    handleSizeChange(val) {
      this.pageSize = val;
      this.currentPage = 1;
    },
    // 分页-当前页数
    handleCurrentChange(val) {
      this.currentPage = val;
    },
  },
};
</script>