vue3封裝移動端table組件

table組件示例

table組件大概長這樣,總計行不需要可以刪除

CustomTable.vue 子組件

<template>
  <div class="report_table">
    <!-- 表頭 -->
    <div class="table_columns">
      <div
        class="cell"
        v-for="item in props.columns"
        :key="item.prop"
        :style="{ width: item.width }"
      >
        {{ item.lable }}
      </div>
    </div>
    <!-- 匯總 -->
    <div class="summary">
      <slot name="summary"></slot>
    </div>

    <!-- 內(nèi)容區(qū)域 -->
    <div
      class="table_source"
      @scroll="
        () => {
          if (props.tableType === 1) {
            handleScroll();
          }
        }
      "
      ref="tableRef"
      v-if="props.dataSource.length"
    >
    <!-- 下拉刷新  -->
      <van-pull-refresh
        v-model="props.refreshLoading"
        @refresh="emits('onRefresh')"
      >
        <div class="row" v-for="record in props.dataSource" :key="record.id">
          <div
            class="cell"
            v-for="items in columns"
            :key="items"
            :style="{ width: items.width }"
          >
            <div class="cell_item" v-if="items.moneyType">
              ¥{{ record[items.prop] }}
            </div>
            <div class="cell_item" v-else>{{ record[items.prop] }}</div>
          </div>
        </div>
      </van-pull-refresh>
    </div>
    <!-- 暫無內(nèi)容區(qū)域 -->
    <div class="no_data" v-else>
      <span class="data_text">暫無內(nèi)容</span>
    </div>
  </div>
</template>


<script setup>
import { ref } from "vue";

const props = defineProps({
  // 當前加載的table類型,  1.  滾動動態(tài)請求數(shù)據(jù)  2. 滾動不請求數(shù)據(jù)
  tableType: {
    type: Number,
    default: null,
  },
  // 列表數(shù)據(jù)
  dataSource: {
    type: Array,
    default: () => [],
  },
  // 列表字段
  columns: {
    type: Array,
    default: () => [],  // width 參數(shù)建議設置 百分比摸柄,設置百分比可自適應
  },
  refreshLoading: {
    type: Boolean,
    default: false,
  },
  total: {
    type: Number,
    default: 0,
  },
});

const emits = defineEmits(["onRefresh", "onTableScroll"]);

const tableRef = ref(null);

// 上拉刷新
const handleScroll = () => {
  // 變量scrollTop是滾動條滾動時导犹,距離頂部的距離
  const scrollTop = tableRef.value.scrollTop;
  // 變量scrollHeight是滾動條的總高度
  const scrollHeight =
    tableRef.value.scrollHeight;
  // 變量clientHeight是滾動條可視區(qū)域的高度
  const clientHeight =
    tableRef.value.clientHeight;

  // 當滾動條到達底部湖苞,并且距離底部小于10px時,加載數(shù)據(jù)
  if (scrollTop + clientHeight >= scrollHeight) {
    if (props.total > props.dataSource.length) {
      emits('onTableScroll')
    }
  }
};
</script>

<style lang="scss" scoped>
.report_table {
  width: 100%;
  height: 0;
  flex: 1;
  background: #fff;
  .table_columns {
    width: 100%;
    height: 50px;
    font-weight: 400;
    font-size: 15px;
    color: #989898;
    display: flex;

    .cell {
      height: 100%;
      line-height: 50px;
      text-align: center;
    }
  }

  .summary {
    width: 100%;
    height: 50px;
    border-top: 1px solid #efefef;
    box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.13);

    display: flex;
    color: #2c2c2c;
    font-size: 15px;
  }

  .table_source {
    height: calc(100% - 100px);
    overflow: auto;
    .row {
      display: flex;
      padding: 15px 0;
      border-bottom: 1px solid #efefef;

      .cell {
        font-weight: 400;
        font-size: 15px;
        color: #2c2c2c;
        text-align: center;

        .cell_item {
          width: 100%;
          word-break: break-all;
        }
      }
    }
  }

  .no_data {
    width: 100%;
    height: calc(100% - 100px);
    background: #F6F6F6;
    text-align: center;

    .data_text {
      display: inline-block;
      margin-top: 50px;
    }
  }
}
</style>

index.vue 父組件

<template>
  <div class="booking">
    <!-- 導航欄 -->
    <van-sticky>
      <NavBar :title="title" @on-back="handleBack"></NavBar>
    </van-sticky>
    <div class="report_table_container">
      <!-- 檢索組件 -->
      <Search :searchList="searchList" @on-search="handleSearch"/>
      <!-- table組件 -->
      <Table :total="page.total" :columns="columns" :dataSource="dataSource" :tableType="tableType" @onRefresh="handleRefresh" :refreshLoading="refreshLoading" @onTableScroll="handleTableScroll">
        <!--插槽部分-->
        <template #summary>
          <div class="report_table_summary" style="width: 12%">總計</div>
          <div class="report_table_summary" style="width: 44%">0臺</div>
          <div class="report_table_summary" style="width: 22%">¥0</div>
          <div class="report_table_summary" style="width: 22%">¥0</div>
        </template>
      </ReportTable>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref } from "vue";
import { useRouter } from "vue-router";

import Search  from "./components/Search.vue";
import Table from "./components/Table.vue";

// 
const tableType = ref(1);
const router = useRouter();
const searchList = ref([
  {
    placeholder: "請輸入姓名",
    value: "username",
  },
  {
    placeholder: "別名",
    value: "nickname",
  },
]);
// 列表下拉loading
const refreshLoading = ref(false);
// 表頭 
const columns = ref([
    {
        lable: "編號",
        prop: "id",
        width: '12%',
    },
    {
        lable: "姓名",
        prop: "username",
        width: '22%',
    },
    {
        lable: "別名",
        prop: "nickname",
        width: '22%',
    },
    {
        lable: "金額",
        prop: "money",
        width: '22%',
        moneyType: true
    },
    {
        lable: "余額",
        prop: "balance",
        width: '22%',
        moneyType: true
    },
]);
// table內(nèi)容
const dataSource = ref([])
// 分頁參數(shù)
const page = ref({
  pageNum: 1,
  pageRow: 20,
  total: 0,
});

onMounted(() => {
  // 獲取明細數(shù)據(jù)
  getList()
})


// 檢索
const handleSearch = (formData) => {
  getList(formData)
}

// 滾動加載
const handleTableScroll = () => {
   page.value.pageNum++;
   getList()
}

// 獲取table列表
const getList = (searchParams) => {
   const params = {
      ...page.value,   // 分頁數(shù)據(jù)
     ...searchParams  // search組件參數(shù)
   }

    .............
}

// 下拉刷新
const handleRefresh = () => {
  page.value.pageNum = 1
  refreshLoading.value = true
  // 請求數(shù)據(jù)  ......
  getList()
}

const handleBack = () => {
  router.go(-1);
};
</script>t pa


最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纵竖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辽聊,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涯鲁,死亡現(xiàn)場離奇詭異帝雇,居然都是意外死亡甜害,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門玛臂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人封孙,你說我怎么就攤上這事迹冤。” “怎么了虎忌?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵泡徙,是天一觀的道長。 經(jīng)常有香客問我膜蠢,道長堪藐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任挑围,我火速辦了婚禮礁竞,結果婚禮上,老公的妹妹穿的比我還像新娘杉辙。我一直安慰自己模捂,他們只是感情好,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布奏瞬。 她就那樣靜靜地躺著枫绅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪硼端。 梳的紋絲不亂的頭發(fā)上并淋,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機與錄音珍昨,去河邊找鬼县耽。 笑死句喷,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的兔毙。 我是一名探鬼主播唾琼,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼澎剥!你這毒婦竟也來了锡溯?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤哑姚,失蹤者是張志新(化名)和其女友劉穎祭饭,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叙量,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡倡蝙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绞佩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寺鸥。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖品山,靈堂內(nèi)的尸體忽然破棺而出胆建,到底是詐尸還是另有隱情,我是刑警寧澤谆奥,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布眼坏,位于F島的核電站,受9級特大地震影響酸些,放射性物質(zhì)發(fā)生泄漏宰译。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一魄懂、第九天 我趴在偏房一處隱蔽的房頂上張望沿侈。 院中可真熱鬧,春花似錦市栗、人聲如沸缀拭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛛淋。三九已至,卻和暖如春篡腌,著一層夾襖步出監(jiān)牢的瞬間褐荷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工嘹悼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留叛甫,地道東北人层宫。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像其监,于是被迫代替她去往敵國和親萌腿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容