npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

npm-vue3-element-table

v1.1.5

Published

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

Downloads

894

Readme

注: 由于 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>