封装Vue ElementUI el-table组件

做后台管理项目期间,有非常多的表格表单的操作,所以想着封装一个组件完成对表格的增删改查操作,目前正在完善中,也请大佬们多多指教,代码如下。

子组件tempale  代码1-1

//子组件template部分

<template>
  <div>
    <el-table :data="tableList" style="width: 100%" border :header-cell-style="headerCellStyle" empty-text="暂无数据">
      <el-table-column v-for="(prop,index) in propsKey" :key="index" :label="!keyLabel[index]?prop:keyLabel[index]" align="center">
        <template slot-scope="scope">
          <span>{{scope.row[prop]?scope.row[prop]:'暂无数据'}}</span>
        </template>
      </el-table-column>
      <el-table-column v-if="showPermission" align="center">
        <template slot-scope="scope">
          <el-button v-if="permissionList.indexOf('R')!=-1" size="mini" @click="handleRead(scope.$index, scope.row)">Read</el-button>
          <el-button v-if="permissionList.indexOf('D')!=-1" size="mini" @click="handleDelect(scope.$index, scope.row)">Delect</el-button>
          <el-button v-if="permissionList.indexOf('U')!=-1" size="mini" @click="handleUpdate(scope.$index, scope.row)">Update</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog title="修改" :visible.sync="dialogVisible" :width="dialogWidth" v-if="dialogVisible" :before-close="dialogCloseHandle">
      <el-form :model="emitFrom">
        <el-form-item v-for="(item,index) in propsKey" :key="index" :label="!keyLabel[index]?item:keyLabel[index]" :label-width="dialogLabelWidth">
          <slot :name="item+'-insert'" :modelKey="emitFrom" :modelValue="item" :dialogInsertWidth="dialogInsertWidth">
            <el-input v-model="emitFrom[item]" :style="{width:dialogInsertWidth}"></el-input>
        <!--  插槽,from-item默认是输入框,可自定义from-item-->
          </slot>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogCloseHandle">取 消</el-button>
        <el-button type="primary" @click="dialogSucceedHandle">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

子组件srcipt  代码1-2

export default {
  name: "FullTable",
  props: {
    tableList: {//接收表单数据
      type: Array,
      required: true,
    },
    keyLabel: { //表单key对应的label,用于展示table表头的label
      type: Array,
    },
    permissions: {//可进行的操作,可选CRUD
      type: String,
      default: "",
    },
    showExclude: {//需要在展示中排除的数据项,例如后端返回的数据有id,不需要展示,可以排除
      type: Array,
      default: () => [],
    },
    permissionExclude: {//在进行增删改查时候不能修改的数据项,例如在dialog中账号可能需要展示,但不能修改
      type: Array,
      default: () => [],
    },
    headerCellStyle: {//表头样式 el-table默认属性//还有很多默认属性目前没加,等后续开发
      type: Object,
      default: () => ({ background: "#f5f7fa", color: "#606266" }),
    },
    dialogWidth: {//弹窗宽度
      type: String,
      default: "35%",
    },
    dialogLabelWidth: {//弹窗内from子项label宽度
      type: String,
      default: "60px",
    },
    dialogInsertWidth: {//弹窗内from子项输入框的宽度
      type: String,
      default: "250px",
    },
  },
  data() {
    return {
      permissionList: [], //权限列表数组
      dialogVisible: false, //dialog状态
      emitFrom: "", //弹框From数据
    };
  },
  created() {
    this.managePermissions();
  },
  computed: {
    propsKey() {
      //props对象数组里面的key,排除不需要展示的key后返回
      let res = [];
      Object.keys(this.tableList[0]).forEach((key) => {
        if (this.showExclude.indexOf(key) == -1) {
          res.push(key);
        }
      });
      return res;
    },
    showPermission() {
      return this.permissionList.reduce((status = false, permission) => {
        return (status = status || "URD".indexOf(permission) >= 0);
      }, "");
    },
  },
  methods: {
    managePermissions() {
      this.permissionList = this.permissions.toUpperCase().split("");
    },
    handleRead(index, row) {},
    handleDelect(index, row) {
      this.$emit("handleDelect", row);
    },
    handleUpdate(index, row) {
      this.emitFrom = JSON.parse(JSON.stringify(row));
      this.dialogVisible = true;
    },
    dialogCloseHandle() {
      this.dialogVisible = false;
      this.emitFrom = "";
      this.dialogKey = [];
    },
    dialogSucceedHandle() {
      this.dialogVisible = false;
      this.$emit("handleUpdate", this.emitFrom);
      this.emitFrom = "";
      this.dialogKey = [];
    },
  },
};

 父组件如下 代码2-1

<template>
  <div>
    <FullTable :tableList="testTableList" :keyLabel="label" permissions="curd" :showExclude="['id']" @handleDelect="handleDelect" @handleUpdate="handleUpdate">
      <template #sex-insert="{modelKey,modelValue,dialogInsertWidth}">
        <el-select v-model="modelKey[modelValue]" :style="{'min-width':dialogInsertWidth}" placeholder="请选择">
          <el-option v-for="item in options" :key="item" :label="item" :value="item">
          </el-option>
        </el-select>
      </template>
    </FullTable>
  </div>
</template>

<script>
import FullTable from "@/views/demo/index.vue";
export default {
  components: { FullTable },
  data() {
    return {
      options: ["男", "女"],
      testTableList: [
        { name: "zsy", age: 18, sex: "男", id: "1029", demo: 10 },
        { name: "zsy", age: 18, sex: "男", id: "1028", demo: 10 },
        { name: "zsy", age: 18, sex: "男", id: "1027", demo: 10 },
        { name: "zsy", age: 18, sex: "男", id: "1024", demo: 10 },
      ],
      label: ["姓名", "年龄", "性别"],
    };
  },
  methods: {
    handleDelect(row) {
      console.log(row, "---parent component");
    },
    handleUpdate(row) {
      this.testFrom.map((item, index) => {
        if (item.id === row.id) {
          this.$set(this.testFrom, index, row);
        }
        return item;
      });
      console.log(this.testFrom, "---handleUpdate");
    },

        具体使用大概可以这样:

                ------在父组件中导入

                ------传入tableList、权限、tablelist里面的所对应的label

        这样最基本的用法就出来了

        如你需要在dialog的from-item中使用下拉框等你所需要的输入方式,可以用插槽修改默认的输入框,如代码2-1所示。可用作用域插槽获取子组件绑定的值,用modelKey[modelValue]表示,用v-model绑定这个值就可修改。插槽的名字为你想要自定义的from-item的key 和insert拼起来

        eg. 如果你要自定义from-item中 sex的默认修改方式,则该插槽的名字应该改为 sex-insert,如代码2-1 第四行所示

下面展示效果 

目前组件还未完善。后续将继续完善

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值