当前位置:   article > 正文

Vue2虚拟列表,umy-ui封装

umy-ui

一、起因

1、需求: 由于业务需求在页面一次性展示较多数据,不低于上千,但是每条数据涉及样式较多,数据渲染过多就会导致页面卡顿
2、满足: 大量数据加载;表格功能:列显隐、列顺序调整、固定、筛选、排序;表格调整存储本地
3、技术框架: 若依、Element UI、vue2

二、umy-ui

1、umy-ui库中的table表格组件,它不造轮子。它改造了element-ui等等库的表格组件。只为了免费解决前端小伙伴的问题。

2、用前须知(这是关于表格的须知,你应该认真读完下面的内容)

 1. 表格解决卡顿问题,那么虚拟表格原理呢大概就是: 减少对DOM节点的渲染,通过滚动函数节流实现滚动后事件来动态渲染数据

 2. 基础表格其实就是element的表格的升级版,修改了ele的表格bug(如果你想使用个普通表格你无需安装其他库,就使用这个表格即可),你可以发现基础表格里面的示例没有配置:use-virtual 这个属性。

 3 基础表格没有使用use-virtual属性,代表表格数据不多,只想要一个普通的表格。如果你表格卡。请你关注下虚拟表格部分。

 4. 使用u-table 开启use-virtual虚拟可以支持微小的合并行|列 如2列 2行,支持多级头, 超过2行2列可能布局错乱,因为虚拟滚动的原理导致某些节点并未渲染。
 
 	4.5 使用u-table 开启use-virtual不支持开展行,如果需要展开行,你是要虚拟表格部分的ux展开行!

 5. u-table不支持展开行,需要展开行使用ux-grid
 
 6. ux-grid解决列多 行多导致卡的情况, u-table解决行多的情况,不解决列多的情况(如你的列超过70+,你可能就需要使用ux-grid了,因为此时你需要把列也虚拟)

 7. 重点:虚拟表格集成了基础表格的东西(如属性/方法/事件)!

 8. 虚拟表格在本文档中呢, 意思就是解决了数据量多导致卡顿的情况! 基础表格在文档中呢,意思就是升级版的el-table(但是没解决数据多卡的情况)!

 9. 编辑型表格呢,是解决那种表格单元带有输入框或者选择时间等等的情况,而导致卡顿的场景!意思就是表格单元格具有一定的操作,单元格有自定义组件或者UI库组件等等

 10. 有了表格,怎么导出表格数据为excel并且带样式呢?,[请点击](https://github.com/livelyPeng/pl-export-excel)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

三、安装引入

1.安装
推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用

 npm install umy-ui
  • 1

2.引入
main.js

// 引入umy-ui
import UmyUi from 'umy-ui'

Vue.use(UmyUi);
  • 1
  • 2
  • 3
  • 4

三、封装

以下代码是基于若依框架封装的主代码,其余见附带资源中,对应表格中输入或展示形式可自行封装:

<script>
export default {
  name: "SuperUxTable",
  props: {
    // 数据
    value: {
      type: [Array],
      require: true,
    },
    // 字典
    dict: {
      type: [Object],
      require: true,
    },
    // 分页
    page: {
      type: [Object],
      require: false,
    },
    // 模板
    columns: {
      type: [Array],
      require: true,
    },
    // 是否显示序号
    index: {
      type: Boolean,
      default: false,
    },
    // 是否显示单选
    radio: {
      type: Boolean,
      default: false,
    },
    // 是否显示多选
    checkbox: {
      type: Boolean,
      default: false,
    },
    // 是否显示分页
    pagination: {
      type: Boolean,
      default: false,
    },
    // 是否列操作
    convenitentOperation: {
      type: Boolean,
      default: false,
    },
    // 是否禁止选择
    selectable: {
      type: Function,
      default: () => {},
    },
    //
    storageKey: {
      type: String,
    },
    showSummary: {
      type: Boolean,
      default: false,
    },
    height: {
      type: [String, Number],
      require: false,
    },
    firstSummary: {
      type: Boolean,
      default: false,
    },
  },
  components: {
    ElDictTag: () => import("@/components/DictTag/index.vue"),
    ElDraggable: () => import("@/components/draggable/index.vue"),
    ElFilePreview: () => import("@/components/file-preview/index.vue"),
    ElComputedInput: () => import("@/components/computed-input/index.vue"),
    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
    ElPopoverMultipleSelectV2: () =>
      import("@/components/popover-select-v2/multiple.vue"),
    ElComputedInputV2: () => import("@/components/computed-input-v2/index.vue"),
    ElPopoverTreeSelect: () =>
      import("@/components/popover-tree-select/index.vue"),
    ButtonHide: () => import("./hide.vue"),
    ButtonFreeze: () => import("./freeze.vue"),
    IconHide: () => import("./once/hide.vue"),
    IconSort: () => import("./once/sort.vue"),
    IconFreeze: () => import("./once/freeze.vue"),
    IconFilter: () => import("./once/filters.vue"),
  },
  data() {
    const { columns, storageKey } = this.$props;
    const localColumns = localStorage.getItem(storageKey);
    const innerColumns =
      storageKey && localColumns
        ? JSON.parse(localColumns)
        : columns.map(({ item, attr }) => ({
            attr,
            item: { hidden: true, ...item },
          }));
    return {
      innerColumns: innerColumns,
      rowKey: "id",
      // 选择
      selectData: [],
      selectState: false,
      // 过滤
      filterData: [],
      filterState: false,
      count: 0,
      scrollTop: 0,
      resizeHeight: 0,
    };
  },
  computed: {
    innerValue: {
      get() {
        if (this.filterState) {
          return this.filterData;
        } else if (this.selectState) {
          return this.selectData;
        } else {
          return this.$props.value;
        }
      },
      set(value) {
        this.$emit("input", value);
      },
    },
    showColumns: {
      get() {
        return this.innerColumns.filter(({ item }) => item.hidden);
      },
      set() {},
    },
    filterRules: {
      get() {
        return Object.fromEntries(
          this.innerColumns
            .filter(({ item }) => item.filter && !!item.filter.length)
            .map(({ item }) => [item.key, item.filter])
        );
      },
      set() {},
    },
    tableHeight: {
      get() {
        let { height } = this.$props;
        return height ? height : this.resizeHeight;
      },
      set() {},
    },
  },
  watch: {
    filterRules: {
      handler: function (newValue) {
        function multiFilter(array, filters) {
          const filterKeys = Object.keys(filters);
          // filters all elements passing the criteria
          return array.filter((item) => {
            // dynamically validate all filter criteria
            return filterKeys.every((key) => {
              //ignore when the filter is empty Anne
              if (!filters[key].length) return true;
              return !!~filters[key].indexOf(item[key]);
            });
          });
        }
        this.filterState = JSON.stringify(newValue) !== "{}";
        this.filterData = multiFilter(this.$props.value, newValue);
      },
    },
    value: {
      handler: function (newValue) {
        if (this.value.length > 0) {
          this.$refs.superUxTable && this.$refs.superUxTable.clearSelection();
        }
      },
      immediate: true,
      deep: true,
    },
  },
  directives: {
    // 使用局部注册指令的方式
    resize: {
      // 指令的名称
      bind(el, binding) {
        // el为绑定的元素,binding为绑定给指令的对象
        let width = "",
          height = "";
        function isReize() {
          const style = document.defaultView.getComputedStyle(el);
          if (width !== style.width || height !== style.height) {
            binding.value(); // 关键
          }
          width = style.width;
          height = style.height;
        }
        el.__vueSetInterval__ = setInterval(isReize, 300);
      },
      unbind(el) {
        clearInterval(el.__vueSetInterval__);
      },
    },
  },
  methods: {
    resize() {
      this.resizeHeight =
        document.getElementsByClassName("el-super-ux-table")[0].offsetHeight -
        55;
    },
    //
    onSelectionChange(value) {
      this.selectData = value;
      this.$emit("row-select", this.selectData);
    },
    //
    onRowClick(row, column, event) {
      const { radio, checkbox } = this.$props;
      // 单选
      if (radio) {
        this.$emit("row-select", [row]);
      }
      // 多选
      if (checkbox) {
        this.$refs.superUxTable.toggleRowSelection([
          this.innerValue.find((item) => item.id === row.id),
        ]);
      }
    },
    // 宽度
    onWidth({ column }) {
      this.innerColumns = this.innerColumns.map(({ item, attr }) => ({
        attr,
        item: {
          ...item,
          width: item.key === column.property ? column.resizeWidth : item.width,
        },
      }));
      if (this.$props.storageKey) {
        localStorage.setItem(
          this.$props.storageKey,
          JSON.stringify(this.innerColumns)
        );
      }
    },
    // 隐藏
    onHide(prop) {
      this.$nextTick(() => {
        this.$refs.superUxTable.doLayout();
        if (this.$props.storageKey) {
          localStorage.setItem(
            this.$props.storageKey,
            JSON.stringify(this.innerColumns)
          );
        }
      });
    },
    // 排序
    onSort(prop) {
      const { key, sort } = prop;
      console.log(key, "key", sort, "sort");
      this.$nextTick(() => {
        this.$refs.superUxTable.sort(key, sort);
        this.$refs.superUxTable.doLayout();
        if (this.$props.storageKey) {
          localStorage.setItem(
            this.$props.storageKey,
            JSON.stringify(this.innerColumns)
          );
        }
      });
    },
    // 冻结
    onFreeze() {
      this.$nextTick(() => {
        this.$refs.superUxTable.doLayout();

        if (this.$props.storageKey) {
          localStorage.setItem(
            this.$props.storageKey,
            JSON.stringify(this.innerColumns)
          );
        }
        this.count++;
      });
    },
    // 过滤
    onFilter() {
      this.$nextTick(() => {
        this.$refs.superUxTable.doLayout();
        if (this.$props.storageKey) {
          localStorage.setItem(
            this.$props.storageKey,
            JSON.stringify(this.innerColumns)
          );
        }
      });
    },
    onFilters(value) {
      const {
        item: { key },
        attr: { dictName },
      } = value;
      let dataList = [];
      const dict = this.dict.type[dictName];
      dataList = Array.from(
        new Set(this.innerValue.map((item) => item[key]).filter((item) => item))
      ).map((item) => ({
        text: dictName
          ? (dict.find((dictItem) => dictItem.value == item) || {}).label
          : item,
        value: item,
      }));
      return dataList;
    },
    // 继承el-table的Method
    extendMethod() {
      const refMethod = Object.entries(this.$refs["superUxTable"]);
      for (const [key, value] of refMethod) {
        if (!(key.includes("$") || key.includes("_"))) {
          this[key] = value;
        }
      }
    },
    getSummaries({ columns, data }) {
      const means = []; // 合计

      let { firstSummary } = this.$props;

      columns.forEach((column, columnIndex) => {
        if (!firstSummary && columnIndex === 0) {
          means.push("合计");
        } else {
          const values = data.map((item) => Number(item[column.property]));

          let sumColumn = this.showColumns.filter(
            ({ item, attr }) => attr.isSummary && item.key === column.property
          );

          // 合计
          // if (!values.every(value => isNaN(value))) {
          if (sumColumn.length) {
            means[columnIndex] = values.reduce((prev, curr) => {
              const value = Number(curr);

              if (!isNaN(value)) {
                return prev + curr;
              } else {
                return prev;
              }
            }, 0);

            means[columnIndex] = means[columnIndex].toFixed(2);
          } else {
            means[columnIndex] = "";
          }
        }
      });
      // sums[index] = sums[index] && sums[index].toFixed(2); // 保留2位小数,解决小数合计列
      return [means];
    },
  },
  created() {},
  mounted() {
    this.extendMethod();
  },
  updated() {
    this.$nextTick(() => {
      this.$refs.superUxTable.doLayout();
    });
  },
  destroyed() {},
};
</script>

<template>
  <div class="el-super-ux-table" :key="count" v-resize="resize">
    <ux-grid
      border
      row-key
      use-virtual
      keep-source
      show-overflow
      beautify-table
      ref="superUxTable"
      v-bind="$attrs"
      :height="tableHeight"
      v-on="$listeners"
      :data="innerValue"
      :show-summary="showSummary"
      :summary-method="getSummaries"
      @row-click="onRowClick"
      @header-dragend="onWidth"
      @selection-change="onSelectionChange"
      :header-row-style="{
        color: '#515a6e',
      }"
      style="flex: 1"
    >
      <!-- 多选 -->
      <ux-table-column
        v-if="checkbox"
        fixed="left"
        width="50"
        align="center"
        type="checkbox"
        resizable
        reserve-selection
        :column-key="rowKey"
      ></ux-table-column>
      <!-- 序号 -->
      <ux-table-column
        v-if="index"
        fixed="left"
        width="50"
        title="序号"
        type="index"
        align="center"
        class="is-index"
        resizable
      ></ux-table-column>
      <ux-table-column
        v-for="({ item, attr }, index) in showColumns"
        :key="item.key + index"
        :field="item.key"
        :title="item.title"
        :fixed="item.fixed ? 'left' : undefined"
        :width="item.width || 180"
        :sortable="item.sortabled"
        resizable
        show-overflow
      >
        <template slot="header" slot-scope="scope">
          <template>
            <span v-if="item.require" style="color: #ff4949">*</span>
            <span
              :style="{
                color:
                  item.sort ||
                  item.fixed ||
                  (item.filter && !!item.filter.length)
                    ? '#1890ff'
                    : '',
              }"
            >
              {{ item.title }}
            </span>
            <template>
              <!-- <icon-sort
                v-if="item.sortabled"
                v-model="item.sort"
                @sort="onSort(item)"
              ></icon-sort> -->
              <icon-freeze
                v-if="item.fixedabled"
                v-model="item.fixed"
                @freeze="onFreeze"
              ></icon-freeze>
              <icon-filter
                v-if="item.filterabled"
                v-model="item.filter"
                :filters="onFilters({ item, attr })"
                @filter="onFilter"
              ></icon-filter>
              <icon-hide
                v-if="item.hiddenabled"
                v-model="item.hidden"
                @hide="onHide"
              ></icon-hide>
            </template>
          </template>
        </template>
        <template slot-scope="scope">
          <slot :name="item.key" v-bind="scope" :item="item" :attr="attr">
            <template v-if="attr.is">
              <component
                v-if="attr.is === 'el-dict-tag'"
                v-bind="attr"
                :size="$attrs.size"
                :value="scope.row[item.key]"
                :options="dict.type[attr.dictName]"
              ></component>
              <component
                v-else-if="attr.is === 'el-popover-select-v2'"
                v-bind="attr"
                v-model="scope.row[item.key]"
                :title="item.title"
                :size="$attrs.size"
                :source.sync="scope.row"
              >
              </component>
              <component
                v-else-if="attr.is === 'el-popover-multiple-select-v2'"
                v-bind="attr"
                v-model="scope.row[item.key]"
                :title="item.title"
                :size="$attrs.size"
                :source.sync="scope.row"
              >
              </component>
              <component
                v-else-if="attr.is === 'el-select'"
                v-bind="attr"
                v-model="scope.row[item.key]"
                :size="$attrs.size"
              >
                <template>
                  <el-option
                    v-for="item in dict.type[attr.dictName]"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </template>
              </component>
              <component
                v-else
                v-bind="attr"
                v-model="scope.row[item.key]"
                :size="$attrs.size"
                style="width: 100%"
              >
              </component
            ></template>
            <template v-else>
              <component v-if="attr.formatter" is="span">{{
                attr.formatter(scope.row)
              }}</component>
              <component v-else is="span">{{
                scope.row[item.key] || "--"
              }}</component>
            </template>
          </slot>
        </template>
      </ux-table-column>
      <slot></slot>
      <!-- </el-table> -->
    </ux-grid>
    <div
      style="
        height: 50px;
        display: flex;
        justify-content: space-between;
        align-items: center;
      "
      :style="{
        height: checkbox || pagination ? '50px' : '0px',
      }"
    >
      <div class="mr-4">
        <template v-if="convenitentOperation">
          <button-hide v-model="innerColumns" @change="onHide"></button-hide>
        </template>
      </div>
      <pagination
        v-if="pagination"
        v-show="!selectState"
        :total="page.total"
        :page.sync="page.pageNum"
        :limit.sync="page.pageSize"
        @pagination="$emit('pagination', { ...$event })"
        style="height: 32px; padding: 0 !important; flex: 1; overflow-x: auto"
      />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.el-super-ux-table {
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  overflow: auto;
}
::v-deep.el-super-ux-table .elx-cell {
  word-break: keep-all;
  white-space: nowrap;
  .icon-sort {
    display: none;
  }
  &:hover .icon-sort {
    display: inline-block;
  }
  .icon-freeze {
    display: none;
  }
  &:hover .icon-freeze {
    display: inline-block;
  }
  .icon-filter {
    display: none;
  }
  &:hover .icon-filter {
    display: inline-block;
  }
  .icon-hide {
    display: none;
  }
  &:hover .icon-hide {
    display: inline-block;
  }
  .elx-cell--sort {
    display: none;
  }
  &:hover .elx-cell--sort {
    display: inline-block;
  }
}

::v-deep.uxbeautifyTableClass
  .elx-header--column
  .elx-resizable.is--line:before {
  height: 100%;
  background-color: #dfe6ec;
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578
  • 579
  • 580
  • 581
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • 592
  • 593
  • 594
  • 595
  • 596
  • 597
  • 598
  • 599
  • 600
  • 601
  • 602
  • 603
  • 604
  • 605
  • 606
  • 607
  • 608
  • 609
  • 610
  • 611
  • 612
  • 613
  • 614
  • 615
  • 616
  • 617
  • 618

四、实例

<el-super-ux-table
  index
   v-model="materialInfo[item.key]"
   :dict="dict"
   :ref="tabName"
   :columns="columns"
   :size="$attrs.size"
   :height="420"
 >
   
   <!-- 判断是否禁用 -->
   <template slot="drug" slot-scope="scope">
     <component
       v-bind="scope.attr"
       v-model="scope.row[scope.item.key]"
       :size="$attrs.size"
       :source.sync="scope.row"
       :disabled="!(scope.row.medicineMaterial === '0')"
     >
       <el-option
         v-for="item in dict.type[scope.attr.dictName]"
         :key="item.value"
         :label="item.label"
         :value="item.value"
       >
       </el-option>
     </component>
   </template>

   <template slot="registrationNo" slot-scope="scope">
     <component
       v-bind="scope.attr"
       v-model="scope.row[scope.item.key]"
       :size="$attrs.size"
       :source.sync="scope.row"
       :disabled="!(scope.row.medicineMaterial === '0')"
     >
     </component>
   </template>
   <ux-table-column
     fixed="right"
     title="操作"
     width="120"
     align="center"
   >
     <template slot="header" slot-scope="scope">
       <el-button
         type="text"
         :size="$attrs.size"
         @click="useRowAdd(tabName)"
       >
         增行
       </el-button>
     </template>
     <template slot-scope="scope">
       <el-button
         type="text"
         :size="$attrs.size"
         @click.native.prevent="useRowRemove(tabName, scope)"
       >
         删除
       </el-button>
       <AmendantRecord
         v-if="
           tabName === 'materialBasic' &&
           addType === 'edit' &&
           scope.row.id
         "
         v-model="scope.row"
       ></AmendantRecord>
     </template>
   </ux-table-column>
 </el-super-ux-table>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/115396
推荐阅读
相关标签
  

闽ICP备14008679号