vue3-基于el-table的二次封装

139 阅读1分钟

这里的表格功能比较全,包含分页,以及顶部按钮,可以根据自己的需求进行改装

  • 这样子的好处我们可以实现数据和view层的分离,提升开发效率
<template>
  <div class="base-table">
    <div class="action">
      <slot name="action"></slot>
    </div>
    <el-table
        v-bind="$attrs"
    >
      <template v-for="item in columns" :key="item.prop">
        <el-table-column
            type="selection"
            width="55"
            v-if="item.type === 'selection'"
            key="selection"
        >
        </el-table-column>
        <el-table-column
            v-else-if="!item.type"
            v-bind="item"
        >
        </el-table-column>
<!--        v-if="btn.visible"-->
        <el-table-column v-if="item.type === 'action'" v-bind="item" size="mini"  #default="scope">
          <template v-for="(btn,index) in item.list" :key="index" >
            <el-button :type="btn.type ||'text'" @click="handleAction(index, scope.row)">
              {{ btn.text }}
            </el-button>
          </template>
        </el-table-column>
      </template>
    </el-table>
        <el-pagination
            class="pagination"
            background
            layout="prev, pager, next, jumper"
            :total="pager.total"
            :page-size="pager.pageSize"
            @current-change="handleCurrentChange"
        />
  </div>
</template>
<script>
export default {
  name: 'BaseTable',
  props: ["columns", "pager"],
  setup(props, {emit}) {
    /**
     *
     * @param index {number} 索引
     * @param row {object} 行数据
     */
    const handleAction = (index, row) => {
      emit("handleAction", {index, row: {...row}})
    }
    /**
     * 分页改变
     *  @param pageNum {number} 页码
     */
    const handleCurrentChange = (pageNum) => {
      emit("handleCurrentChange", pageNum)
    }
    return {
      handleAction,
      handleCurrentChange
    }
  },
}
</script>
<style lang='scss' scoped>

</style>

使用案例

<template>
  <div class="user-manage">
    <base-table :columns="columns" :data="userList"
                :pager="pager"
                @selection-change="handleSelectionChange"
                @handleAction="handleAction"
                @handleCurrentChange="handleCurrentChange"
    >
      <template #action>
        <el-button type="primary" @click="handleCreate">新增</el-button>
        <el-button type="danger" @click="handlePatchDel">批量删除</el-button>
      </template>
    </base-table>
  </div>
</template>

<script lang="ts" setup>
import {getCurrentInstance, onMounted, reactive, ref, toRaw} from 'vue';
import api from '../api/index.js';
import BaseTable from '../../packages/BaseTable/BaseTable.vue';

const {proxy, ctx} = getCurrentInstance(); // ctx调用全局会有问题, 通过proxy来调用全局方法属性

const columns = reactive([
  {
    type: 'selection'
  },
  {
    label: '用户ID', prop: 'userId'
  },
  {
    label: '用户名', prop: 'userName',
  },
  {
    label: '用户邮箱', prop: 'userEmail'
  },
  {
    label: '用户角色', prop: 'role',
    formatter(row, column, value) {
      return {
        0: '管理员',
        1: '普通用户'
      }[value];
    }
  },
  {
    label: '用户状态', prop: 'state',
    formatter(row, column, value) {
      return {
        1: '在职',
        2: '离职',
        3: '试用期'
      }[value];
    }
  },
  {
    label: '用户名', prop: 'userName',
  },
  {
    label: '注册时间', prop: 'createTime', width: 180, formatter(row, column, value) {
      return utils.formatDate(new Date(value));
    }
  },
  {
    label: '最后登录时间', prop: 'lastLoginTime', width: 180
  },
  {
    type: 'action',
    label: '操作',
    width: 150,
    list: [
      {
        type: 'primary',
        text: '编辑',
        visible: true
      },
      {
        type: 'danger',
        text: '删除',
        visible: true
      }
    ]
  },
]);

// 初始化用户表单对象
const user = ref({
  // userId: '',
  // userName: '',
  // state: 1
});
const form = [
  {
    type: 'input',
    label: '用户Id',
    model: 'userId',
    placeholder: '请输入用户Id',
  },
  {
    type: 'input',
    label: '用户名称',
    model: 'userName',
    placeholder: '请输入用户名称',
  },
  {
    type: 'select',
    label: '状态',
    model: 'state',
    placeholder: '请选择状态',
    options: [
      {
        value: 0,
        label: '所有',
      },
      {
        value: 1,
        label: '在职',
      },
      {
        value: 2,
        label: '离职',
      },
      {
        value: 3,
        label: '试用期',
      }
    ]
  }
];
// 初始化分页
const pager = reactive({
  pageNum: 1,
  pageSize: 10,
  total: 100
});
// 初始化用户列表
const userList = ref([]);

// 初始化接口调用
onMounted(() => {
  getUserList();
  getDeptList();
  getRoleList();
});
// 获取用户表格数据
const getUserList = async () => {
  let params = {...user.value, ...pager};
  try {
    const {list, page} = await api.getUserList(params);
    userList.value = list;
    pager.total = page.total;
  } catch (e) {
    console.log(e);
  }
};

const action = ref('add');
// 用户提交

// 查询事件,获取用户列表
// 用户单个删除
const handleDel = async (row) => {
  await proxy.$api.userDel({
    userIds: [row.userId]
  });
  proxy.$message.success('删除成功');
  await getUserList();
};

const handleAction = ({index, row}) => {
  if (index === 0) {
    handleEdit(row);
  } else if (index === 1) {
    handleDel(row);
  }
};

const handleSelectionChange = (list) => {
  let arr = [];
  list.map(item => {
    arr.push(item.userId);
  });
  checkedUserIds.value = arr;
};
// 选中用户列表的对象
const checkedUserIds = ref([]);
// 批量删除
const handlePatchDel = async (row) => {
  if (checkedUserIds.value.length === 0) {
    proxy.$message.error('请选择要删除的用户');
    return;
  }
  const res = await proxy.$api.userDel({
    userIds: checkedUserIds.value
  });
  if (res.nModified > 0) {
    proxy.$message.success('删除成功');
    await getUserList();
  } else {
    proxy.$message.success('修改失败');
  }
};


// 重置查询表单
const handleReset = (form) => {
  proxy.$refs[form].resetFields();
};

// 分页事件处理
const handleCurrentChange = (current) => {
  pager.pageNum = current;
  getUserList();
};
// 新增用户
const userForm = reactive({
  state: 3
});
// 弹框显示
const showModal = ref(false);
const handleCreate = () => {
  action.value = 'add';
  showModal.value = true;
};
// 用户编辑
const handleEdit = (row) => {
  action.value = 'edit';
  showModal.value = true;
  // 不能直接写,reset会有问题,会觉得初始状态就有值
  // Object.assign(userForm, row);
  // 等待dom渲染完成再执行,初始状态是空
  proxy.$nextTick(() => {
    // 把row的数据浅拷贝给userForm
    Object.assign(userForm, row);
    console.log('userForm', userForm);
  });
};


// 所有的部门列表
const deptList = ref([]);
// 所有的角色列表
const roleList = ref([]);
// 获取所有的部门
const getDeptList = async () => {
  let list = await proxy.$api.getDeptList();
  deptList.value = list;
};

// 角色列表查询
const getRoleList = async () => {
  let list = await proxy.$api.getRoleList();
  roleList.value = list;
};


// 定义动态表格头

</script>

<style>

</style>