浏览代码

refactor(CustomTable、TableFilterForm组件): 拆分表格的查询表单,形成TableFilterForm组件

拆分表格的查询表单,形成
    -TableFilterForm组件
    -FilterInput组件
    -FilterSelect组件
    -FilterSelectLabel组件

删除GameMangeView组件中的watch gid的代码
fxs 6 月之前
父节点
当前提交
aa8bae0ec0

+ 4 - 0
components.d.ts

@@ -46,7 +46,10 @@ declare module 'vue' {
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     FileUpload: typeof import('./src/components/form/FileUpload.vue')['default']
+    FilterInput: typeof import('./src/components/form/TableFilterForm/FilterInput.vue')['default']
     FilterPopover: typeof import('./src/components/toolsBtn/FilterPopover.vue')['default']
+    FilterSelect: typeof import('./src/components/form/TableFilterForm/FilterSelect.vue')['default']
+    FilterSelectLabel: typeof import('./src/components/form/TableFilterForm/FilterSelectLabel.vue')['default']
     HeaderCard: typeof import('./src/components/dataAnalysis/HeaderCard.vue')['default']
     IconIcBaselineVisibility: typeof import('~icons/ic/baseline-visibility')['default']
     IconIcBaselineVisibilityOff: typeof import('~icons/ic/baseline-visibility-off')['default']
@@ -61,6 +64,7 @@ declare module 'vue' {
     RouterView: typeof import('vue-router')['RouterView']
     StatisticText: typeof import('./src/components/dataAnalysis/StatisticText.vue')['default']
     TableFieldText: typeof import('./src/components/table/TableFieldText.vue')['default']
+    TableFilterForm: typeof import('./src/components/form/TableFilterForm/TableFilterForm.vue')['default']
     TemporalTrend: typeof import('./src/components/dataAnalysis/TemporalTrend.vue')['default']
     TimeLineChart: typeof import('./src/components/echarts/TimeLineChart.vue')['default']
     WithIconSelect: typeof import('./src/components/common/WithIconSelect.vue')['default']

+ 2 - 0
src/assets/base.css

@@ -1,3 +1,5 @@
+@import url('./form.css');
+
 ::-webkit-scrollbar {
   display: none;
 }

+ 24 - 428
src/components/table/CustomTable.vue

@@ -2,73 +2,40 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-20 18:16:18
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-11-29
+ * @LastEditTime: 2024-12-02
  * @Description: 
  * 
 -->
 <script setup lang="ts">
-import type {
-  PropsParams,
-  QueryInfo,
-  SelectInfo,
-  TableFieldInfo,
-  TablePaginationSetting
-} from '@/types/table.ts'
+import type { PropsParams, TableFieldInfo, TablePaginationSetting } from '@/types/table.ts'
 import type { ReqConfig } from '@/types/dataAnalysis.ts'
-import type { FormInstance } from 'element-plus'
-import { FilterType } from '@/types/table.ts'
 import { FieldSpecialEffectType } from '@/types/tableText.ts'
 
 import { initLoadResource } from '@/utils/resource'
 import { fuzzySearch, throttleFunc } from '@/utils/common'
-import { useCustomFilter } from '@/hooks/useCustomFilter.ts'
+
 import { useTable } from '@/hooks/useTable.ts'
 import { useRequest } from '@/hooks/useRequest.ts'
 import { computed, onMounted, reactive, ref, toRaw, watch } from 'vue'
-import { Filter } from '@element-plus/icons-vue'
 
-import CustomFilter from '../form/CustomFilter.vue'
+import TableFilterForm from '../form/TableFilterForm/TableFilterForm.vue'
 import FilterPopover from '../toolsBtn/FilterPopover.vue'
 import RefreshBtn from '../toolsBtn/RefreshBtn.vue'
 import TableFieldText from './TableFieldText.vue'
 import axiosInstance from '@/utils/axios/axiosInstance.ts'
-import { isArray } from 'element-plus/es/utils/types.mjs'
-
-type CustomFilterRef = InstanceType<typeof CustomFilter>
-
-interface SelectAllItem {
-  isCheckAll: boolean // 是否选中了所有
-  isIndeterminate: boolean // 是否是中间状态
-}
-
-// 所有选择框的全选按钮信息
-const filterFormCheckAllInfo = ref<Record<string, SelectAllItem>>({})
+type TableFilterFormRef = InstanceType<typeof TableFilterForm>
 
-// 自定义筛选组件的ref
-const customFilterRef = ref<CustomFilterRef>()
+// 查询表单的Ref
+const filterFormRef = ref<TableFilterFormRef>()
 
 const { analysisResCode } = useRequest()
 
-const {
-  customFilterDialog,
-  customFilterInfo,
-  customFilterList,
-  activeCustomFilterKey,
-  initCustomFilterInfo,
-  resetCustomFilterList,
-  openCustomFilter,
-  openedInit,
-  confirmCustomFilter
-} = useCustomFilter(customFilterRef)
 // 节流的延迟时间
 const throttleTime = 500
 
 // 表格工具图标大小
 const toolsIconSize = ref(25)
 
-// 查询表单
-const queryFormRef = ref<FormInstance>()
-
 const props = withDefaults(defineProps<PropsParams>(), {
   needRowindex: true,
   needAverage: false,
@@ -97,11 +64,6 @@ const backupTableData: Array<any> = []
 // 查询表单的数据
 const queryFormData = reactive<{ [key: string]: any }>({})
 
-const backupQueryFormData = reactive<{ [key: string]: any }>({})
-
-// 备份其他的请求信息
-let backupReqOtherOptions = {}
-
 // 分页数据
 const paginationConfig = reactive<TablePaginationSetting>({
   currentPage: 1,
@@ -141,36 +103,6 @@ const tableDataNoPaging = computed<any[]>(() => {
   return tableData.slice(begin, end)
 })
 
-// 所有类型为input的表单控件信息
-const inputFieldsList = computed(() => {
-  return props.queryInfo?.filter((item) => item.type === FilterType.INPUT)
-})
-
-// 所有类型为select的表单控件信息
-const selectFieldsList = computed(() => {
-  return props.queryInfo?.filter((item) => {
-    const isSelect = item.type === FilterType.SELECT || item.type === FilterType.MULTI_SELECT
-    if (isSelect && item.type === FilterType.MULTI_SELECT) {
-      filterFormCheckAllInfo.value[item.name] = {
-        isCheckAll: true,
-        isIndeterminate: false
-      }
-    }
-    return isSelect
-  })
-})
-
-// 所有类型为date的表单控件信息
-const dateFieldsList = computed(() => {
-  if (!props.queryInfo) return []
-  return props.queryInfo?.filter((item) => item.type === FilterType.DATE)
-})
-
-// 所有自定义筛选条件的表单控件信息
-const customFieldsList = computed(() => {
-  return props.queryInfo?.filter((item) => item.type === FilterType.CUSTOM)
-})
-
 // 计算行号
 const computedRowIndex = (index: number) => {
   return (paginationConfig.currentPage - 1) * paginationConfig.limit + index + 1
@@ -309,29 +241,6 @@ const queryTableData = () => {
 const throttleQueryTableData = throttleFunc(queryTableData, throttleTime)
 
 /**
- * 重置查询表单参数
- */
-const resetQueryFormData = () => {
-  let data = JSON.parse(
-    JSON.stringify(backupQueryFormData, (_, v) => (typeof v === 'undefined' ? '' : v))
-  )
-  Object.assign(queryFormData, data)
-  reqConfig.otherOptions = backupReqOtherOptions // 要把请求的参数也重置一次,不然切换平台等操作,会带着原来地查询参数请求
-}
-
-/**
- * @description: 重置整个查询表单,重置后,再请求一次全部表格
- */
-const resetQueryForm = () => {
-  resetQueryFormData() // 重置查询表单
-  initCustomFilterInfo(customFieldsList) // 重置自定义表单数据
-  throttleQueryTableData()
-}
-
-// 把重置方法包装一下,节流
-const throttleResetQueryForm = throttleFunc(resetQueryForm, throttleTime)
-
-/**
  * @description: 在获取完数据后,插入均值行
  * @param  start 插入的位置
  * @param  rowData 插入的数据
@@ -382,17 +291,9 @@ const tableCellStyle = (info: any) => {
 const watchLimit = watch(
   () => paginationConfig.limit,
   (newLimit, oldLimit) => {
-    // resetQueryForm(false)
-
     if (newLimit !== oldLimit) {
-      resetQueryFormData()
-      // 需要给分页按钮加上:current-page.sync="current_page" 配置,不然不生效
-      // 当改变每页大小时把之前的缓存全部清除,重新开始
-      if (paginationConfig.currentPage !== 1) {
-        paginationConfig.currentPage = 1
-      } else {
-        getData()
-      }
+      paginationConfig.currentPage = 1
+      filterFormRef.value?.throttleResetQuery()
     }
   },
   { deep: true }
@@ -427,8 +328,7 @@ watch(
   () => props.requestConfig?.otherOptions.gid,
   (newGid, oldGid) => {
     if (newGid != oldGid) {
-      // resetQueryForm(false)
-      resetQueryFormData()
+      filterFormRef.value?.resetFormData()
       reqConfig.otherOptions.gid = newGid
 
       getData()
@@ -442,8 +342,7 @@ const watchPf = watch(
   () => props.requestConfig?.otherOptions.pf,
   (newPf, oldPf) => {
     if (newPf != oldPf) {
-      // resetQueryForm(false)
-      resetQueryFormData()
+      filterFormRef.value?.resetFormData()
       reqConfig.otherOptions.pf = newPf
       getData()
     }
@@ -455,9 +354,7 @@ const watchPf = watch(
 const changeDataList = watch(
   () => [props.dataList],
   () => {
-    // resetQueryForm(false)
-    resetQueryFormData()
-    getData()
+    filterFormRef.value?.throttleResetQuery()
   },
   {
     deep: true
@@ -468,9 +365,7 @@ const changeDataList = watch(
 const watchDateChange = watch(
   () => [props.requestConfig?.otherOptions.startTime, props.requestConfig?.otherOptions.endTime],
   () => {
-    // resetQueryForm(false)
-    resetQueryFormData()
-    getData()
+    filterFormRef.value?.throttleResetQuery()
   },
   { deep: true }
 )
@@ -510,24 +405,11 @@ const initReqConfig = () => {
 }
 
 /**
- * @description: 初始化查询框的数据
- */
-const initFormData = () => {
-  props.queryInfo?.map((item: any) => {
-    queryFormData[item.name] = item.default
-    backupQueryFormData[item.name] = item.default
-  })
-  // backupQueryFormData = JSON.parse(JSON.stringify(queryFormData))
-  Object.assign(backupQueryFormData, JSON.parse(JSON.stringify(queryFormData)))
-}
-
-/**
  * @description: 表格排序
  * @param {*} data 获取到的数据
  */
 const tableSortChange = (data: { column: any; prop: string; order: any }) => {
-  // resetQueryForm(false)
-  resetQueryFormData()
+  filterFormRef.value?.resetFormData()
   let { order } = { ...data }
   if (order === 'ascending') order = 'asc'
   else if (order === 'descending') order = 'desc'
@@ -546,9 +428,7 @@ const deleteRow = (url: string, fieldsInfo: any) => {
     .post(url, { ...fieldsInfo })
     .then((data) => {
       analysisResCode(data).then(() => {
-        // resetQueryForm(false)
-        resetQueryFormData()
-        getData()
+        filterFormRef.value?.throttleResetQuery()
       })
     })
     .catch((err) => {
@@ -570,138 +450,19 @@ const outGetTableData = () => {
   return toRaw(tableData).flat()
 }
 
-/**
- * 格式化输入框的值,只允许输入数字
- *
- * @param key 输入框的key
- */
-const numberInput = (key: string) => {
-  let val = queryFormData[key]
-  val = parseInt(val)
-  if (isNaN(val)) {
-    val = 0
-  }
-  queryFormData[key] = val
-}
-
-/**
- * 接收重置表单命令
- */
-const resetCustomFilterData = () => {
-  resetCustomFilterList(FormData)
-}
-
-const isMultipleSelect = (item: QueryInfo): boolean => {
-  const options = item.otherOption
-  const formList = queryFormData[item.name]
-  let result = true
-  if (item.type !== FilterType.MULTI_SELECT) {
-    result = false
-    console.error('非多选类型')
-  }
-  if (!(options && isArray(options))) {
-    result = false
-    console.error('选项为空或非数组')
-  }
-  if (!(formList && isArray(formList))) {
-    result = false
-    console.error('表单数据为空或非数组')
-  }
-  return result
-}
-
-/**
- * 根据全选情况改变选择情况
- *
- * @param item 查询条件信息
- * @param formList 表单数据
- */
-const changeCheckAll = (item: QueryInfo) => {
-  if (!isMultipleSelect(item)) return
-  const options = item.otherOption as Array<SelectInfo>
-  const activeSelectInfo = filterFormCheckAllInfo.value[item.name]
-  const isCheckAll = activeSelectInfo.isCheckAll
-  const formList = queryFormData[item.name]
-
-  activeSelectInfo.isIndeterminate = false
-  if (isCheckAll) {
-    const valList = options.map((option) => {
-      return option.value
-    })
-    formList.splice(0, formList.length, ...valList)
-  } else {
-    formList.splice(0, formList.length)
-  }
-}
-
-/**
- * 处理点击多选按钮事件。
- *
- * formData对应的值不为数组或不是多选类型则报错
- *
- * @param item 查询条件信息
- */
-const handleCheckAll = (item: QueryInfo) => {
-  changeCheckAll(item)
-}
-
-/**
- * 处理选项改变
- * 单选情况:不处理
- * 多选情况:改变上方多选框状态
- *
- * @param item 查询条件信息
- * @param val 目前选择的值
- */
-const selectChange = (item: QueryInfo, val: any) => {
-  // 目前只处理数组
-  if (!isArray(val)) {
-    return
-  }
-  // 不符合多选信息的不处理
-  if (!isMultipleSelect(item)) return
-  const activeCheckInfo = filterFormCheckAllInfo.value[item.name]
-  if (!activeCheckInfo) {
-    console.error('不存在的多选信息')
-    return
-  }
-  const options = item.otherOption as Array<SelectInfo>
-  const isSelectedAll = val.length === options.length
-
-  activeCheckInfo.isCheckAll = isSelectedAll
-
-  if (val.length === 0) {
-    activeCheckInfo.isIndeterminate = false
-  } else {
-    activeCheckInfo.isIndeterminate = !isSelectedAll
-  }
-}
-
 // 定义暴露出去的方法
 defineExpose({
   getData,
   resetTableData,
   deleteRow,
   downLoadTable,
-  outGetTableData,
-  resetQueryForm
+  outGetTableData
 })
 
 onMounted(() => {
   initPageConfig()
   initReqConfig()
-  initFormData()
-  initCustomFilterInfo(customFieldsList)
-  backupReqOtherOptions = reqConfig.otherOptions // 备份一份请求参数
-  // registerWatchProps()
-  // if (props.loadingState !== undefined) {
-  //   loading.value = props.loadingState
-  // }
   loading.value = props.loadingState
-  // 这里会造成有的table页第一次进来刷新两次,因为有的页面gid或者平台等数据会变化,导致请求第二次
-  // 但是这里又必须请求一次,因为有的页面数据是没有变化的
-  // 可以直接在没有变化的页面,外部调用getData
-  // getData()
   // 去加载所有需要的资源
   initLoadResource(resourceInfo).then((data) => {
     Object.assign(blobUrlInfo, data)
@@ -711,185 +472,21 @@ onMounted(() => {
 
 <template>
   <div class="tableContent">
-    <div class="filterBox" v-if="openFilterQuery">
+    <div class="filterBox" v-if="openFilterQuery && queryInfo">
       <!-- slot -->
       <div class="filterHeader">
         <span>查询条件</span>
       </div>
       <div class="filterBody">
-        <el-form
-          :inline="true"
-          ref="queryFormRef"
-          :model="queryFormData"
-          class="queryForm"
-          :label-position="'left'"
-        >
-          <template v-for="item in inputFieldsList" :key="item.name">
-            <!-- 所有的input查询框 -->
-            <el-form-item
-              @keyup.enter="throttleQueryTableData"
-              :label="item.label"
-              v-if="item.valueType !== 'int'"
-              class="filterItem"
-            >
-              <el-input
-                clearable
-                :placeholder="item.placeholder"
-                v-model="queryFormData[item.name]"
-              />
-            </el-form-item>
-            <el-form-item
-              @keyup.enter="throttleQueryTableData"
-              :label="item.label"
-              v-else
-              class="filterItem"
-            >
-              <el-input
-                clearable
-                :placeholder="item.placeholder"
-                v-model="queryFormData[item.name]"
-                @input="numberInput(item.name)"
-              />
-            </el-form-item>
-          </template>
-
-          <!-- 所有选择框 -->
-          <el-form-item
-            :label="item.label"
-            v-for="item in selectFieldsList"
-            :key="item.name"
-            class="filterItem"
-          >
-            <template #label="{ label }">
-              <span class="selectLabelContainer">
-                <span class="selectLabel"> {{ label }}</span>
-                <span class="selectSupplement" v-if="item.supplementInfo">
-                  <!-- <el-icon><QuestionFilled /></el-icon>
-                  {{ item.supplementInfo }} -->
-                  <el-popover placement="top" trigger="hover">
-                    <p
-                      style="
-                        width: auto;
-                        padding: 0 5px;
-                        display: inline-block;
-                        text-align: center;
-                        color: black;
-                      "
-                    >
-                      {{ item.supplementInfo }}
-                    </p>
-                    <template #reference>
-                      <el-icon><QuestionFilled /></el-icon>
-                    </template>
-                  </el-popover>
-                </span>
-              </span>
-            </template>
-            <el-select
-              :empty-values="[undefined, null]"
-              v-model="queryFormData[item.name]"
-              :placeholder="item.placeholder"
-              :value-key="item.name"
-              collapse-tags
-              collapse-tags-tooltip
-              style="width: 240px"
-              :multiple="item.type === FilterType.MULTI_SELECT"
-              @change="selectChange(item, queryFormData[item.name])"
-            >
-              <template #header v-if="item.type === FilterType.MULTI_SELECT">
-                <el-checkbox
-                  v-model="filterFormCheckAllInfo[item.name].isCheckAll"
-                  :indeterminate="filterFormCheckAllInfo[item.name].isIndeterminate"
-                  @change="handleCheckAll(item)"
-                >
-                  全部
-                </el-checkbox>
-              </template>
-              <el-option
-                v-for="val in item.otherOption"
-                :key="val.name"
-                :label="val.cnName"
-                :value="val.value"
-              />
-            </el-select>
-          </el-form-item>
-
-          <!-- 所有日期选择框 -->
-          <el-form-item
-            :label="item.label"
-            v-for="item in dateFieldsList"
-            :key="item.name"
-            class="filterItem"
-          >
-            <el-date-picker
-              v-model="queryFormData[item.name]"
-              type="date"
-              :value-format="item.otherOption.valueFormat"
-              :placeholder="item.placeholder"
-              clearable
-            />
-          </el-form-item>
-
-          <!-- 所有自定义筛选条件 -->
-          <el-form-item
-            :label="item.label"
-            v-for="item in customFieldsList"
-            :key="item.name"
-            class="filterItem"
-          >
-            <el-button plain size="default" :icon="Filter" @click="openCustomFilter(item)"
-              >筛选
-            </el-button>
-          </el-form-item>
-        </el-form>
-        <!-- 分割线 -->
-        <!-- <el-divider class="queryPartition" content-position="center" direction="vertical" /> -->
-        <div class="queryBox">
-          <el-divider class="queryPartition" content-position="center" direction="vertical" />
-          <div class="queryBtnBox">
-            <el-button class="queryBtn" color="#165dff" @click="throttleQueryTableData">
-              <el-icon>
-                <Search />
-              </el-icon>
-              查询
-            </el-button>
-            <el-button class="refreshBtn" color="#f2f3f5" @click="throttleResetQueryForm()">
-              <el-icon>
-                <RefreshRight />
-              </el-icon>
-              重置
-            </el-button>
-          </div>
-        </div>
-        <el-dialog
-          v-model="customFilterDialog"
-          title="自定义筛选条件"
-          width="800"
-          @open="openedInit"
-        >
-          <CustomFilter
-            :custom-filter-list="customFilterList[activeCustomFilterKey]"
-            :filter="customFilterInfo[activeCustomFilterKey]"
-            @reset-filter-list="resetCustomFilterData"
-            ref="customFilterRef"
-          ></CustomFilter>
-          <template #footer>
-            <div class="dialog-footer">
-              <el-button
-                type="primary"
-                @click="confirmCustomFilter(queryFormData)"
-                style="margin-right: 20px"
-              >
-                确定
-              </el-button>
-              <el-button @click="customFilterDialog = false">取消</el-button>
-            </div>
-          </template>
-        </el-dialog>
+        <TableFilterForm
+          v-model:queryFormData="queryFormData"
+          :queryInfo="queryInfo"
+          @query="throttleQueryTableData"
+          ref="filterFormRef"
+        ></TableFilterForm>
       </div>
     </div>
-    <!-- 分割线 -->
-    <!-- <el-divider class="partition" content-position="center" /> -->
+
     <div class="tableTools">
       <div class="leftTools">
         <div class="leftToolsGroup" v-if="needLeftTools" style="display: flex">
@@ -1117,7 +714,6 @@ onMounted(() => {
   width: 90%;
   display: flex;
   flex-wrap: wrap;
-  /* justify-content: space-between; */
 }
 
 .filterItem {

+ 3 - 3
src/hooks/useCustomFilter.ts

@@ -1,4 +1,4 @@
-import type { ComputedRef, Reactive, Ref } from 'vue'
+import type { Reactive, Ref } from 'vue'
 import type {
   CustomFilter as CustomFilterInfo,
   DatePickerCustomFilter,
@@ -69,8 +69,8 @@ export function useCustomFilter(customFilterRef: Ref<CustomFilterRef | undefined
    * 初始化每个筛选器的信息,为筛选器赋值类型,让筛选器根据类型不同,渲染不同组件。
    *
    */
-  const initCustomFilterInfo = (customFieldsList: ComputedRef<QueryInfo[] | undefined>) => {
-    customFieldsList.value?.forEach((item) => {
+  const initCustomFilterInfo = (customFieldsList: QueryInfo[] | undefined) => {
+    customFieldsList?.forEach((item) => {
       customFilterList[item.name] = [
         {
           filterCondition: 'gt',

+ 2 - 12
src/views/Home/InfoManage/GameManageView.vue

@@ -6,7 +6,7 @@ import type { FormField } from '@/types/form'
 
 import { FormFieldType } from '@/types/form'
 import { FilterType } from '@/types/table'
-import { onMounted, reactive, ref, watch } from 'vue'
+import { onMounted, reactive, ref } from 'vue'
 import { useRequest } from '@/hooks/useRequest'
 import { useCommonStore } from '@/stores/useCommon'
 
@@ -14,7 +14,7 @@ import Dialog from '@/components/common/CustomDialog.vue'
 import Table from '@/components/table/CustomTable.vue'
 import { FieldSpecialEffectType } from '@/types/tableText.ts'
 
-const { allGameInfo, selectInfo } = useCommonStore()
+const { allGameInfo } = useCommonStore()
 const { AllApi } = useRequest()
 
 const gameTableRef = ref<InstanceType<typeof Table>>()
@@ -297,16 +297,6 @@ const formSub = (formData: any, type: number) => {
   gameTableRef.value?.getData()
 }
 
-watch(
-  () => selectInfo.gid,
-  () => {
-    gameTableRef.value?.resetQueryForm()
-  },
-  {
-    deep: true
-  }
-)
-
 onMounted(() => {
   gameTableRef.value?.getData()
 })

+ 2 - 5
src/views/Home/InfoManage/PlayerManageView.vue

@@ -12,11 +12,12 @@ import { FormFieldType } from '@/types/form'
 import { useRequest } from '@/hooks/useRequest'
 import { useCommonStore } from '@/stores/useCommon'
 import { useAnalysis } from '@/hooks/useAnalysis'
+import { usePage } from '@/hooks/usePage'
 
 import Dialog from '@/components/common/CustomDialog.vue'
 import Table from '@/components/table/CustomTable.vue'
 import axiosInstance from '@/utils/axios/axiosInstance'
-
+const { watchPageChange } = usePage()
 const { updateReqConfig } = useAnalysis()
 
 const { AllApi, analysisResCode } = useRequest()
@@ -251,10 +252,6 @@ const updateSelect = (gid: any) => {
 
 const backupSelect = reactive([])
 
-import { usePage } from '@/hooks/usePage'
-
-const { watchPageChange } = usePage()
-
 watchPageChange(() => [selectInfo.gid], backupSelect, updateSelect)
 </script>
 <template>