1.1.5 • Published 10 months ago

npm-vue3-element-table v1.1.5

Weekly downloads
-
License
MIT
Repository
-
Last release
10 months ago

注: 由于 sass 版本变更较大,如果遇到安装后报错的 可以查看本地之前安装的 sass 版本是否是 1.80.4 , sass-loader 是否是 16.0.2 如果不是这个版本,请升级一下 sass 版本,并且在 vite.config.ts 里面加上

css: {
    preprocessorOptions: {
        scss: {
            silenceDeprecations: ['legacy-js-api'], //去掉警告提示
        }
    }
}

如果引入 npm-vue3-element-table 报 ts 类型错误,在 src 文件夹下面创建 shims-vue.d.ts 文件,写入 declare module 'npm-vue3-element-table'

示例图片

Fileter_transaction Fileter_transaction

github 项目使用链接地址

封装表格使用说明

调用方法

1.在 main.ts 中全局引入 import { MyBasicTable } from 'npm-vue3-element-table'
app.use(MyBasicTable)
2.在页面中单独引入 import { MyBasicTable } from 'npm-vue3-element-table'

接收参数

1.表格:tableObj(在父组件 computed 计算方法里面声明)

const tableObj = computed(() => {
  let table = {
    data: tableData.value,
    option: tableOptions.value,
    config: {
      height:'300',//高度
      showHeader:true,//是否显示表头
      columnType:'selection', // selection(复选框) expand(展开) radio(单选框)
      hasRadio:true/false, //是否显示单选框
      hasSelection:true/false, //是否显示复选框
      defaultSort: { prop: 'startTime', order: 'descending' }.//默认排序
      rowKey:id, //为表格数据的唯一值,例如id、uuid
      defaultExpandAll: false ,//有展开列时,用该参数设置是否默认展开所有列
      reserveSelection:true// 仅对 type=selection 的列有效
    },
    operation: {
      label: '操作',//操作列
      width: operation.width || '120',
      fixed: operation.fixed || false,
      show: operation.show || false,
      minWidth: operation.minWidth || '',
      showIcon: operation.showIcon || false
    }
  }
  return table
})

2.tableOptions:

tableOptions 中的每一项的 width,min-width 都支持设置

const tableOptions = computed(() => {
  let tableOptions = [
    {
      prop: 'applyPersonName',
      label: '申请人',
      showOverflowToolTip: true,
      show:true/false   //当前列是否显示
    },
    {
      prop: 'name', //如果无需修改,可以直接写后端返回的对应的 key
      showOverflowToolTip: true, //展示超出时鼠标悬浮提示
      fun: (row: any) => {
        goDetail(row) //点击进入详情页
      },
      label: '申请名称' //列名
    },
    {
      prop: 'applyPersonName',
      label: '申请人',
      showOverflowToolTip: true,
      headerRender: (row: any) => {   //自定义表头
        return h(
          ElButton,
          {
            onClick: btnClick
          },
          ['row.action + row.target']
        )
      },
    },
    {
      prop: 'status',
      label: '状态',
      showOverflowToolTip: true,
      filter: true,
      filterKey: 'status',
      selectOptions: statusOptions.value,
      render: (row: any) => {
        return h(statusItem, {
          row: row
        })
      }
    },
    //平台管理-账单管理-消费概览
    {
      prop: 'nameTxt',
      label: '项目名称',
      multipleTip: true, //鼠标悬浮,tooltip 有多个提示的情况
      multipleTipContent: 'multipleTipContent' //tooltip 中展示的内容
    },
      // 表格展开示例
    {
      prop: 'expand',
      label: '',
      render: (row: any) => {
        return h(
          'span',
          row.action ? row.status + '(' + row.userAccount + ')' : '-'
        )
      }
    },
  ]
  return tableOptions
})

3.分页:Pagination(没有特殊需求,在 data 中声明即可)

const Pagination = reactive({
  pagingData: [10, 50, 100, 200],
  pageSize: 10,
  total: 0,
  currentPage: 1,
  show: true
})

4.方法

分页:@pagingEvent="pagingChange"
排序:@sortChange="sortChange"
列表中的筛选事件:@filterChange="filterChange"
当选择项发生变化时会触发该事件:@handleSelectionChange="handleSelectionChange"(handlerSelectAll,handlerSelect的触发 均会触发handleSelectionChange事件,一般情况下写这个事件就可以获取选中的行)
当用户手动勾选全选 Checkbox 时触发的事件:@handlerSelectAll="handlerSelectAll"
当用户手动勾选数据行的 Checkbox 时触发的事件:@handlerSelect="handlerSelect"

5.示例

父页面:
<template>
  <my-basic-table
    ref="logTable"
    :Pagination="Pagination"
    @pagingEvent="pagingChange"
    :tableObj
    @sortChange="sortChange"
    @filterChange="filterChange"
  ></my-basic-table>
</template>
<script lang="ts" setup>
import { ref, computed, reactive, h } from 'vue'
import { ElButton } from 'element-plus'
import statusItem from './status-item.vue'
import editName from './edit-name.vue'
const moduleOptions = ref([
  { value: 'module_login', text: '登录' },
  { value: 'module_job', text: '作业管理' },
])
const statusOptions = ref([
  { value: 'success', text: '成功' },
  { value: 'fail', text: '失败' },
])
const tableData = ref([
  {
    type: 'file',
    createtime: '2024-10-29 13:14:33',
    createpin: '',
    updatetime: null,
    updatepin: '',
    yn: 1,
    uuid: '6d995990-f629-4072-b237-93dc01115d97',
    userAccount: 'gjx',
    userName: 'gjx1',
    managerNum:3,
    multipleTipContent:['account1','account2','account3'],
    module: '登录',
    action: '登录',
    chinese: 2,
    else: 3,
    target: '',
    targetUuid: '6c219b34-db38-48d4-8dd0-a6e84454eacd',
    targetName: 'gjx',
    status: '成功',
    message: null,
    messageExtra: null,
    ip: '172.27.133.22',
    startTime: '2024-10-29 13:14:33',
    endTime: '2024-10-29 13:14:33',
  },
])

const addOperation = (server: any) => {
  const operation = []
  operation.push({
    value: '删除',
    className:'del',
    fun: (item, row) => {
      return openDrawer('删除', row)
    }
  })
  operation.push({
    value: '编辑',
    fun: (item, row) => {
      return openDrawer('编辑', row)
    }
  })
  return (server.operation = operation)
}
const openDrawer = (str: string, obj: object) => {}
tableData.value.map((item: any) => {
  // @ts-ignore
  item.operation = addOperation(item)
})

const Pagination = reactive({
  pagingData: [10, 50, 100, 200],
  pageSize: 10,
  total: 100,
  currentPage: 1,
  show: true,
})
const tableOptions = computed(() => {
  const tableOptions = [
    // 表格展开示例
    {
      prop: 'expand',
      label: '',
      render: (row: any) => {
        return h(
          'span',
          {
            class: 'mgl60',
          },
          row.action ? row.status + '(' + row.userAccount + ')' : '-',
        )
      },
    },
    {
      prop: 'name',
      label: '操作人',
      showOverflowToolTip: true,
      render: (row: any) => {
        return h(
          'span',
          row.userAccount ? row.userAccount + '(' + row.userName + ')' : '-',
        )
      },
    },
    {
      prop: 'managerNum',
      label: '管理员',
      multipleTip: true,
      multipleTipContent: 'multipleTipContent',
      showOverflowToolTip: true
    },
    {
      label: '作业量',
      align: 'center',
      showOverflowToolTip: true,
      children: [
        {
          prop: 'chinese',
          label: '语文',
          showOverflowToolTip: true,
          sortProp: 'chinese',
          minWidth: 120,
        },
        {
          prop: 'else',
          label: '其它',
          minWidth: 110,
          filter: true,
          filterKey: 'elseNum',
          selectOptions: [
            { value: 'math', text: '数学' },
            { value: 'english', text: '英语' },
          ],
          showOverflowToolTip: true,
        },
      ],
    },
    {
      prop: 'module',
      label: '操作模块',
      showOverflowToolTip: true,
      width: 140,
      filter: true,
      filterKey: 'module',
      selectOptions: moduleOptions.value,
    },
    {
      prop: 'actionTxt',
      showOverflowToolTip: true,
      width: 140,
      label: '执行动作', // 自定义渲染表头示例
      headerRender: (row: any) => {
        return h(
          ElButton,
          {
            onClick: btnClick,
          },
          ['自定义表头'],
        )
      },
      render: (row: any) => {
        return h('span', row.action + row.target)
      },
    },
    {
      prop: 'operationName',
      showOverflowToolTip: true,
      width: 200,
      label: '操作对象',
      render: (row: any) => {
        return h(editName)
      },
    },
    {
      prop: 'status',
      label: '状态',
      filter: true,
      filterKey: 'status',
      selectOptions: statusOptions.value,
      render: (row: any) => {
        return h(statusItem, {
          row: row,
        })
      },
    },
    {
      prop: 'startTime',
      label: '操作时间',
      width: 160,
      sortProp: 'startTime',
    },
  ]
  return tableOptions
})
const tableObj = computed(() => {
  const table = {
    data: tableData.value,
    option: tableOptions.value,
    operation:{show:true},
    config: {
      defaultSort: { prop: 'startTime', order: 'descending' },
    },
  }
  return table
})
const pagingChange = (type: string, val: number) => {
  console.log(type, val, '分页')
}
const filterChange = (obj: any) => {
  console.log(obj, '筛选条件')
}
const btnClick = () => {
  console.log('自定义表头按钮点击事件')
}
const sortChange = (obj: any) => {
  console.log(obj, '排序条件')
}
</script>
<style lang="scss">
#app {
  height: 100vh;
}
.mgl60 {
  margin-left: 60px;
}
</style>
status-item子页面
<template>
  <div class="">
    <span class="status">
      <span
        class="status-circle"
        :class="
          row.status == '成功'
            ? 'success'
            : row.status == '失败'
              ? 'fail'
              : 'color-create-update-delete'
        ">
        <!-- ● -->
      </span>
      <span
        class="fs14"
        :class="
          row.status == '成功'
            ? 'success'
            : row.status == '失败'
              ? 'fail'
              : 'color-create-update-delete'
        ">
        {{
          row.status == '成功'
            ? '成功'
            : row.status == '失败'
              ? '失败'
              : '操作中'
        }}
      </span>
      <el-popover
        v-if="row.status == '失败'"
        placement="top"
        popper-class="ope-status-pop"
        title="【失败原因】"
        width="200"
        trigger="hover">
        <template #reference>
          <img class="icon-img" src="../../assets/images/warning.png" alt="" />
        </template>
        <template #default>
          <div class="ope-status-pop-content">
            {{ row.message }}
          </div>
        </template>
      </el-popover>
    </span>
  </div>
</template>

<script lang="ts" setup>
defineProps({ row: Object as any })
</script>

<style lang="scss" scoped>
.status {
  // 成功
  .success {
    color: #333;
    font-size: 1rem;
    &::before {
      background: #50b89c;
    }
  }
  // 其他
  .color-create-update-delete {
    font-size: 1rem;
    color: #333;
    &::before {
      background: #206bfa;
    }
  }
  // 失败
  .fail {
    color: #333;
    font-size: 1rem;
    &::before {
      background: #ec7c7c;
    }
  }
  .status-circle {
    &::before {
      content: '';
      display: inline-block;
      width: 0.375rem;
      height: 0.375rem;
      border-radius: 50%;
      position: relative;
      top: -0.125rem;
      margin-right: 0.25rem;
      white-space: nowrap;
    }
  }
  .fs14 {
    font-size: 0.875rem !important;
  }
  .icon-img {
    width: 0.875rem;
    height: 0.875rem;
    position: relative;
    top: 0.125rem;
    margin-left: 0.125rem;
  }
}
</style>

<style lang="scss">
.ope-status-pop {
  font-weight: 400;
  font-size: 0.875rem;
  color: #333;
  letter-spacing: 0;
  text-align: justify;
  line-height: 1.375rem;
  .ope-status-pop-content {
    max-height: 300px;
    overflow-y: auto;
  }
  .el-popover__title {
    font-weight: 600;
    font-size: 1rem;
    color: #333;
  }
}
.ope-status-pop .el-popper__arrow {
}
</style>
edit-name子页面
<template>
  <div class="table-name-wrapper">
    <el-icon>
      <FolderOpened v-if="row.type == 'folder'" />
      <Shop v-else />
    </el-icon>
    <div class="edit-show-box">
      <template v-if="isEdit">
        <el-input
          v-model="inputShowName"
          placeholder="请输入"
          maxlength="255" />
        <!-- 扩展名 -->
        <span v-if="row.type == 'file'">{{ extendName }}</span>
        <!-- 按钮 -->
        <el-icon @click="confirm"><Check /></el-icon>
        <el-icon><Close @click="cancel" /></el-icon>
      </template>
      <span v-else class="show-name-box">
        <span :title="showName">{{ showName }}{{ extendName }}</span>
        <el-icon @click="edit"><EditPen /></el-icon>
      </span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage } from 'element-plus'

const props = defineProps<{
  row: {
    userName: string
    type: 'file' | 'folder'
  }
}>()
const $emit = defineEmits(['openDialog'])
const isEdit = ref(false)
const inputShowName = ref('') // input内绑定名称
const showName = ref('') // 表格内显示名称
const extendName = ref('') // 扩展名

function edit() {
  isEdit.value = true
  inputShowName.value = showName.value
}
function confirm() {
  isEdit.value = false
  showName.value = inputShowName.value
  ElMessage({
    message: '编辑成功',
    type: 'success'
  })
}
function cancel() {
  isEdit.value = false
}

function init() {
  console.log(props.row, 'row')
  showName.value = props.row.userName
}
init()
</script>

<style scoped lang="scss">
.table-name-wrapper {
  display: flex;
  align-items: center;
  .icon-wenjianjia1 {
    color: #ffca28;
  }
  .icon-yingyong {
    color: #1496db;
  }
  .edit-show-box {
    margin-left: 8px;
    display: flex;
    align-items: center;
    flex: 1;
    width: calc(100% - 8px - 1rem);
    .el-icon {
      font-size: 16px;
      cursor: pointer;
      margin-left: 8px;
    }
    .show-name-box {
      display: flex;
      align-items: center;
      width: 100%;
      > span {
        color: #206bfa;
        cursor: pointer;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      .el-icon {
        color: #206bfa;
      }
    }
  }
}
</style>
1.1.1

10 months ago

1.1.0

10 months ago

1.0.9

10 months ago

1.0.8

10 months ago

1.0.7

10 months ago

1.1.5

10 months ago

1.1.4

10 months ago

1.1.3

10 months ago

1.1.2

10 months ago

1.0.10

10 months ago

1.0.5

10 months ago

1.0.4

10 months ago

1.0.3

10 months ago