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

@junhe/common-table

v1.0.27

Published

要确保项目中使用的 Vue2 版本为 2.6.14,步骤如下:

Downloads

99

Readme

使用前准备

要确保项目中使用的 Vue2 版本为 2.6.14,步骤如下:

  • 在 package.json 中:

    • "vue": "^2.6.14" 改为 "vue": "2.6.14",

    • "vue-template-compiler": "^2.6.14" 改为 "vue-template-compiler": "2.6.14"

  • 然后删除项目中的 node_modules 和 package-lock.json

  • 最后重新安装一下依赖:npm install

使用说明书(FlexibleTableIntegration.vue)

外部可以调用的方法

refreshTableRows 刷新表格内容数据

resetCurrPageAndRefreshTableRows 重置当前页码到第一页,并刷新表格内容数据

addFormRow 添加一行新的表单行

addNewRows 添加一或多行新的普通数据行

getRowMultiSelection 获取所有被多选列勾选的数据

setRowMultiSelection 设置多选列的选中状态

getRowSingleSelection 获取被单选列选中的数据

setRowSingleSelection 设置单选列的选中状态

对外抛出的事件

cell-click 当表格的可点击单元格被点击时

column-button-click 当表格中的图标列的单元格被点击时

cell-corner-tip-click 当表格的单元格右上角的提示性按钮被点击时

row-multi-select 当多选列的选中状态被改变时

text-search 当搜索框有改变并确认时

selection-list-change 当筛选栏的当前筛选器的筛选项被选中或取消时

Props

| 属性名 | 解释 | |----------------------|------------------------------------------------------| | baseURL | 后端地址(指定本值,主要用于测试用途) | | normalTabs | 标签列表 | | extraTabs | 不显示本页内容的标签 | | defaultTabIndex | 默认显示的标签的序号 | | operationWidth | 操作按钮列的宽度 | | cardWidth | 卡片视图下卡片的宽度 | | moduleName | 模块名称(传给后端) | | hasDataOverview | 是否有数据概览 | | hasClassification | 是否有标签栏 | | defaultFilterIndex | 默认打开第几个单列条件选择器(从0开始) | | hasCheckboxColumn | 是否有多选列 | | isSelectionReserved | 换页时,是否保持之前的选择 | | hasDataStatistics | 是否有统计数据 | | hasExportData | 是否有导出表格数据的功能按钮 | | hasOperation | 是否有操作按钮 | | hasViewSwitcher | 是否有表格视图和卡片视图的切换功能 | | hasSideFilter | 是否有侧边筛选栏 | | formCellUpdateType | 表格型单元格的更新类型 | | defaultView | 默认的视图 | | confirmCellSelection | 表格中的下拉框单元格的下拉列表的某一项被选中时的回调 |

使用方法示例

<template>
  <div class="test-flexible-table">
    <div class="module-btns">
      <ElButton
        :type="moduleName === '模块1' ? 'primary' : 'default'"
        size="mini"
        @click="onModuleBtnClick(1)"
        >模块1</ElButton
      >
      <ElButton
        :type="moduleName === '模块2' ? 'primary' : 'default'"
        size="mini"
        @click="onModuleBtnClick(2)"
        >模块2</ElButton
      >
    </div>
    <div class="flexible-table-container">
      <FlexibleTableIntegration
        ref="flexibleTableIntegration"
        :baseURL="baseURL"
        :normalTabs="NORMAL_TABS"
        :extraTabs="EXTRA_TABS"
        :defaultTabIndex="DEFAULT_TAB_INDEX"
        :operationWidth="100"
        :cardWidth="300"
        :moduleName="moduleName"
        :hasDataOverview="false"
        :hasClassification="false"
        :defaultFilterIndex="2"
        :hasCheckboxColumn="isMultiSelection"
        :hasRadioColumn="!isMultiSelection"
        :isSelectionReserved="true"
        :hasExportData="true"
        :hasOperation="true"
        :hasViewSwitcher="true"
        :hasSideFilter="true"
        :defaultSideFilterVisible="true"
        :defaultView="'table'"
        :confirmCellSelection="confirmCellSelection"
        @cell-click="onBodyCellClick"
        @cell-corner-tip-click="onBodyCellCornerTipClick"
        @column-button-click="onColumnButtonClick"
        @row-multi-select="onRowMultiSelect"
      >
        <template v-slot:operation="row">
          <OperationButton
            :name="'op1'"
            :title="'操作1'"
            :row="row"
            :hasIcon="true"
            :maxTitleCount="3"
            @btn-click="onOperationBtnClick"
          >
            <!-- <template v-slot:icon>
              <IconFilter :size="12" />
            </template> -->
          </OperationButton>

          <!-- <OperationDropdown>
            <OperationDropdownItem
              :name="'op4'"
              :title="'操作4'"
              :row="row"
              :hasIcon="false"
              @item-click="onOperationBtnClick"
            ></OperationDropdownItem>
            <OperationDropdownItem
              :name="'op5'"
              :title="'操作5'"
              :row="row"
              :hasIcon="true"
              @item-click="onOperationBtnClick"
            >
              <template v-slot:icon>
                <IconFilter :size="12" />
              </template>
            </OperationDropdownItem>
            <OperationDropdownItem
              :name="'op6'"
              :title="'操作6'"
              :row="row"
              :hasIcon="true"
              @item-click="onOperationBtnClick"
            >
              <template v-slot:icon>
                <IconFilter :size="12" />
              </template>
            </OperationDropdownItem>
          </OperationDropdown> -->
        </template>

        <template v-slot:midbar>
          <ElSwitch
            :style="{ width: '132px' }"
            v-model="isMultiSelection"
            active-text="多选"
            inactive-text="单选"
          >
          </ElSwitch>
          <ElButton type="primary" size="small" @click="onGetSelectClick"
            >获取选择</ElButton
          >
          <ElButton type="primary" size="small" @click="onSetSelectClick"
            >尝试选择</ElButton
          >
        </template>
        11
        <template v-slot:card="{ row }">
          <CardTemplate
            class="my-card"
            :height="200"
            :imgSrc="'https://youimg1.c-ctrip.com/target/100r10000000pycel4E0E.jpg'"
          >
            <template v-slot:header>{{ row["type_row_id"] }}</template>
            <template v-slot:details>
              <div class="rows">
                <div class="row">
                  <span>{{ row["type_string2"] }}</span>
                </div>

                <OverflowTooltip :content="row['type_string']">
                  <div class="row">
                    <span>{{ row["type_string"] }}</span>
                  </div>
                </OverflowTooltip>

                <div class="row">
                  <span>{{ row["type_merge_str"] }}</span>
                </div>
              </div>
            </template>
          </CardTemplate>
        </template>

        <template v-slot:button-column-icon="{ iconClass, data }">
          <template v-if="iconClass === 'plus'">
            <IconAdd />
          </template>
          <template v-else-if="iconClass === 'copy'">
            <IconCopy />
          </template>
          <template v-else-if="iconClass === 'edit'">
            <IconEdit />
          </template>
          <template v-else-if="iconClass === 'comment-btn'">
            <IconComment />
          </template>
          <template v-else-if="iconClass === 'receivable-node-btn'">
            <template v-if="Array.isArray(data)">
              <template v-for="(node, index) in data">
                <IconTextCircle
                  :key="index"
                  :text="node['name']"
                  :active="node['active']"
                />
              </template>
            </template>
          </template>
          <template v-else-if="iconClass === 'alert-btn'">
            <IconAlertSign :text="'已有风险'" />
            <!-- <template v-for="(node, index) in data">
              </template> -->
          </template>
          <template v-else></template>
        </template>

        <!-- <template v-slot:cell-bottom="{ row, col }">
          <div
            class="my-progress-bar"
            v-if="col.id === 'type_number' && row['type_row_id']"
          >
            <el-progress
              :text-inside="true"
              :stroke-width="8"
              :percentage="70"
            ></el-progress>
          </div>
        </template> -->

        <!-- <template v-slot:cell-left="{ row, col }">
          <div
            class="my-tip"
            v-if="col.id === 'type_number' && row['type_row_id']"
          ></div>
        </template> -->

        <template v-slot:form-cell="{ row, col }">
          <template v-if="col.id === 'icon_col_1'">
            <div class="my-form-cell">
              <template v-if="typeof row[col.id] === 'string'">
                <div class="my-column-icon" :style="{ cursor: 'pointer' }">
                  <Icon
                    :size="24"
                    :iconBaseUrl="row[col.id]"
                    @click.native="onFormCellBtnEditClick(row, col)"
                  />
                </div>
              </template>
              <template v-else>
                <ElButton
                  type="text"
                  size="mini"
                  @click="onFormCellBtnEditClick(row, col)"
                  >自定义功能</ElButton
                >
              </template>
            </div>
          </template>
        </template>
      </FlexibleTableIntegration>
    </div>

    <ElDialog
      class="my-dial-icon-selection"
      title="提示"
      :visible.sync="isIconDialVisible"
      width="30%"
    >
      <div class="content">
        <div :style="{ marginBottom: '16px' }">在此选择头像</div>
        <div>
          <template v-for="(url, index) in iconUrls">
            <Icon
              class="user-icon"
              :style="{ cursor: 'pointer', marginRight: '16px' }"
              :key="index"
              :iconBaseUrl="url"
              @click.native="onDialIconClick(url)"
            />
          </template>
        </div>
      </div>

      <span slot="footer" class="dialog-footer">
        <el-button @click="isIconDialVisible = false">取 消</el-button>
        <el-button type="primary" @click="isIconDialVisible = false"
          >确 定</el-button
        >
      </span>
    </ElDialog>
  </div>
</template>
<script>
import Vue from "vue";
import {
  Button as ElButton,
  // Progress as ElProgress,
  Dialog as ElDialog,
  Switch as ElSwitch,
} from "element-ui";

import {
  FlexibleTableIntegration,
  CardTemplate,
  OperationButton,
  // OperationDropdown,
  // OperationDropdownItem,
  OverflowTooltip,
  Icon,
  IconAdd,
  IconCopy,
  IconEdit,
  IconComment,
  IconTextCircle,
  IconAlertSign,
  // IconFilter,
  // BaseColumn,
  // Column,
  ButtonColumn,
  // IconColumn,
  // KeyValuePair,
} from "@junhe/common-table";

const NORMAL_TABS = [
  { name: "tab-name-1", label: "标签1" },
  { name: "tab-name-2", label: "标签2" },
  { name: "tab-name-3", label: "标签3" },
];

const EXTRA_TABS = [{ name: "board", label: "看板" }];

const DEFAULT_TAB_INDEX = 0;

export default Vue.extend({
  name: "TestWithFakeData",
  components: {
    ElButton,
    // ElProgress,
    ElDialog,
    ElSwitch,
    IconAdd,
    IconCopy,
    IconEdit,
    IconComment,
    IconTextCircle,
    IconAlertSign,
    // IconFilter,
    FlexibleTableIntegration,
    CardTemplate,
    OperationButton,
    // OperationDropdown,
    // OperationDropdownItem,
    OverflowTooltip,
    Icon,
  },
  data() {
    return {
      moduleName: "模块1",
      NORMAL_TABS,
      EXTRA_TABS,
      DEFAULT_TAB_INDEX,

      baseURL: "http://220.168.85.72:10930",
      // baseURL: "http://localhost:10930",

      isIconDialVisible: false,
      iconUrls: [
        "http://220.168.85.72:3000/avatars/d73d86c441955bd24b89577835608fa3?size=512",
        "http://220.168.85.72:3000/avatars/e47e9a540465ff1cc530b46afa573c6e?size=512",
      ],
      currCellInfo: {
        row: {},
        col: {},
      },

      isMultiSelection: false, // 是显示多选列还是单选列
    };
  },
  computed: {
    iconStyle() {
      const size = 12;
      return { width: `${size}px`, height: `${size}px` };
    },
  },
  methods: {
    onModuleBtnClick(flag) {
      this.moduleName = `模块${flag}`;
    },
    // 表格操作列中的某个按钮被点击
    onOperationBtnClick(row, name) {
      console.log("row, name :>> ", row, name);
    },
    // 当表格的可点击单元格被点击时
    onBodyCellClick(row, col) {
      console.log("row, col :>> ", row, col);
    },
    // 当表格中的图标列的单元格被点击时
    onColumnButtonClick(row, col, insideBtnCol) {
      const refTb = this.$refs["flexibleTableIntegration"];

      if (col instanceof ButtonColumn) {
        // 属于独立按钮列
        switch (col.iconClass) {
          case "comment-btn": {
            // 复制一遍 row,然后添加到表格中
            const newRow = JSON.parse(JSON.stringify(row));
            newRow.id = `id-${Math.random()}`;
            newRow.type_merge_str = `${Math.floor(Math.random() * 1000)}`;
            refTb.addNewRows(row, [newRow]);
            break;
          }
          case "receivable-node-btn": {
            console.log("receivable-node-btn", row);
            break;
          }
          default:
            break;
        }
      } else {
        // 属于内置按钮列
        switch (insideBtnCol.iconClass) {
          case "plus": {
            refTb.addFormRow(row, "new", {
              submissionExceptionClassNames: ["my-dial-icon-selection"],
            });
            break;
          }
          case "copy": {
            refTb.addFormRow(row, "copy", {
              submissionExceptionClassNames: ["my-dial-icon-selection"],
            });
            break;
          }
          default:
            break;
        }
      }
    },
    // 当表格的单元格右上角的提示性按钮被点击时
    onBodyCellCornerTipClick(row, col) {
      console.log("row, col :>> ", row, col);
    },
    // 当多选列的选中状态被改变时
    onRowMultiSelect(selection) {
      console.log("selection :>> ", selection);
    },
    /**
     * 表格中的下拉框单元格 -> 下拉列表的某一项被选中时的回调
     * @param resolve resolve(true) 代表确认选择,resolve(false) 代表取消选择
     */
    confirmCellSelection(row, column, item, resolve) {
      console.log("row, column, item :>> ", row, column, item);
      setTimeout(() => {
        resolve(true);
      }, 1000);
    },
    onGetSelectClick() {
      const refTb = this.$refs["flexibleTableIntegration"];

      let selection;
      if (this.isMultiSelection) {
        selection = refTb.getRowMultiSelection();
      } else {
        selection = refTb.getRowSingleSelection();
      }

      console.log("当前选择的行 :>> ", selection);
    },
    onSetSelectClick() {
      const refTb = this.$refs["flexibleTableIntegration"];

      if (this.isMultiSelection) {
        refTb.setRowMultiSelection(["id-2", "id-3"]);
      } else {
        refTb.setRowSingleSelection("id-2");
      }
    },
    onFormCellBtnEditClick(row, col) {
      console.log("col :>> ", col);
      this.currCellInfo = { row, col };
      this.isIconDialVisible = true;
    },
    onDialIconClick(url) {
      const { row, col } = this.currCellInfo;

      if (row && col) {
        console.log("row, col :>> ", row, col);
        row[col.id] = url;
      }
    },
  },
});
</script>
<style lang="scss" scoped>
.test-flexible-table {
  width: 100%;
  height: 100%;

  $module-btns-height: 32px;

  .module-btns {
    box-sizing: border-box;
    width: 100%;
    height: $module-btns-height;
    border-bottom: 1px solid #eee;
  }

  .flexible-table-container {
    box-sizing: border-box;
    width: 100%;
    height: calc(100% - $module-btns-height);
  }

  .my-progress-bar {
    width: 100%;
  }

  .my-card {
    .rows {
      box-sizing: border-box;
      width: 100%;
      height: 100%;
      padding: 8px 0;

      .row {
        width: 100%;
        height: 28px;
        line-height: 28px;
      }
    }
  }

  .my-form-cell {
    .my-column-icon {
    }
  }

  .my-dial-icon-selection {
  }
}
</style>