element-plus表格渲染数据(多选框+分页)(二)

我们接着上回,没看上一回的建议先看一下,不讲废话,上一回我们创建完表格了,也渲染了静态数据上去,现在我们接着做分页。

还是老样子,我把前一回的注释都删了,现在看到的注释就是比较关键的点,帮助大家理解学习

分页:

<script setup>
import { reactive } from 'vue';

//模拟后端返回的数据,如果是发请求的话,每次返回的数据条数应该是你限定的条数,这里先定义九条数据备用,实际开发发请求就有数据了
const tableData = [
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称',
      goodsDesc: '商品详情'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称',
      goodsDesc: '商品详情'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称',
      goodsDesc: '商品详情'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称',
      goodsDesc: '商品详情'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称',
      goodsDesc: '商品详情'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
]

//模拟后端接口需要传递的参数,也是分页要用到的三个值,数据总数,偏移值和每页显示的条数
const pageData = reactive({
  //定义分页的偏移值(偏移值就是往后移动固定条数取数据,比如偏移值为5,第一次取索引值为0-4的数据,第二次取5-10,以此类推)
  offset: 0,
  //定义每次请求回来的数据,有些接口会定义limit参数,就是每次返回几条数据
  limit: 5,
  //定义数据的总条数,有些接口会返回一个总条数的值,没有的也可以用全部数据.length来代替这个total
  total:12
})

//建议大家自己执行一下这个函数,加深记忆,该事件定义在el-pagination上,当前页改变的时候就会触发
const handleCurrentChange = (e) => {
//e打印的就是去到的那一页的索引
  console.log(e);
}
</script>

<template>
  <div class="constainer">
    <div class="content">
      <el-table :row-style="{ height: '110px' }" :data="tableData">
        <el-table-column type="selection" width="70" align="center" />
        <el-table-column label="商品" width="270" align="center">
          <template v-slot="scope">
            <div class="goods-info">
              <img :src="scope.row.goodsDetail.goodsImg" alt="" class="cart-img" />
              <div>
                <p>{{ scope.row.goodsDetail.goodsName }}</p>
                <p class="desc">
                  {{ scope.row.goodsDetail.goodsDesc }}
                </p>
              </div>
            </div>
          </template>
        </el-table-column>
        <!-- prop="属性名"来绑定每一列数据 -->
        <el-table-column prop="goodsPrice" label="单价" width="120" align="center">
        </el-table-column>
        <el-table-column prop="goodsNum" label="数量" align="center" width="140"> </el-table-column>
        <el-table-column label="小计" width="120" align="center">
          <template v-slot="scope"> ¥{{ scope.row.goodsPrice * scope.row.goodsNum }} </template>
        </el-table-column>
        <el-table-column prop="" label="操作" width="180" align="center">
          <template #default="scope">
            <!-- 气泡弹出框来确认用户是否要删除商品 @confirm写确认后的事件,逻辑很简单,这个函数是假的,只是示范一下 -->
            <el-popconfirm title="你确定要删除吗?" @confirm="deleteGoods(scope.row.id)">
              <template #reference>
                <el-button type="info">移除商品</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <div class="allTotal">
        <!-- el-pagination用来定义分页 -->
        <!-- :total定义数据的总数 -->
        <!-- v-model:page-size定义每页显示个数 -->
        <!-- current-change是一个事件,当前页发生改变的时候就会触发,可以自己打印输出看一下 -->
        <el-pagination
        class="page"
        layout="prev, pager, next"
        background
        :total="pageData.total"
        @current-change="handleCurrentChange"
        v-model:page-size="pageData.limit"
      />
      <div class="total-box">
        <span class="total">总价:¥</span>
        <!-- <el-button type="info" size="large" class="totalBtn" v-if="selectListData.totalPrice === 0">去结算</el-button> -->
        <el-button type="primary" size="large" class="totalBtn">去结算</el-button>
      </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.constainer {
  width: 100vw; //宽等于屏幕的宽
  height: 100vh; //高等于屏幕的高
  background-color: #ccc;
  padding-top: 50px;
}
.content {
  width: 900px;
  height: 700px;
  margin: 0 auto;
  background-color: #fff;
  border-radius: 10px;
  overflow: hidden;
  .goods-info {
    display: flex;
    align-items: center;
    .cart-img {
      margin: 0 1.5em 0 1em;
      width: 80px;
      height: 80px;
    }
    p {
      text-align: left;
    }
    .desc {
      margin-top: 1em;
    }
  }
  .allTotal{
      display: flex;
      justify-content: space-between;
      .page{
      margin-left: 2em;
    }
    .total-box{
      display: flex;
      justify-content: center;
      align-items: center;
      margin: 2em 2em 2em 0;
      .total{
      display: inline-block;
      font-size: 20px;
      height: 40px;
      line-height: 40px;
      
    }
    .totalBtn{
      margin-left: 1em;
      width: 150px;
    }
    }
    
    }
}
</style>

效果:

当然,现在翻页是没效果的,所以我们接着往下:

<script setup>
import { reactive,ref } from 'vue';

const tableData = [
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称1',
      goodsDesc: '商品详情1'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称2',
      goodsDesc: '商品详情2'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称3',
      goodsDesc: '商品详情3'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称4',
      goodsDesc: '商品详情4'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称5',
      goodsDesc: '商品详情5'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称6',
      goodsDesc: '商品详情6'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称7',
      goodsDesc: '商品详情7'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称8',
      goodsDesc: '商品详情8'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称9',
      goodsDesc: '商品详情9'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称10',
      goodsDesc: '商品详情10'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称11',
      goodsDesc: '商品详情11'
    },
    goodsPrice: 188,
    goodsNum: 3
  },
  {
    goodsDetail: {
      goodsImg: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
      goodsName: '商品名称12',
      goodsDesc: '商品详情12'
    },
    goodsPrice: 188,
    goodsNum: 3
  }
]
//这里定义一个变量来接收处理数据,用来渲染数据,实际开发的时候就不需要定义了,因为后端返回的数据就是切好的
const handleData = ref('')
const pageData = reactive({
  //这里定义偏移值为5
  offset: 5,
  limit: 5,
  total:12
})

const handleCurrentChange = (e) => {
  //e打印的是页码
  console.log(e);
  //想要做到数据的切换更新,那就需要我们在切换到不同页码的时候更新数据
  // 在分页上我们绑定了:page-size="pageData.limit",就是每页的条数,这是不变的,这时候就要用到偏移值来动态更新
  //这里我们用切割数组的方法,实际开发不用这样做,因为请求后端返回的数据已经是切割好的了
  // (e-1)*pageData.offset  因为我们默认页码是1开始的,而数据在第一页的偏移值应该是0,就是应该从第0条数据开始渲染
  // e*pageData.offset  一个偏移值就是5条数据,所以页码为1就是渲染前五条数据,页码为2就是渲染往后五条
  handleData.value = tableData.slice((e-1)*pageData.offset,e*pageData.offset)
}

//初始化页面的数据
const initData = () => {
  handleData.value = tableData.slice(0, pageData.offset)
}
initData()
</script>

<template>
  <div class="constainer">
    <div class="content">
      <!-- 没有后端返回的数据,用handleData模拟处理过后的数据 -->
      <el-table :row-style="{ height: '110px' }" :data="handleData">
        <el-table-column type="selection" width="70" align="center" />
        <el-table-column label="商品" width="270" align="center">
          <template v-slot="scope">
            <div class="goods-info">
              <img :src="scope.row.goodsDetail.goodsImg" alt="" class="cart-img" />
              <div>
                <p>{{ scope.row.goodsDetail.goodsName }}</p>
                <p class="desc">
                  {{ scope.row.goodsDetail.goodsDesc }}
                </p>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="goodsPrice" label="单价" width="120" align="center">
        </el-table-column>
        <el-table-column prop="goodsNum" label="数量" align="center" width="140"> </el-table-column>
        <el-table-column label="小计" width="120" align="center">
          <template v-slot="scope"> ¥{{ scope.row.goodsPrice * scope.row.goodsNum }} </template>
        </el-table-column>
        <el-table-column prop="" label="操作" width="180" align="center">
          <template #default="scope">
            <el-popconfirm title="你确定要删除吗?" @confirm="deleteGoods(scope.row.id)">
              <template #reference>
                <el-button type="info">移除商品</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <div class="allTotal">
        <el-pagination
        class="page"
        layout="prev, pager, next"
        background
        :total="pageData.total"
        @current-change="handleCurrentChange"
        v-model:page-size="pageData.limit"
      />
      <div class="total-box">
        <span class="total">总价:¥</span>
        <!-- <el-button type="info" size="large" class="totalBtn" v-if="selectListData.totalPrice === 0">去结算</el-button> -->
        <el-button type="primary" size="large" class="totalBtn">去结算</el-button>
      </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.constainer {
  width: 100vw; //宽等于屏幕的宽
  height: 100vh; //高等于屏幕的高
  background-color: #ccc;
  padding-top: 50px;
}
.content {
  width: 900px;
  height: 700px;
  margin: 0 auto;
  background-color: #fff;
  border-radius: 10px;
  overflow: hidden;
  .goods-info {
    display: flex;
    align-items: center;
    .cart-img {
      margin: 0 1.5em 0 1em;
      width: 80px;
      height: 80px;
    }
    p {
      text-align: left;
    }
    .desc {
      margin-top: 1em;
    }
  }
  .allTotal{
      display: flex;
      justify-content: space-between;
      .page{
      margin-left: 2em;
    }
    .total-box{
      display: flex;
      justify-content: center;
      align-items: center;
      margin: 2em 2em 2em 0;
      .total{
      display: inline-block;
      font-size: 20px;
      height: 40px;
      line-height: 40px;
      
    }
    .totalBtn{
      margin-left: 1em;
      width: 150px;
    }
    }
    
    }
}
</style>

效果:

分享到这里了,太晚了,现在基本效果是有了,但是多选框有些不足,不足就在你在一个页面选中的那些多选框,在切换页面后再切回来就恢复到未选中状态。所以要做一下回显,太晚了,爱惜身体,爱惜自己,对自己好一点。