vue中原生写分页组件

编程入门 行业动态 更新时间:2024-10-27 14:21:55

vue中原生写<a href=https://www.elefans.com/category/jswz/34/1769545.html style=分页组件"/>

vue中原生写分页组件

效果:

 分页的本质:

                    分批次的查询数据(基于页码page与每页的条数pagesize),后端接收到分页参数后,会基于这些参数查询数据库,然后基于数据库进行分页;基于sql语句(select * from user limit n,m);

分页组件需要实现的功能:

  • 基本组件的结果

  • 动态计算中间的页码

  • 控制省略号的显示和隐藏,控制页码的切换,点击第4页的时候会 居中显示和前后出现省略号,后2页的时候不显示后面的省略号,

     

  • 控制上一页和下一页的按钮禁用状态,点击第一页时候,前面没有省略号,上一页按钮为禁用状态

 

 全部代码:

父组件:父组件是一个评论列表

<template><div class="goods-comment" v-if="conditions"><div class="head"><div class="data"><p><span>{{ conditions.salesCount }}</span><span>人购买</span></p><p><span>{{ conditions.praisePercent }}</span><span>好评率</span></p></div><div class="tags"><div class="dt">大家都在说:</div><div class="dd"><ahref="javascript:;"@click="toggle(i)":class="{ active: currentIndex === i }"v-for="(item, i) in conditions.tags":key="i">{{ item.title }}({{ item.tagCount }})</a></div></div></div><div class="sort"><span>排序:</span><a href="javascript:;" :class="{ active: reqParams.sortField === null }" @click="changeSort(null)">默认</a><a href="javascript:;" @click="changeSort('createTime')" :class="{ active: reqParams.sortField === 'createTime' }">最新</a><ahref="javascript:;"@click="changeSort('praiseCount')":class="{ active: reqParams.sortField === 'praiseCount' }">最热</a></div><!-- 评论列表 --><div class="list"><!-- 列表 --><div class="item" v-for="item in list" :key="item.id"><div class="user"><img :src="item.member.avatar" alt="" /><span>{{ item.member.nickname }}</span></div><div class="body"><div class="score"><i class="iconfont icon-wjx01" v-for="star in item.score" :key="star"></i><i class="iconfont icon-wjx01" v-for="unstar in 5 - item.score" :key="unstar"></i><span class="attr">{{ formatSpec(item.orderInfo.specs) }}</span></div><div class="text">{{ item.content }}<!-- 评论图片的预览 --><GoodsCommentImage :pictures="item.pictures"></GoodsCommentImage></div><div class="time"><span>{{ item.createTime }}</span><span class="zan"><i class="iconfont icon-dianzan"></i>{{ item.praiseCount }}</span></div></div></div></div><!-- 分页组件 page=1是默认的高亮页码 --><XtxPagination :total="total" @changePage="changePage" :page="1" :pagesize="reqParams.pagesize"></XtxPagination></div>
</template>
<script>
import GoodsCommentImage from '@/views/goods/goods-comment-image.vue'
import { ref, inject, reactive, watch } from 'vue'
import { findCommentInfoByGoods, findCommentListByGoods } from '@/api/product.js'
export default {name: 'GoodsComment',props: {// id: {//   type: String,//   required: true// }},components: { GoodsCommentImage },setup() {const conditions = ref(null)const goods = inject('goods')const total = ref(0)findCommentInfoByGoods(goods.value.id).then(res => {res.result.tags.unshift({title: '有图',type: 'pic',tagCount: res.result.hasPictureCount})res.result.tags.unshift({title: '全部评价',type: 'all',tagCount: res.result.evaluateCount})conditions.value = res.result})const currentIndex = ref(0)const toggle = index => {currentIndex.value = index// 根据索引获取当前点击的标签的对象信息const info = conditions.value.tags[index]if (info.type === 'pic') {// 点击有图reqParams.hasPicture = truereqParams.tag = null} else if (info.type === 'all') {// 全部评价reqParams.hasPicture = nullreqParams.tag = null} else {// 其他的四个标签reqParams.hasPicture = nullreqParams.tag = info.title}reqParams.page = 1}const list = ref([])// 筛选条件准备// 改为响应式的才可以高亮const reqParams = reactive({// 当前页码page: 1,// 每页的条数pageSize: 10,// 是否有图片hasPicture: null,// 筛选条件tag: null,// 排序的字段sortField: null})findCommentListByGoods(goods.value.id, reqParams).then(res => {list.value = res.result.itemstotal.value = res.result.counts})// 控制排序条件的切换const changeSort = type => {reqParams.sortField = typereqParams.page = 1}// 检测reqParams是否有变化watch(reqParams, () => {findCommentListByGoods(goods.value.id, reqParams).then(res => {total.value = res.result.countslist.value = res.result.items})})// 格式化规格信息const formatSpec = spec => {return spec.reduce((ret, item) => {return ret + item.name + ':' + item.nameValue}, '')}// 修改分页组件const changePage = page => {reqParams.page = page}return { changePage, conditions, currentIndex, toggle, list, total, reqParams, changeSort, formatSpec }}
}
</script>
<style scoped lang="less">
.goods-comment {.list {padding: 0 20px;.item {display: flex;padding: 25px 10px;border-bottom: 1px solid #f5f5f5;.user {width: 160px;img {width: 40px;height: 40px;border-radius: 50%;overflow: hidden;}span {padding-left: 10px;color: #666;}}.body {flex: 1;.score {line-height: 40px;.iconfont {color: #ff9240;padding-right: 3px;}.attr {padding-left: 10px;color: #666;}}}.text {color: #666;line-height: 24px;}.time {color: #999;display: flex;justify-content: space-between;margin-top: 5px;}}}.head {display: flex;padding: 30px 0;.data {width: 340px;display: flex;padding: 20px;p {flex: 1;text-align: center;span {display: block;&:first-child {font-size: 32px;color: @priceColor;}&:last-child {color: #999;}}}}.tags {flex: 1;display: flex;border-left: 1px solid #f5f5f5;.dt {font-weight: bold;width: 100px;text-align: right;line-height: 42px;}.dd {flex: 1;display: flex;flex-wrap: wrap;> a {width: 132px;height: 42px;margin-left: 20px;margin-bottom: 20px;border-radius: 4px;border: 1px solid #e4e4e4;background: #f5f5f5;color: #999;text-align: center;line-height: 40px;&:hover {border-color: @xtxColor;background: lighten(@xtxColor, 50%);color: @xtxColor;}&.active {border-color: @xtxColor;background: @xtxColor;color: #fff;}}}}}.sort {height: 60px;line-height: 60px;border-top: 1px solid #f5f5f5;border-bottom: 1px solid #f5f5f5;margin: 0 20px;color: #666;> span {margin-left: 20px;}> a {margin-left: 30px;&.active,&:hover {color: @xtxColor;}}}
}
</style>

分页组件:

分为两种情况:

1.页码小于等于5

2.页码大于5:

       又分为三种情况

             1).页码小于2时候,页码从1开始到5结束;(左临界值)

              2).页码小于最大页码的后两个的时候,页码从pages(总页码)-4开始到pages结束(右临界值)

              3).页码始终在中间时,页码从currentPage-2开始到currentPage+2结束(currentPage是当前页面)

        

<template><div class="xtx-pagination"><a href="javascript:;" @click="changePage(false)" :class="{ disabled: currentPage === 1 }">上一页</a><span v-if="currentPage > 3">...</span><ahref="javascript:;"@click="changePage(item)":class="{ active: currentPage === item }"v-for="item in list":key="item">{{ item }}</a><span v-if="currentPage < pages - 2">...</span><a href="javascript:;" @click="changePage(true)" :class="{ disabled: currentPage === pages }">下一页</a></div>
</template>
<script>
import { computed, ref } from 'vue'
export default {name: 'XtxPagination',props: {total: {type: Number,default: 0},pagesize: {type: Number,default: 10}// // 默认初识页码,父组件给传 但是不这样接收// page: {//   type: Number,//   default: 1// }},setup(props, { emit, attrs }) {// attrs表示父组件传得属性,但是props没有接收的属性,这种属性不是强制的 ,或者不是响应式的// 动态计算中间的页码信息 基于一份数据获得另外一份数据// 以下两行是约定的每页的条数pagesize = 8// 总结数 默认值是0 在外边是只能有一次的计算所以放在计算属性中可以是根据传入的值随时变化的const pages = computed(() => Math.ceil(props.total / props.pagesize))console.log(attrs.page)const currentPage = ref(attrs.page || 1)const list = computed(() => {// 当父组件传递的total的值发生了变化的时候,计算属性要重新计算// pages = Math.ceil(props.total / props.pagesize)const result = []// 当前的页码// 页码小于等于5的情况if (pages.value <= 5) {for (let i = 1; i <= pages.value; i++) {result.push(i)}} else {// 大于5页的情况if (currentPage.value <= 2) {// 左侧临界值for (let i = 1; i <= 5; i++) {result.push(i)}} else if (currentPage.value >= pages.value - 1) {// 右侧临界值for (let i = pages.value - 4; i <= pages.value; i++) {result.push(i)}} else {// 中间的临界值for (let i = currentPage.value - 2; i <= currentPage.value + 2; i++) {result.push(i)}}}return result})// 控制上一页和下一页的变化const changePage = type => {if (type === false) {// 上一页// 页码是第一页的时候,上一页为disabled状态if (currentPage.value === 1) returnif (currentPage.value > 1) {currentPage.value -= 1}} else if (type === true) {// 下一页// 如果是最后的页面 下一页为disabled状态if (currentPage.value === pages.value) returnif (currentPage.value < pages.value) {currentPage.value += 1}} else {// 点击其他的页面currentPage.value = type}emit('changePage', currentPage.value)}return {list,currentPage,pages,changePage}}
}
</script>
<style scoped lang="less">
.xtx-pagination {display: flex;justify-content: center;padding: 30px;> a {display: inline-block;padding: 5px 10px;border: 1px solid #e4e4e4;border-radius: 4px;margin-right: 10px;&:hover {color: @xtxColor;}&.active {background: @xtxColor;color: #fff;border-color: @xtxColor;}&.disabled {cursor: not-allowed;opacity: 0.4;&:hover {color: #333;}}}> span {margin-right: 10px;}
}
</style>

注意:attrs的使用是将父组价中给子组件传值,不需要响应式的可以这么写哦~~ See you

更多推荐

vue中原生写分页组件

本文发布于:2024-02-13 04:03:32,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1690600.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:分页   组件   vue

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!