1.0.27 • Published 12 months ago

@junhe/common-table v1.0.27

Weekly downloads
-
License
-
Repository
-
Last release
12 months ago

使用前准备

要确保项目中使用的 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>
1.0.27

12 months ago

1.0.25

12 months ago

1.0.24

12 months ago

1.0.23

12 months ago

1.0.22

12 months ago

1.0.21

12 months ago

1.0.20

12 months ago

1.0.19

12 months ago

1.0.18

12 months ago

1.0.17

12 months ago

1.0.16

12 months ago

1.0.15

12 months ago

1.0.14

12 months ago

1.0.13

12 months ago

1.0.12

12 months ago

1.0.11

12 months ago

1.0.10

12 months ago

1.0.9

12 months ago

1.0.8

12 months ago

1.0.7

12 months ago

1.0.6

12 months ago

1.0.5

12 months ago

1.0.4

12 months ago

1.0.3

12 months ago

1.0.2

12 months ago

1.0.1

12 months ago

1.0.0

12 months ago