dy
2025-04-08 cac2a51a3f9fcc6d55cdb292d70bd06525adf895
封装vxe-grid组件
已添加2个文件
已修改1个文件
347 ■■■■■ 文件已修改
src/components/HxlhTable/index.vue 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/hxlhTable/index.vue 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/HxlhTable/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,234 @@
<template>
    <div class="hxlh-table">
        <vxe-grid
            ref="vxeTable"
            :show-header-overflow="true"
            :show-overflow="showOverflow"
            :stripe="true"
            :border="true"
            :show-footer="showfooter"
            header-align="center"
            highlight-hover-column
            highlight-hover-row
            resizable
            :loading="loading"
            :pager-config="tablePage"
            :form-config="tableForm"
            :columns="columns"
            :data.sync="data"
            :checkbox-config="checkboxConfig"
            :height="height"
            :max-height="maxHeight"
            :toolbar="toolbar"
            :reload-data="reloadData"
            :footer-method="footerMethod"
            :footer-cell-class-name="footerCellClassName"
            :scroll-x="{enabled: true}"
            :scroll-y="{enabled: true}"
            @sort-change="sortChange"
            @page-change="pagerChange"
            @form-submit="findList"
            @checkbox-change="checkChange"
            @checkbox-all="checkChangeall"
            >
            <template v-slot:buttons>
                <slot />
            </template>
        </vxe-grid>
    </div>
  </template>
<script setup>
// èŽ·å– Vuex å­˜å‚¨å®žä¾‹
// const useStore = useStore();
const props = defineProps({
/* table å‚æ•°*/
showOverflow: {
    type: Boolean,
    default: () => {
    return true
    }
},
columns: {
    type: Array,
    default: () => {
    return []
    }
},
showfooter: {
    type: Boolean,
    default: () => {
    return false
    }
},
toolbar: {
    type: Object,
    default: () => {
        return {
            id: 'khjgz',
            zoom: true,
            resizable: {
            storage: true
            },
            custom: {
            storage: true
            },
            slots: {
            buttons: 'buttons'
            }
        }
    }
},
data: {
    type: Array,
    default: () => {
    return []
    }
},
loading: {
    type: Boolean,
    default: false
},
page: {
    type: Object,
    default: function() {
    return null
    }
},
checkboxConfig: {
    type: Object,
    default: () => {
    return {}
    }
},
maxHeight: {
    type: String,
    default: () => {
    return ''
    }
},
height: {
    type: String,
    default: () => {
    return ''
    }
},
reloadData: {
    type: Function,
    default: () => {
    return {}
    }
},
footerCellClassName: {
    type: Function,
    default: () => {
    return {}
    }
},
mxTableFootData: {
    type: Array,
    default: () => {
    return []
    }
}
})
const tableForm = ref([]);
const height = ref(document.documentElement.clientHeight - 94.5 + "px;")
// const url = computed(() => props.src)
const emit = defineEmits();
function pagerChange({ type, currentPage, pageSize }) {
    if (type == 'current') {
        emit("changePageNo", currentPage);
    } else if (type == 'size') {
        emit('changePageSize', pageSize)
    }
}
function findList() {}
function sortChange({ column, property, order }) {
    emit('sortTable', property, order)
}
function checkChange(info) {
    const { records, checked, row, rowIndex } = info
    emit('on-checkbox', { records, rowIndex, checked })
}
function checkChangeall(info) {
    const { records, checked, row } = info
    emit('on-checkbox', { records, rowIndex: null, checked })
}
// å®šä¹‰ footerMethod å‡½æ•°
function footerMethod({ columns, data }) {
  // è§¦å‘ footerMethod äº‹ä»¶
  emit('footerMethod', { columns, data });
  // è¿”回 Vuex ä¸­çš„ hxlhTableFootData çŠ¶æ€
//   return useStore.state.hxlhTableFootData;
};
function handleSum(list, field) {
    var total = 0
    for (var index = 0; index < list.length; index++) {
    total += Number(list[index][field] || 0)
    }
    return total
}
const vxeTable = ref(null);
// åœ¨å€¼å‘生改变时更新表尾合计
function updateFooter(params) {
    const xTable = vxeTable.value
    xTable.updateFooter()
}
// å–消复选框选择
function clearCheckboxRow() {
    const xTable = vxeTable.value
    xTable.clearCheckboxRow()
}
// å®šä¹‰ tablePage è®¡ç®—属性
const tablePage = computed(() => {
  if (!props.page) {
    return;
  }
  console.log(props.page);
  return {
    total: props.page.total,
    currentPage: props.page.current,
    pageSize: props.page.size,
    align: 'left',
    pageSizes: [10, 20, 50, 100, 500],
    layouts: ['PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total'],
    perfect: true
  };
});
console.log(tablePage);
// å®šä¹‰ footData è®¡ç®—属性
const footData = computed(() => props.mxTableFootData);
</script>
<style lang="less">
  .hxlh-table .vxe-toolbar .vxe-tools--operate {
    margin-top: -23px;
  }
  .hxlh-table .vxe-toolbar {
    min-height: 52px;
    height: auto;
  }
  .vxe-table .vxe-footer--column.col-red {
    color: red;
  }
</style>
src/main.js
@@ -42,6 +42,11 @@
import ImagePreview from "@/components/ImagePreview"
// å­—典标签组件
import DictTag from '@/components/DictTag'
// vxe-table
import 'xe-utils';
import VXETable from 'vxe-table'
import 'vxe-table/lib/index.css'
const app = createApp(App)
@@ -78,5 +83,6 @@
  // æ”¯æŒ large、default、small
  size: Cookies.get('size') || 'default'
})
app.use(VXETable)
app.mount('#app')
src/views/system/hxlhTable/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,107 @@
<template>
    <div id="view">
        <el-row>
            <el-col :span="24">
                <div slot="header" class="clearfix">
                    <span><b>表格展示</b></span>
                </div>
                <div style="width: 100%;display: flex;flex-direction: column;align-items: center;">
                    <!--查询条件-->
                    <!-- <el-form ref="queryForm" style="width: 100%" inline>
                    <el-form-item label="接口名" style="float: left" class="form_btn ">
                        <el-input v-model="selectItem.name" autocomplete="off"></el-input>
                    </el-form-item>
                    <el-form-item style="float: right" class="form_btn ">
                        <el-button icon="el-icon-search" @click="alert('暂时无法搜索')">搜索</el-button>
                    </el-form-item>
                    </el-form> -->
                    <HxlhTable
                        style="width: 100%"
                        :columns="columns"
                        :data="tableData"
                        :loading="loading"
                        :page="page"
                    >
                    </HxlhTable>
            </div>
            </el-col>
        </el-row>
    </div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import HxlhTable from '@/components/HxlhTable'
// æœç´¢ä½¿ç”¨ç»„ä»¶
const selectItem = reactive({
  name: ''
});
// è¡¨æ ¼ - é¡¹ç›®æ‰€æœ‰æ•°æ®
const tableData = ref([
  { code: '111', name: '张三', sex: '男' },
  { code: '222', name: '李四', sex: '男' },
  { code: '333', name: '王五', sex: '男' },
  { code: '444', name: '赵六', sex: '女' }
]);
for (let i = 0; i < 1000; i++) {
    tableData.value.push({
      code: `new${i + 1}`,
      name: `新人${i + 1}`,
      sex: '未知'
    });
  }
// è¡¨æ ¼é…ç½®
const columns = ref([
  { type: 'seq', title: '序号', width: 60 },
  {
    title: '编号',
    field: 'code'
  },
  {
    title: '名称',
    field: 'name'
  },
  {
    title: '性别',
    field: 'sex'
  }
]);
// è¡¨æ ¼ç¼“冲
const loading = ref(false);
// åˆ†é¡µå±žæ€§
const page = reactive({
  total: 1004,
  current: 1,
  size: 10
});
// ç”Ÿå‘½å‘¨æœŸé’©å­ï¼Œæ›¿ä»£ mounted
onMounted(() => {
  // è¿™é‡Œå¯ä»¥æ”¾ç½®åŽŸæ¥ mounted é’©å­ä¸­çš„代码
});
</script>
<style scoped="scoped">
#view {
    width: 100%;
    height: 100%;
    padding: 0px;
    margin: 0px;
}
.box-card {
    width: 480px;
}
</style>