Browse Source

fix:下拉框滚动加载

cmy 3 weeks ago
parent
commit
c958a2cefa
2 changed files with 89 additions and 13 deletions
  1. 2 1
      src/api/marketing/config.ts
  2. 87 12
      src/views/marketing/config/form.vue

+ 2 - 1
src/api/marketing/config.ts

@@ -30,10 +30,11 @@ export const delObj = (ids: Array<String>) => {
 	});
 };
 
-export const getAppList = () => {
+export const getAppList = (params?: Object) => {
 	return request({
 		url: '/admin/marketing/config/apps',
 		method: 'get',
+		params
 	});
 };
 

+ 87 - 12
src/views/marketing/config/form.vue

@@ -9,9 +9,30 @@
         <div v-for="(item, index) in state.ruleForm.configs" :key="item.index" class="config-container">
           <span>IP</span> <el-input style="width: 140px;" v-model="item.ip" clearable :placeholder="$t('marketingConfig.inputIPTip')"></el-input>
           <span>{{ $t('marketingConfig.app') }}</span>
-          <el-select style="width: 140px;" v-model="item.appId" clearable :placeholder="$t('marketingConfig.inputAppSel')">
-            <el-option v-for="item in state.appList" :key="item.appId" :label="item.appName" :value="item.appId"></el-option>
+
+          <el-select
+            style="width: 140px;"
+            v-model="item.appId"
+            clearable
+            :placeholder="$t('marketingConfig.inputAppSel')"
+            popper-class="apps-loadmore"
+            @visible-change="handleVisibleChange"
+          >
+            <!-- <el-option
+              v-for="item in state.appList"
+              :key="item.appId"
+              :label="item.appName"
+              :value="item.appId"
+            ></el-option> -->
+            
+            <el-option
+              v-for="(item, index) in state.appList"
+              :key="item.appId"
+              :label="item.appName"
+              :value="item.appId"
+            />
           </el-select>
+
           <div class="config-actions">
             <svg 
               v-if="index === state.ruleForm.configs.length - 1" 
@@ -46,6 +67,7 @@ import {useI18n} from 'vue-i18n';
 import {info, getAppList, save} from '/@/api/marketing/config';
 import {useMessage} from '/@/hooks/message';
 import {rule} from '/@/utils/validate';
+
 // 定义子组件向父组件传值/事件
 const emit = defineEmits(['refresh']);
 const {t} = useI18n();
@@ -89,8 +111,15 @@ const dataRules = reactive({
   ],
 });
 
+// 分页参数
+const pagination = reactive({
+  current: 1,
+  size: 10,
+  total: 0
+})
+
 // 打开弹窗
-const openDialog = (type: string, row?: any) => {
+const openDialog = async (type: string, row?: any) => {
   visible.value = true;
 
   nextTick(() => {
@@ -98,7 +127,7 @@ const openDialog = (type: string, row?: any) => {
   });
 
   if (row?.id && type === 'edit') {
-    getConfigDetail(row.id);
+    await getConfigDetail(row.id);
   } else {
     state.ruleForm = {
       id: null,
@@ -114,6 +143,7 @@ const openDialog = (type: string, row?: any) => {
       ],
     };
   }
+  pagination.current = 1;
   // 获取应用列表
   getAllAppData();
 };
@@ -125,15 +155,56 @@ const getConfigDetail = (id: string) => {
   });
 };
 
-// 从后端获取菜单信息(含层级)
-const getAllAppData = () => {
-  state.appList = [];
-  getAppList().then((res) => {
-    console.log(res);
-    state.appList = res.data;
-  });
+const handleVisibleChange = (visible) => {
+  if (visible) {
+      // 添加滚动事件监听
+      const dropdown = document.querySelector('.apps-loadmore .el-select-dropdown__wrap');
+      dropdown.addEventListener('scroll', handleScroll);
+  } else {
+      // 移除滚动事件监听
+      const dropdown = document.querySelector('.el-select-dropdown');
+      dropdown.removeEventListener('scroll', handleScroll);
+  }
 };
 
+//防抖函数,由于滚动一次滑轮会触发多次scroll事件,需要控制一下触发的次数。
+function debounce(func, delay) {
+    let timeout;
+    return function(...args) {
+        const context = this;
+        clearTimeout(timeout);
+        timeout = setTimeout(() => func.apply(context, args), delay);
+    };
+}
+
+const handleScroll = debounce((event) => {
+  //判断是否到达可视区域底部,
+  const bottom = event.target.scrollHeight === event.target.scrollTop + event.target.clientHeight;
+  if (bottom && state.appList.length < pagination.total) {
+      pagination.current += 1;
+      getAllAppData();
+    }
+}, 100);
+
+// 从后端获取菜单信息(含层级)
+const getAllAppData = async () => {
+  try {
+    const res = await getAppList({
+      current: pagination.current,
+      size: pagination.size
+    })
+
+    if (pagination.current === 1) {
+      state.appList = res.data.records
+    } else {
+      state.appList = [...state.appList, ...res.data.records]
+    }
+    pagination.total = res.data.total
+  } catch (error) {
+    console.error(error)
+  }
+}
+
 // 保存数据
 const onSubmit = async () => {
   const valid = await menuDialogFormRef.value.validate().catch(() => {
@@ -166,7 +237,7 @@ defineExpose({
   openDialog,
 });
 </script>
-<style scoped>
+<style>
 .config-container {
   display: flex;
   align-items: center;
@@ -182,4 +253,8 @@ defineExpose({
   align-items: center;
   justify-content: space-between;
 }
+
+.apps-loadmore.el-select-dropdown .el-scrollbar__wrap {
+  height: 330px !important;
+}
 </style>