欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vxe Table+Vue2封裝及使用方式

 更新時間:2025年04月24日 09:50:10   作者:i褐瞳Cutey  
本文將詳細(xì)介紹如何在 Vue2 項目中對 Vxe Table 進(jìn)行封裝,并給出實際使用示例,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

一、前言

在前端開發(fā)中,表格展示數(shù)據(jù)是極為常見的需求。Vxe Table 作為一款功能強大的基于 Vue 的表格組件庫,為我們高效構(gòu)建表格提供了諸多便利。

Vxe Table 具有豐富的特性,如支持復(fù)雜表頭、單元格編輯、數(shù)據(jù)校驗、排序、篩選等。它擁有簡潔易用的 API,能幫助開發(fā)者快速搭建出符合業(yè)務(wù)需求的表格界面,大大提高開發(fā)效率。其強大的自定義能力,可以滿足各種復(fù)雜場景下的表格展示需求。

二、Vxe Table 的封裝

1 安裝及引入流程見官網(wǎng)VxeTable v3

? 注意版本適配,Vue2對應(yīng)V3版本,Vue3對應(yīng)V4版本。

2 封裝自定義表格組件

? 在項目/src/components目錄下創(chuàng)建vxeTable目錄,新建一個index.jsindex.vue。

代碼如下:

// index.js
import VxeUIAll from 'vxe-pc-ui'
import 'vxe-pc-ui/lib/style.css'
import VxeUITable from 'vxe-table'
import 'vxe-table/lib/style.css'

export const CustomVxeTable = (app) => {
  app.use(VxeUIAll)
  app.use(VxeUITable)
}
<template>
  <!-- 表格組件 -->
  <vxe-grid
    ref="vxeTable"
    v-bind="gridOptions"
    v-on="$listeners"
    :data="dataSource"
    :columns="columns"
    :border="bordered"
  >
    <!-- 自定義表單內(nèi)容 -->
    <template #form>
      <slot name="form"></slot>
    </template>

    <!-- 自定義表格上方內(nèi)容 -->
    <template #top>
      <slot name="top"></slot>
    </template>

    <!-- 自定義表頭內(nèi)容 -->
    <template v-for="header in slotsHeader" #[header]>
      <slot :name="header"></slot>
    </template>

    <!-- 自定義表格展開內(nèi)容 -->
    <template #expandedRowRender="{ row }">
      <slot name="expandedRowRender" :record="row"></slot>
    </template>

    <!-- 自定義表格內(nèi)容 -->
    <template v-for="slot in slotsDefault" #[slot]="{ row }">
      <slot :name="slot" :text="row[slot]" :record="row"></slot>
    </template>

    <!-- 自定義空數(shù)據(jù)內(nèi)容 -->
    <template #empty>
      <slot v-if="$slots.empty" name="empty"></slot>
      <a-empty v-else />
    </template>

    <!-- 自定義表格下方內(nèi)容 -->
    <template #bottom>
      <slot name="bottom"></slot>
    </template>

    <!-- 分頁組件 -->
    <template #pager>
      <vxe-pager
        v-if="pagination"
        :loading="gridOptions.loading"
        :loyouts="pagerOptions.loyouts"
        :size="pagerOptions.size"
        :currentPage.sync="pagerOptions.current"
        :pageSize.sync="pagerOptions.pageSize"
        :pageSizes="pagerOptions.pageSizes"
        :total="pagerOptions.total"
        @page-change="handlePageChange">
      </vxe-pager>
    </template>
  </vxe-grid>
</template>

<script>
import defaultConf from './defaultConf'

/**
 * 根據(jù)插槽類型獲取插槽列表
 * @param columns 列配置
 * @param slotType  插槽類型
 * @returns {*[]}
 */
function slotsByType(columns, slotType) {
  const slots = []

  const findSlots = (column) => {
    if (!column) return

    if (column.slots && column.slots[slotType]) {
      slots.push(column.slots[slotType])
    }

    if (column.children) {
      for (let child of column.children) {
        findSlots(child)
      }
    }
  }

  for (let column of columns) {
    findSlots(column)
  }

  return slots
}

export default {
  name: 'VxeTable',
  props: {
    // 表格數(shù)據(jù)
    dataSource: {
      type: Array,
      required: true
    },
    // 表格列配置
    columns: {
      type: Array,
      required: true
    },
    // 邊框
    bordered: {
      type: Boolean,
      default: true
    },
    // 分頁配置
    pagination: {
      type: Object,
      default: null // 默認(rèn)不啟用分頁
    }
  },
  data() {
    return {}
  },
  computed: {
    gridOptions() {
      const gridOptions = {
        ...defaultConf.grid,  // 默認(rèn)配置
        ...this.$attrs,       // 用戶傳入的配置
        ...this.props,        // props傳入的配置
        rowConfig: { ...defaultConf.rowConfig, useKey: Boolean(this.$attrs.rowKey), keyField: this.$attrs.rowKey }  // 特殊配置單獨處理
      }
      const expiredAttribute = ['rowKey'] // 刪除過期屬性,避免傳入到vxe-grid組件報錯
      for (let attr of expiredAttribute) {
        delete gridOptions[attr]
      }
      return gridOptions
    },
    pagerOptions() {
      if (!this.pagination) return {}
      return {
        ...defaultConf.pager,   // 默認(rèn)配置
        ...this.pagination,    // 用戶傳入的配置
        pageSizes: this.pagination.pageSizeOptions.map(item => parseInt(item)) // 特殊配置單獨處理
      }
    },
    slotsDefault() {
      return slotsByType(this.columns, 'default')
    },
    slotsHeader() {
      return slotsByType(this.columns, 'header')
    }
  },
  mounted() {
    // 將子組件的方法復(fù)制到父組件
    Object.keys(this.$refs.vxeTable.$options.methods).forEach(method => {
      this[method] = this.$refs.vxeTable[method].bind(this.$refs.vxeTable)
    })
  },
  methods: {
    handlePageChange({ currentPage, pageSize }) {
      this.$emit('change', { ...this.pagination, current: currentPage, pageSize: pageSize })
    }
  }
}
</script>

<style scoped>
/* 可以根據(jù)需要添加樣式 */
</style>

? 此外,為了方便使用,新建一個默認(rèn)配置文件defaultConf.js。

export default {
  grid: {
    layouts: ['Form', 'Toolbar', 'Top', 'Table', 'Bottom', 'Pager'],
    height: null,  // %, px
    minHeight: null,
    maxHeight: null,
    stripe: true, // 斑馬紋
    border: true, // 邊框
    round: false, // 圓角邊框
    size: 'small', // medium, small, mini
    showHeader: true, // 是否顯示表頭
    showFooter: false, // 是否顯示表尾
    headerAlign: 'center',  // 表頭對齊方式
    footerAlign: 'left',  // 表尾對齊方式
    keepSource: false,  // 保持原始值的狀態(tài),被某些功能所依賴,比如編輯狀態(tài)、還原數(shù)據(jù)等
    showOverflow: false,  // 列超出寬度是否自動省略,推薦每列自主設(shè)置 'false' 'true/ellipsis' 'title' 'tooltip'
    showHeaderOverflow: 'title',  // 表頭列超出寬度是否自動省略
    showFooterOverflow: 'title',  // 表尾列超出寬度是否自動省略
    autoResize: true, // 是否自動監(jiān)聽父容器變化去重新計算表格(對于固定高度的表格,可能會用到)
    resizeConfig: {
      refreshDelay: 250 // 只對 autoResize 有效,刷新延時,當(dāng)父容器發(fā)生變化時,至少多少毫秒刷新布局
    },
    columnConfig: {
      isCurrent: false,  // 鼠標(biāo)點擊列頭時是否高亮當(dāng)前列
      isHover: false,  // 鼠標(biāo)移到列時是否高亮當(dāng)前列
      resizable: false // 是否允許拖動列寬調(diào)整大小,推薦每列自主設(shè)置
    },
    rowConfig: {
      // keyField: '_X_ROW_KEY', // 行數(shù)據(jù)的唯一主鍵字段名
      isCurrent: false, // 當(dāng)鼠標(biāo)點擊行時,是否要高亮當(dāng)前行
      isHover: false  // 當(dāng)鼠標(biāo)移到行時,是否要高亮當(dāng)前行
    },
    cellConfig: {
      padding: true // 是否顯示間距
      // height: 48, // number, 默認(rèn)單元格高度
    },
    editConfig: {
      // mode: 'cell', // cell, row
      trigger: 'click',
      showIcon: true,
      showAsterisk: true
    },
    radioConfig: {
      // trigger: 'default'
      strict: true
    },
    checkboxConfig: {
      // trigger: 'default',
      strict: true
    },
    tooltipConfig: {
      // 所有單元格開啟工具提示 boolean
      showAll: false,
      // tooltip 的主題顏色string  dark,light
      theme: 'dark',
      // 鼠標(biāo)是否可進(jìn)入到工具提示中boolean
      enterable: false,
      // 鼠標(biāo)移入后延時多少才顯示工具提示number
      enterDelay: 500,
      // 鼠標(biāo)移出后延時多少才隱藏工具提示number
      leaveDelay: 300
    },
    validConfig: {
      showMessage: true,
      autoClear: true,
      autoPos: true,
      message: 'inline',
      msgMode: 'single'
    },
    menuConfig: {
      enabled: false // 是否啟用
    },
    customConfig: {
      allowVisible: true,
      allowResizable: true,
      allowFixed: true,
      allowSort: true,
      showFooter: true,
      placement: 'topRight',
      //  storage: false,
      //  checkMethod () {},
      modalOptions: {
        showZoom: true,
        mask: true,
        lockView: true,
        resize: true,
        escClosable: true
      }
    },
    sortConfig: {
      // remote: false,
      // trigger: 'default',
      // orders: ['asc', 'desc', null],
      // sortMethod: null,
      showIcon: true,
      iconLayout: 'vertical'
    },
    filterConfig: {
      // remote: false,
      // filterMethod: null,
      showIcon: true
    },
    treeConfig: {
      rowField: 'id',
      parentField: 'parentId',
      childrenField: 'children',
      hasChildField: 'hasChild',
      indent: 20,
      showIcon: true,
      expandInit: false
    },
    expandConfig: {
      // trigger: 'default',
      showIcon: true
    },
    importConfig: {
      _typeMaps: {
        csv: 1,
        html: 1,
        xml: 1,
        txt: 1
      },
      modes: ['insert', 'covering']
    },
    exportConfig: {
      _typeMaps: {
        csv: 1,
        html: 1,
        xml: 1,
        txt: 1
      },
      modes: ['current', 'selected']
    },
    printConfig: {
      modes: ['current', 'selected']
    },
    mouseConfig: {
      extension: true
    },
    keyboardConfig: {
      isEsc: true
    },
    scrollX: {
      // enabled: false,
      gt: 60
      // oSize: 0
    },
    scrollY: {
      // enabled: false,
      gt: 100
      // oSize: 0
    }
  },
  pager: {
    loyouts: ['Home', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'End', 'Sizes', 'FullJump', 'Total']
  }
}

? 在上述代碼中,我們通過 props 接收外部傳遞的主要屬性(如:數(shù)據(jù)和表格列配置),其余屬性通過this.$attrs接收,父組件未設(shè)定的屬性值通過defaultConf進(jìn)行默認(rèn)配置。

實現(xiàn)了一個具有基本功能的可復(fù)用表格組件。同時,綁定了一些常用的事件,如選擇項變化和行雙擊事件,并通過$emit將事件傳遞給父組件。

三、Vxe Table 的使用示例

在父組件中引入并使用封裝的表格組件

在需要使用表格的父組件中,引入MyTable.vue組件,并傳遞相應(yīng)的數(shù)據(jù)和配置。

<template>
  <div class="demo-page-wrapper">
    <!-- 使用二次封裝的 VxeTable 組件 -->
    <div style="padding: 16px 0; display: flex;align-items: center;justify-content: space-between;">
      <a-space size="middle">
        <a-button @click="sortEvent('age', 'asc')">年齡 升序</a-button>
        <a-button @click="sortEvent('age', 'desc')">年齡 降序</a-button>
        <a-button @click="clearSortEvent" type="primary">清除排序</a-button>
      </a-space>
      <a-space size="middle">
        <div>
          總計:
          <span>1000</span>
          元
        </div>
        <a-button @click="getSelectEvent" type="primary">獲取選中數(shù)據(jù)</a-button>
        <a-button @click="handleExport" type="primary">導(dǎo)出</a-button>
      </a-space>
    </div>

    <VxeTable
      ref="table"
      size="small"
      rowKey="id"
      border
      round
      stripe
      height="auto"
      :expandConfig="{ showIcon: false }"
      :loading="loading"
      :dataSource="dataSource"
      :columns="cols"
      :pagination="ipagination"
      :menuConfig="menuConfig"
      @cell-menu="cellMenuEvent"
      @menu-click="menuClickEvent"
      @cell-click="handleCellClick"
      @edit-closed="handleEditClosed"
      @change="handleTableChange"
      @form-submit="formSubmitEvent"
      @form-reset="formResetEvent"
    >
      <!-- 自定義表頭內(nèi)容 -->
      <template #name_header>
        <span>《名字名字名字名字名字》</span>
      </template>

      <template #expandedRowRender="{ record }">
        <vxe-grid :columns="childCols" :data="record.bookList"></vxe-grid>
      </template>

      <!-- 自定義表格內(nèi)容 以下三種寫法結(jié)果相同 -->
      <!--      <template v-slot:email="{ record }">-->
      <!--      <template #email="{ text,record }">-->
      <template slot="email" slot-scope="{ text,record }">
        {{ text }}
        <vxe-text :content="record.email" click-to-copy></vxe-text>
      </template>

      <template #action="{ record }">
        <a @click="handleEdit(record)">編輯</a>
      </template>

      <!-- 自定義空數(shù)據(jù)內(nèi)容 -->
      <template #empty>
        <span style="color: red;">
          <img src="https://vxeui.com/resource/img/546.gif">
          <p>不用再看了,沒有更多數(shù)據(jù)了?。。。?!</p>
        </span>
      </template>
    </VxeTable>
  </div>
</template>

<script>
import XEUtils from 'xe-utils'
import VxeTable from '@/components/VxeTable/Index.vue'
import GridMixin from '@/mixins/GridMixin'
import { loadMockData } from '@views/demo/vxeTable/generateData'
import { VxeUI } from 'vxe-table'

// 自定義單元格渲染
const avatarUrlCellRender = {
  name: 'VxeImage',
  props: {
    circle: true,
    width: 36,
    height: 36
  }
}
const levelNumCellRender = {
  name: 'VxeRate',
  props: {
    readonly: false
  }
}
const flagCellRender = {
  name: 'VxeSwitch',
  props: {
    readonly: false
  },
  events: {
    change: (cellParams, targetParams) => {
      console.log('flag', targetParams.value, cellParams)
    }
  }
}
const nameEditRender = {
  name: 'VxeInput',
  props: {
    trim: true,
    clearable: true,
    maxLength: 5,
    placeholder: '請輸入名字'
  },
  events: {
    blur: (cellParams, targetParams) => {
      console.log('name', targetParams.value)
    }
  }
}

// 格式化單元格
const formatSex = ({ cellValue }) => {
  if (cellValue) {
    return cellValue === '1' ? '男' : '女'
  }
  return ''
}
const cityOptions = [
  { label: '中華人民共和國廣東省深圳市龍崗區(qū)人民法院', value: 'sz' },
  { label: '廣東省廣州市', value: 'gz' },
  { label: '北京市', value: 'bj' },
  { label: '上海市', value: 'sh' },
  { label: '浙江省杭州市', value: 'hz' }
]
const formatCity = ({ cellValue }) => {
  const item = cityOptions.find(item => item.value === cellValue)
  return item ? item.label : cellValue
}
const formatAmount = ({ cellValue }) => {
  if (cellValue) {
    return `¥${ XEUtils.commafy(cellValue, { digits: 2 }) }`
  }
  return ''
}

// 篩選條件
const sexFilterOptions = [
  { label: '女', value: '0' },
  { label: '男', value: '1' }
]
const ageFilterOptions = [
  { label: '(18,25]', value: '18-25' },
  { label: '(26,35]', value: '26-35' },
  { label: '(36,45]', value: '36-45' },
  { label: '(46,55]', value: '46-55' },
  { label: '(56,65]', value: '56-65' }
]
const ageFilterMethod = function({ value: filterVal, cellValue }) {
  filterVal = filterVal.split('-')
  const age = parseInt(cellValue)
  if (filterVal.length === 2) {
    return age >= parseInt(filterVal[0]) && age < parseInt(filterVal[1])
  }
}

// 右鍵菜單
const menuConfig = {
  header: {
    options: [
      [
        { code: 'exportAll', name: '導(dǎo)出所有.csv', prefixConfig: { icon: 'vxe-icon-download' }, visible: true, disabled: false }
      ]
    ]
  },
  body: {
    options: [
      [
        { code: 'copy', name: '復(fù)制內(nèi)容(Ctrl+C)', prefixConfig: { icon: 'vxe-icon-copy' }, visible: true, disabled: false },
        { code: 'clear', name: '清除內(nèi)容', visible: true, disabled: false },
        { code: 'reload', name: '刷新表格', visible: true, disabled: false }
      ],
      [
        {
          code: 'fixed',
          name: '凍結(jié)列',
          children: [
            { code: 'cancelFixed', name: '取消凍結(jié)' },
            { code: 'fixedLeft', name: '凍結(jié)在左側(cè)', prefixConfig: { icon: 'vxe-icon-fixed-left' } },
            { code: 'fixedRight', name: '凍結(jié)在右側(cè)', prefixConfig: { icon: 'vxe-icon-fixed-right' } }
          ]
        }
      ],
      [
        { code: 'myPrint', name: '打印(Ctrl+P)', prefixConfig: { icon: 'vxe-icon-print' }, visible: true, disabled: false },
        { code: 'myExport', name: '導(dǎo)出.csv', prefixConfig: { icon: 'vxe-icon-download' }, visible: true, disabled: false }
      ]
    ]
  }
}

const formConfig = {
  data: {
    name: '',
    role: '',
    sex: '',
    num: '',
    address: ''
  },
  items: [
    { field: 'name', title: '名稱', span: 8, itemRender: { name: 'VxeInput' } },
    { field: 'email', title: '郵件', span: 8, itemRender: { name: 'VxeInput' } },
    { field: 'nickname', title: '昵稱', span: 8, itemRender: { name: 'VxeInput' } },
    { field: 'role', title: '角色', span: 8, folding: true, itemRender: { name: 'VxeInput' } },
    { field: 'sex', title: '性別', span: 8, folding: true, itemRender: { name: 'VxeInput' } },
    { field: 'age', title: '年齡', span: 8, folding: true, itemRender: { name: 'VxeInput' } },
    {
      span: 24,
      collapseNode: true,
      align: 'center',
      itemRender: {
        name: 'VxeButtonGroup',
        options: [
          { type: 'submit', content: '搜索', status: 'primary' },
          { type: 'reset', content: '重置' }
        ]
      }
    }
  ]
}

/**
 * 列常用配置說明:
 * 1. type:列類型,支持的類型有 seq(序號)、checkbox(復(fù)選框)、radio(單選框)、expand(展開行)、html(HTML片段)
 * 2. field:列字段名
 * 3. title:標(biāo)題名
 * 4. width: 列寬,支持auto、固定像素、百分比、等比例分配等,如果不設(shè)置則按照表格的寬度進(jìn)行均勻分配。該表格組件支持min-width,可適時使用
 * 5. 溢出省略:
 *  key的取值:showOverflow(單元格)、showHeaderOverflow(表頭) 和 showFooterOverflow(表尾)
 *  value的取值:ellipsis(省略號)、title(省略號 + 原生title)、tooltip(省略號 + tooltip提示)
 * 5. resizable: 是否允許拖動列寬調(diào)整大小
 * 6. fixed: 列固定,支持 left(固定左側(cè))、right(固定右側(cè))
 * 7. align: 對齊方式,支持 left、center、right
 * 8. sortable: 是否允許排序
 * 9. filters: 篩選項。數(shù)組格式,元素結(jié)構(gòu):{ label: '選項', value: '值' ,checked:'是否默認(rèn)選中'}。搭配filterMethod定義篩選方法,filterMultiple定義是否多選
 * 10. formatter: (({ cellValue, row, column }) => string) | any[] | string,格式化顯示內(nèi)容
 * 11. cellRender: 自定義單元格渲染
 * 12. editRender: 自定義編輯渲染
 * 13. contentRender: 自定義內(nèi)容渲染
 * 13. slots: 自定義插槽
 */
const cols = [
  { type: 'expand', width: '40px', align: 'center', slots: { content: 'expandedRowRender' } },
  { field: 'seq', type: 'seq', width: '40px', align: 'center', resizable: false },
  { field: 'checkbox', type: 'checkbox', width: '40px', align: 'center' },
  { field: 'avatarUrl', title: '頭像', width: '80px', align: 'center', titlePrefix: { content: '自定義前綴圖標(biāo)', icon: 'vxe-icon-question-circle-fill' }, cellRender: avatarUrlCellRender },
  { field: 'name', title: '名字', align: 'center', showHeaderOverflow: 'ellipsis', minWidth: '100px', dragSort: true, editRender: nameEditRender, slots: { header: 'name_header' } },
  {
    title: '基本信息',
    field: 'info',
    children: [
      { field: 'city', title: '所在地', width: '250px', showOverflow: 'tooltip', formatter: formatCity },
      { field: 'age', title: '年齡', width: '100px', align: 'center', sortable: true, filters: ageFilterOptions, filterMethod: ageFilterMethod, editRender: { name: 'input', attrs: { type: 'number' } } },
      { field: 'sex', title: '性別', width: '60px', align: 'center', formatter: formatSex, filters: sexFilterOptions, filterMultiple: true, editRender: { name: 'select', options: sexFilterOptions } },
      { field: 'email', title: '郵箱', width: '220px', slots: { default: 'email' } }
    ]
  },
  { field: 'flag', title: '是否啟用', width: '80px', align: 'center', cellRender: flagCellRender },
  { field: 'levelNum', title: '評分', width: '200px', align: 'center', cellRender: levelNumCellRender },
  {
    title: '年度賬單',
    field: 'annualStatement',
    children: [
      { field: 'annualStatement.m1', title: '一月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m2', title: '二月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m3', title: '三月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m4', title: '四月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m5', title: '五月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m6', title: '六月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m7', title: '七月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m8', title: '八月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m9', title: '九月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m10', title: '十月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m11', title: '十一月', width: '140px', formatter: formatAmount },
      { field: 'annualStatement.m12', title: '十二月', width: '140px', formatter: formatAmount }
    ]
  },
  { title: '操作', field: 'action', width: '100px', align: 'center', fixed: 'right', slots: { default: 'action' } }
]

const childCols = [
  { field: 'name', title: '書籍名稱', align: 'center' },
  { field: 'author', title: '作者', align: 'center' },
  { field: 'price', title: '價格', align: 'center' }
]

export default {
  components: {
    VxeTable
  },
  mixins: [GridMixin],
  data() {
    return {
      cols,
      childCols,
      menuConfig,
      formConfig,
      disableMixinCreated: true
    }
  },
  mounted() {
    this.loadData()
  },
  methods: {
    formSubmitEvent() {
      console.log('form submit')
    },
    formResetEvent() {
      console.log('form reset')
    },
    cellMenuEvent({ row }) {
      const $grid = this.$refs.table
      if ($grid) {
        $grid.setCurrentRow(row)
      }
    },
    menuClickEvent({ menu, row, column }) {
      const $grid = this.$refs.table
      if ($grid) {
        switch (menu.code) {
          case 'copy':
            if (row && column) {
              if (VxeUI.clipboard.copy(row[column.field])) {
                VxeUI.modal.message({ content: '已復(fù)制到剪貼板!', status: 'success' })
              }
            }
            break
          case 'clear':
            $grid.clearData(row, column.field)
            break
          case 'myPrint':
            $grid.print()
            break
          case 'myExport':
            $grid.exportData()
            break
          default:
            VxeUI.modal.message({ content: `點擊了 ${ menu.code }`, status: 'success' })
            break
        }
      }
    },
    handleExport() {
      const $grid = this.$refs.table
      if ($grid) {
        $grid.openExport()
      }
    },
    getSelectEvent() {
      const $table = this.$refs.table
      if ($table) {
        const selectRecords = $table.getCheckboxRecords()
        console.log('選中數(shù)據(jù):', selectRecords)
      }
    },
    sortEvent(field, order) {
      const $table = this.$refs.table
      if ($table) {
        $table.sort({ field, order })
      }
    },
    clearSortEvent() {
      const $table = this.$refs.table
      if ($table) {
        $table.clearSort()
      }
    },
    handleEdit(record) {
      console.log('Edit:', record)
      this.$refs.table.setEditRow(record)
    },
    loadData(arg) {
      // if (!this.url.list) {
      //   this.$message.error({
      //     key: this.messageKey,
      //     content: '請設(shè)置url.list屬性!'
      //   })
      //   return
      // }
      // 加載數(shù)據(jù),若傳入?yún)?shù)1則加載第一頁的內(nèi)容
      if (arg === 1) {
        if (false != this.ipagination) {
          this.ipagination.current = 1
        }
      }
      this.selectedRowKeys = []
      this.selectedRows = []
      // 查詢條件
      let params = this.getQueryParams()
      this.loading = true
      // get(this.url.list, params).then(res=> {
      loadMockData(this.ipagination.current, this.ipagination.pageSize).then(res => {
        if (res.success) {
          if (this.rowKey) {
            this.initRowKey(res.data.records)
          }
          this.dataSource = res.data.records
          if (false !== this.ipagination) {
            if (this.dataSource.length <= 0 && this.ipagination.current > 1) {
              this.ipagination.current--
              this.loadData()
              return
            } else if (this.dataSource.length > 0 && this.ipagination.current < 1) {
              this.ipagination.current = 1
            }
            this.ipagination.total = 100
          }
          this.loadDataSuccess()
        } else {
          this.$message.warning({
            key: this.messageKey,
            content: (res.msg && res.msg !== '操作成功' ? res.msg : '操作失??!')
          })
        }
        // setTimeout(() => {
        this.loading = false
        // }, 5000)
      })
    },
    handleEditClosed(params) {
      const { row, rowIndex, column, columnIndex } = params
      console.log('Row edit closed:(' + rowIndex + ', ' + columnIndex + ')', row, row[column.field])
    },
    handleCellClick(params) {
      console.log('Cell click:', params)
    }
  }
}
</script>

<style scoped>
/* 可以根據(jù)需要添加樣式 */
.demo-page-wrapper {
  height: calc(100vh - 158px);
}
</style>	

附件:模擬數(shù)據(jù)生成方法js文件generateData.js

import XEUtils from 'xe-utils'

const arList = XEUtils.shuffle(XEUtils.range(1, 21).map(num => `https://vxeui.com/resource/avatarImg/avatar${ num }.jpeg`))
const neList = XEUtils.shuffle(['張三', '李四', '王五', '小徐', '老張', '老六', '小明', '老徐', '小張', '小趙', '老高', '老鐵', '趙高', '小王', '老王'])
const cyList = XEUtils.shuffle(['sz', 'gz', 'bj', 'sh', 'hz'])
const sxList = XEUtils.shuffle(XEUtils.range(1, 60).map(num => `${ num % 2 }`))
const aeList = XEUtils.shuffle(XEUtils.range(18, 66))
const elList = XEUtils.range(1, 60).map(() => `${ XEUtils.sample('qwertyuiopasdfghjklzxcvbnm'.split(''), XEUtils.random(6, 16)).join('') }@163.com`)
const lnList = XEUtils.shuffle(XEUtils.range(0, 5))
const asmMpas = {
  m1: XEUtils.shuffle(XEUtils.range(1000, 1500)),
  m2: XEUtils.shuffle(XEUtils.range(1100, 1400)),
  m3: XEUtils.shuffle(XEUtils.range(800, 1200)),
  m4: XEUtils.shuffle(XEUtils.range(3000, 3600)),
  m5: XEUtils.shuffle(XEUtils.range(2000, 2100)),
  m6: XEUtils.shuffle(XEUtils.range(1600, 1700)),
  m7: XEUtils.shuffle(XEUtils.range(1200, 1300)),
  m8: XEUtils.shuffle(XEUtils.range(1100, 1200)),
  m9: XEUtils.shuffle(XEUtils.range(1700, 1800)),
  m10: XEUtils.shuffle(XEUtils.range(1300, 1700)),
  m11: XEUtils.shuffle(XEUtils.range(1000, 1300)),
  m12: XEUtils.shuffle(XEUtils.range(800, 1200))
}
const fgList = XEUtils.shuffle(XEUtils.range(1, 60).map(num => (num % 2) === 0))
const cacheList = []

export function loadMockData(page, rows) {
  // 計算需要生成的總數(shù)據(jù)量
  const rSize = page * rows
  return new Promise(resolve => {
    setTimeout(() => {
      // 生成足夠的數(shù)據(jù)到 cacheList
      for (let i = cacheList.length; i < rSize; i++) {
        const item = {
          id: 1000000 + i,
          name: neList[i % neList.length],
          nickname: '',
          sex: sxList[i % sxList.length],
          age: aeList[i % aeList.length],
          email: elList[i % elList.length],
          city: cyList[i % cyList.length],
          avatarUrl: arList[i % arList.length],
          levelNum: lnList[i % lnList.length],
          annualStatement: {
            m1: asmMpas.m1[i % asmMpas.m1.length],
            m2: asmMpas.m2[i % asmMpas.m2.length],
            m3: asmMpas.m3[i % asmMpas.m3.length],
            m4: asmMpas.m4[i % asmMpas.m4.length],
            m5: asmMpas.m5[i % asmMpas.m5.length],
            m6: asmMpas.m6[i % asmMpas.m6.length],
            m7: asmMpas.m7[i % asmMpas.m7.length],
            m8: asmMpas.m8[i % asmMpas.m8.length],
            m9: asmMpas.m9[i % asmMpas.m9.length],
            m10: asmMpas.m10[i % asmMpas.m10.length],
            m11: asmMpas.m11[i % asmMpas.m11.length],
            m12: asmMpas.m12[i % asmMpas.m12.length]
          },
          flag: fgList[i % fgList.length],
          bookList: [
            { id: 1000000 + i + 1, name: '書籍名稱1', author: '作者1', price: 100 },
            { id: 1000000 + i + 2, name: '書籍名稱2', author: '作者2', price: 200 },
            { id: 1000000 + i + 3, name: '書籍名稱3', author: '作者3', price: 300 },
            { id: 1000000 + i + 4, name: '書籍名稱4', author: '作者4', price: 400 },
            { id: 1000000 + i + 5, name: '書籍名稱5', author: '作者5', price: 500 }
          ]
        }
        cacheList.push(item)
      }
      // 計算當(dāng)前頁數(shù)據(jù)的起始和結(jié)束索引
      const startIndex = (page - 1) * rows
      const endIndex = startIndex + rows
      // 截取當(dāng)前頁的數(shù)據(jù)
      const data = cacheList.slice(startIndex, endIndex)
      resolve({
        success: true,
        data: {
          records: data
        }
      })
    }, 150)
  })
}

通過以上步驟,我們完成了在 Vue2 項目中對 Vxe Table 的封裝及使用示例。

通過合理的封裝,能夠提高代碼的復(fù)用性和可維護(hù)性,更高效地實現(xiàn)項目中表格相關(guān)的功能需求。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue實現(xiàn)登錄類型切換

    vue實現(xiàn)登錄類型切換

    這篇文章主要為大家詳細(xì)介紹了vue實現(xiàn)登錄類型切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • vue將data恢復(fù)到初始狀態(tài) && 重新渲染組件實例

    vue將data恢復(fù)到初始狀態(tài) && 重新渲染組件實例

    這篇文章主要介紹了vue將data恢復(fù)到初始狀態(tài) && 重新渲染組件實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • vue項目配置element-ui容易遇到的坑及解決

    vue項目配置element-ui容易遇到的坑及解決

    這篇文章主要介紹了vue項目配置element-ui容易遇到的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • vue整合項目中百度API示例詳解

    vue整合項目中百度API示例詳解

    這篇文章主要為大家介紹了vue整合項目中百度API示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • vue添加自定義右鍵菜單的完整實例

    vue添加自定義右鍵菜單的完整實例

    這篇文章主要給大家介紹了關(guān)于vue添加自定義右鍵菜單的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • vue選項卡組件的實現(xiàn)方法

    vue選項卡組件的實現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了vue選項卡組件的實現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Vue.js狀態(tài)管理之Pinia與Vuex詳解

    Vue.js狀態(tài)管理之Pinia與Vuex詳解

    Pinia和Vuex一樣都是是vue的全局狀態(tài)管理器,其實Pinia就是Vuex5,只不過為了尊重原作者的貢獻(xiàn)就沿用了名字Pinia,下面這篇文章主要給大家介紹了關(guān)于Vue.js狀態(tài)管理之Pinia與Vuex的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • vue實現(xiàn)購物車加減

    vue實現(xiàn)購物車加減

    這篇文章主要為大家詳細(xì)介紹了vue實現(xiàn)購物車加減,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Vue和uniapp中該如何使用canvas詳解

    Vue和uniapp中該如何使用canvas詳解

    說起canvas是css3新增的標(biāo)簽,而餅狀圖又是canvas經(jīng)典,我們公司現(xiàn)在正在用uni-app框架去研發(fā)APP,下面這篇文章主要給大家介紹了關(guān)于Vue和uniapp中該如何使用canvas的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件

    vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件

    這篇文章主要介紹了vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-02-02

最新評論