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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@wakaka1/adaptive-page

v2.1.13

Published

ui for table data

Readme

版本更新

2.1.13

扩展主子表的功能

  • 主表按钮隐藏控制
  • 字表请求自定义处理
  • 子表数据自定义处理
  • 字表 id 没有时自动生成

2.1.12

  • main-sub-table 增加 adaptive-page 插槽透传

2.1.11

  • 删除接口增加 code===200 的成功判断

表格数组展示控件, 在 umy-ui 基础上进行扩展。 包括两个页面和一个组件:

  • 主子表页面main-sub-table
  • 简单表格simple-table
  • 表格组件adaptive-page

使用

安装[email protected][email protected][email protected], @wakaka1/adaptive-page, 在 main.js 中, 添加如下代码:

import { UTable, UTableColumn } from "umy-ui";
import "umy-ui/lib/theme-chalk/index.css"; // 引入样式
Vue.use(UTable);
Vue.use(UTableColumn);
import "@/styles/index.scss";
import "@/styles/element-ui_2.15.6.css";
import AdaptivePage from "@wakaka1/adaptive-page";
Vue.use(AdaptivePage);

多语言

在主项目中,提供以下多语言选项:

  button: {
    search: "搜索",
  },
  tagsView: {
    clear: "清空",
    input: "请输入",
    choose: "请选择",
    handle: "操作",
    Single_Select: "单选",
    order: "排序",
    noData: "暂无数据",
    Header_Set:"列设置",
  },
  components: {
    shrink: "收起",
    unfold: "展开",
  },
  global: {
    add: "新建",
    edit: "编辑",
    delete: "删除",
    import: "导入",
    export: "导出"
  }

simple-table

简单表格页面提供展示表格数据的页面, 以及导入、导出、新增、编辑、删除操作。

示例

<template>
  <simple-table
    :tableTitle="tableTitle"
    :columns="computedColumns"
    :toolbar-opts="toolbarOpts"
    :apiList="getList"
    :importBtn="importBtn"
    :exportBtn="exportBtn"
    :addBtn="addBtn"
    @searchChange="onSearchChange"
    ref="simpleTable"
    class="mall-product"
  >
    <template #header-operator-pre>
      <el-button
        size="mini"
        class="btn-title"
        type="primary"
        @click="navTo(true)"
        :disabled="!canEdit"
        v-permission="['accounts:explosion-pile:list:edit']"
        >{{ $t("global.edit") }}</el-button
      >
    </template>
  </simple-table>
</template>
<script>
import { columns, toolbarOpts } from "./crud";
import {
  getExplosionPileList,
  exportExplosivePile,
} from "@/api/account-explosion";
import dayjs from "dayjs";
export default {
  data() {
    return {
      dynamicColumns: [],
      columns,
      exportBtn: {
        permission: ["accounts:explosion-pile:list:export"],
        api: exportExplosivePile,
      },
      importBtn: {
        permission: ["accounts:explosion-pile:list:import"],
        importType: "explosionPile",
      },
      addBtn: {
        permission: "none", // none表示没有权限控制,所有人都可以使用
        func: () => {
          this.navTo(false);
        },
      },
      toolbarOpts,
      canEdit: false,
      tableTitle: `${this.$t("accounts.explosion.Explosion_Title")} ${this.$t(
        "accounts.explosion.Current_Check"
      )}  --`,
    };
  },
  computed: {
    computedColumns() {
      let cols = this.columns.slice(0);
      let dynamicColumns = this.dynamicColumns.slice(0);
      const list = dynamicColumns.map((item) => ({
        prop: item.prop,
        label: item.label,
      }));
      console.log([...cols, ...list], "computedColumns");
      return [...cols, ...list];
    },
  },
  methods: {
    onSearchChange(newVal) {
      this.tableTitle = `${this.$t(
        "accounts.explosion.Explosion_Title"
      )} ${this.$t("accounts.explosion.Current_Check")}  ${
        newVal.explosivePileDate || "--"
      }`;
    },
    navTo(data) {
      const date = data
        ? this.$refs.simpleTable.search.explosivePileDate
        : dayjs().format("YYYY-MM-DD");
      this.$router.push({
        path: data
          ? "/accounts/explosion-pile/edit"
          : "/accounts/explosion-pile/add",
        query: {
          date,
        },
      });
    },
    getList(param) {
      return getExplosionPileList(param).then((res) => {
        this.canEdit = res.data?.data?.length > 0 || false;
        this.dynamicColumns = res.data?.dynamicHeaders || [];
        return res;
      });
    },
  },
  mounted() {
    this.$refs.simpleTable.search.explosivePileDate =
      dayjs().format("YYYY-MM-DD");
    this.$refs.simpleTable.table.pageShow = false;
  },
};
</script>
<style lang="scss" scoped>
.btn-title {
  color: #ffffff;
  background: var(--color-primary);
  border-color: var(--color-primary);
  margin-left: 10px;
  margin-bottom: 1px;
  padding: 5px 15px;
}
::v-deep .el-date-editor .el-input__inner {
  padding-left: 25px !important;
}
</style>

attributes:

  props: {
    /**
     * 获取数据的接口
     */
    apiList: {
      type: Function,
    },
    /**
     * 格式化搜索选项
     */
    formatSearch: {
      type: Function,
    },
    /**
     * 导入按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则跳转导入页面), importType(默认跳转行为的导入类型)
     */
    importBtn: Object,
    /**
     * 导出按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则使用apiExport执行默认导出), api
     */
    exportBtn: Object,
    /**
     * 添加按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则跳转添加页面), route(默认跳转的路由)
     */
    addBtn: Object,
    /**
     * 编辑按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则用route执行默认跳转), route
     */
    editBtn: Object,
    /**
     * 删除按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则用api执行默认删除), api
     */
    deleteBtn: Object,
  },

Events:

  • searchChange: 查询控件的 Input 事件时触发

Slots:

  • header-operator-pre: 标题栏搜索控件后、导入导出按钮前的插槽
  • header-operator-post: 标题栏导入导出按钮后的插槽
  • row-operator-pre: 行操作编辑、删除之前的插槽
  • row-operator-post: 行操作编辑、删除之后的插槽

main-sub-table

主子表格页面提供展示左侧主表概览,右上主数据描述,右下子表的页面。 以及导入、导出、新增、编辑、删除操作。

示例:

<template>
  <main-sub-table
    title="穿孔记录"
    :mainColumns="mainColumns"
    :subColumns="subColumns"
    :apiMainList="apiMainList"
    :apiSubList="apiSubList"
    :importBtn="importBtn"
    :exportBtn="exportBtn"
    :addBtn="addBtn"
    :editBtn="editBtn"
    :deleteBtn="deleteBtn"
    :formatSearch="formatSearch"
  >
  </main-sub-table>
</template>

<script>
import { mainColumns, subColumns } from "./adCrud.js";
import { getUnit } from "@/utils";
import {
  apiGetPuncherList,
  apiDeletePuncher,
  apiExportPuncher,
  detailPuncherLoadItemList,
} from "@/api/account-puncher";
import { getDeviceList } from "@/api/auxiliary";

import { Equipment_Classify_Puncher } from "@/const/index";

export default {
  name: "accounts-puncher-list",
  data() {
    return {
      deviceList: [],
      currentRoute: null,
      totalDepthLabel: "",
      totalVolumeLabel: "",
      itemDepthLabel: "",
      itemVolumnLabel: "",
      importBtn: {
        permission: ["accounts:puncher:list:import"],
        importType: "puncher",
      },
      exportBtn: {
        permission: ["accounts:puncher:list:export"],
        api: apiExportPuncher,
      },
      addBtn: {
        permission: ["accounts:puncher:list:add"],
        route: "/accounts/puncher/add",
      },
      apiMainList: apiGetPuncherList,
      apiSubList: detailPuncherLoadItemList,
      editBtn: {
        permission: ["accounts:puncher:list:edit"],
        route: "/accounts/puncher/edit",
      },
      deleteBtn: {
        permission: ["accounts:puncher:list:delete"],
        api: apiDeletePuncher,
      },
    };
  },
  computed: {
    mainColumns() {
      let res = [...mainColumns];
      for (let i = 0, len = res.length; i < len; i++) {
        let col = res[i];
        if (col.prop === "deviceName") {
          col.search.bind.optionSource = this.deviceList;
        }
        if (col.prop === "totalPenetrationDepth") {
          col.label = this.totalDepthLabel;
        }
        if (col.prop === "totalPenetrationVolume") {
          col.label = this.totalVolumeLabel;
        }
      }
      return res;
    },
    subColumns() {
      let res = [...subColumns];
      for (let i = 0, len = res.length; i < len; i++) {
        let col = res[i];
        if (col.prop === "penetrationDepth") {
          col.label = this.itemDepthLabel;
        }
        if (col.prop === "penetrationVolume") {
          col.label = this.itemVolumnLabel;
        }
      }
      return res;
    },
  },
  methods: {
    formatSearch(example) {
      if (!!example.workDate && example.workDate.length > 0) {
        example.workDateStart = example.workDate[0];
        example.workDateEnd = example.workDate[1];
      } else {
        delete example.workDateStart;
        delete example.workDateEnd;
      }
      return example;
    },
    initLabelWithUnit() {
      this.totalDepthLabel = this.$t("accounts.puncher.Total_Puncher_Depth");
      this.totalVolumeLabel = this.$t("accounts.puncher.Total_Puncher_Volume");
      this.itemDepthLabel = this.$t("accounts.puncher.Puncher_Depth");
      this.itemVolumnLabel = this.$t("accounts.puncher.Puncher_Volume");
      this.currentRoute = this.$route.path;
      let tmpData = JSON.parse(localStorage.getItem("unitConfigs"));
      if (Object.keys(tmpData).length !== 0) {
        const mainDepthConfig =
          tmpData[this.currentRoute]["/mmes/punchingBook/list"][
            "data.totalPenetrationDepth"
          ];
        const mainVolumeConfig =
          tmpData[this.currentRoute]["/mmes/punchingBook/list"][
            "data.totalPenetrationVolume"
          ];
        if (mainDepthConfig?.category) {
          this.totalDepthLabel += `(${mainDepthConfig.symbol})`;
        }
        if (mainVolumeConfig?.category) {
          this.totalVolumeLabel += `(${mainVolumeConfig.symbol})`;
        }
        const subDepthConfig =
          tmpData[this.currentRoute]["/mmes/punchingBook/listByParent"][
            "penetrationDepth"
          ];

        const subVolumeConfig =
          tmpData[this.currentRoute]["/mmes/punchingBook/listByParent"][
            "penetrationVolume"
          ];

        if (subDepthConfig?.category) {
          this.itemDepthLabel += `(${subDepthConfig.symbol})`;
          this.itemVolumnLabel += `(${subVolumeConfig.symbol})`;
        }
      } else {
        this.totalDepthLabel += `(${getUnit("length")})`;
        this.totalVolumeLabel += `(${getUnit("volume")})`;
        this.itemDepthLabel += `(${getUnit("length")})`;
        this.itemVolumnLabel += `(${getUnit("volume")})`;
      }
    },
  },
  mounted() {
    this.initLabelWithUnit();
    getDeviceList({ deviceClassifyIds: [Equipment_Classify_Puncher] }).then(
      (res) => {
        this.deviceList = res.data.map((x) => ({
          id: x.id,
          name: x.assetName || x.deviceCode,
        }));
      }
    );
  },
};
</script>

attributes

  props: {
    /**
     * 标题
     */
    title: String,
    /**
     * 访问主列表的api
     */
    apiMainList: {
      type: Function,
    },
    /**
     * 访问子列表的api
     */
    apiSubList: {
      type: Function,
    },
    /**
     * 导入按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则跳转导入页面), importType(默认跳转的参数)
     */
    importBtn: Object,
    /**
     * 导出按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则使用apiExport执行默认导出), api
     */
    exportBtn: Object,
    /**
     * 添加按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则跳转添加页面), route(默认跳转的路由)
     */
    addBtn: Object,
    /**
     * 格式化搜索选项
     */
    formatSearch: {
      type: Function,
    },
    /**
     * 主列表的配置
     */
    mainColumns: {
      type: Array,
    },
    /**
     * 子列表的配置
     */
    subColumns: { type: Array },
    /**
     * 编辑按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则用route执行默认跳转), route
     */
    editBtn: Object,
    /**
     * 删除按钮的相关配置,包括hidden(未提供时默认显示),permission, func(提供时优先执行该方法,否则用api执行默认删除), api
     */
    deleteBtn: Object,
  },

adaptive-page

和之前的 adaptive-page 兼容。

增加 toolbarOpts 属性, toolbarOpts 中提供的内容与 opts 一致, 但 toolbarOpts 提供的搜索会与标题栏出现在同一行。

列设置

在 adaptive-page 组件上, 打开 columnSetting 开关。

@/api/index.js中, 增加列配置接口访问方法:

// 根据参数查询用户菜单的列表信息
export function querySysTableRecord(data) {
  return request({
    url: "/component/sysTableRecord/querySysTableRecord",
    method: "post",
    data,
  });
}

// 新增或者修改用户的菜单信息
export function addOrUpdateSysTableRecord(data) {
  return request({
    url: "/component/sysTableRecord/addOrUpdateSysTableRecord",
    method: "post",
    data,
  });
}

@/store/modules/user.js中, 进行如下改动:

@/api中引入 querySysTableRecord、addOrUpdateSysTableRecord 方法:

import {
  querySysTableRecord,
  addOrUpdateSysTableRecord,
} from "@/api";

getDefaultState 中增加 tableColumn 字段:

const getDefaultState = () => {
  return {
    token: getToken(),
    user: {},
    roles: [],
    tenants: [],
    tableColumn: [], // 表格列
  };
};

在 mutations 中增加 SET_TABLE_COLUMN 方法:

const mutations = {
  ...

  // 设置表格列
  SET_TABLE_COLUMN: (state, payload) => {
    state.tableColumn = payload;
  },
};

在 actions 中增加 querySysTableRecord、saveTableColumn 方法:

const actions = {
  ...

  // 查询表格列
  querySysTableRecord({ commit }) {
    return new Promise((resolve, reject) => {
      console.log(state, "state-----------");
      querySysTableRecord({
        queryDefaultFlag: state.menuListConfig,
      })
        .then((res) => {
          // 先根据系统配置是否为1,1表列名为defaultConfigList,否则为userConfigList,当配置为用户时并且userConfigList为空,表列名为defaultConfigList
          const tableColumn =
            state.menuListConfig === "1"
              ? res.data.defaultConfigList
              : res.data.userConfigList.length
              ? res.data.userConfigList
              : res.data.defaultConfigList;
          commit("SET_TABLE_COLUMN", tableColumn);
          resolve(res.data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  },
  // 保存表格列
  saveTableColumn({ commit }, params) {
    return addOrUpdateSysTableRecord({ ...params });
  },
};

@/store/getters.js的 getters 中, 添加 tableColumn:

const getters = {
  tableColumn: (state) => state.user.tableColumn,
};