You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
5.8 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="tm-pagination flex-center">
<view v-if="tal" class="flex-start flex-wrap flex-between fulled">
<tm-button :fllowTheme="false" :shadow="4" :icon-size="24"
:font-color="nowIndex==1||disabled?'grey':color_tmeme" :black="black_tmeme" @click="tv_pre"
:disabled="nowIndex==1||disabled" theme="white" :item-class="round?'rounded':''" block height="64" width="64"
icon="icon-angle-left"></tm-button>
<block v-for="(item,index) in items " :key="index">
<tm-button :fllowTheme="false" :shadow="4" :disabled="disabled" :black="black_tmeme"
:theme="item==nowIndex?color_tmeme:'white'" @click="clicPages(item)" block
:item-class="round?'rounded':''" height="64" width="64">
{{item}}
</tm-button>
</block>
<tm-button :fllowTheme="false" :shadow="4" :icon-size="24"
:font-color="nowIndex==tal||disabled?'grey':color_tmeme" :black="black_tmeme" theme="white"
@click="tv_next" :disabled="nowIndex==tal||disabled?true:false" :item-class="round?'rounded':''" block
height="64" width="64" icon="icon-angle-right">
</tm-button>
</view>
</view>
</template>
<script>
/**
* 分页
* @property {Function} change 页面改变时触发。
* @property {Number} page = [] 默认1当前页码必须使用page.sync
* @property {Number} total-visible = [] 默认5最大可见页数
* @property {Number} total = [] 默认0总条数。
* @property {Number} size = [] 默认8每页的数量。
* @property {Boolean} round = [] 默认false,是否圆形按钮。
* @property {Boolean} black = [] 默认false,是否暗黑模式
* @property {Boolean} disabled = [] 默认false,禁用
* @property {String} color = [] 默认primary,选中的主题色
* @example <tm-pagination :page.sync="page" :total="100"></tm-pagination>
*/
import tmButton from "@/tm-vuetify/components/tm-button/tm-button.vue"
export default {
components: {
tmButton
},
name: "tm-pagination",
props: {
total: {
type: Number,
default: 0
},
// 最大可见按钮数量。
totalVisible: {
type: Number,
default: 5
},
// 当前页码。需要page.sync同步。
page: {
type: Number,
default: 1
},
// 每页的数量 。
size: {
type: Number,
default: 10
},
// 是否圆形按钮。
round: {
type: Boolean,
default: false
},
// 是否暗黑模式
black: {
type: Boolean | String,
default: null
},
// 主题色
color: {
type: String,
default: 'primary'
},
disabled: {
type: Boolean,
default: false
},
// 跟随主题色的改变而改变。
fllowTheme: {
type: Boolean | String,
default: true
}
},
watch: {
page: function(val) {
this.init()
}
},
computed: {
black_tmeme: function() {
if (this.black !== null) return this.black;
return this.$tm.vx.state().tmVuetify.black;
},
color_tmeme: function() {
if (this.$tm.vx.state().tmVuetify.color !== null && this.$tm.vx.state().tmVuetify.color && this
.fllowTheme) {
return this.$tm.vx.state().tmVuetify.color;
}
return this.color;
},
//总共的页码。
tal: function() {
if (this.total <= this.size) return 1;
let isInt = this.total % this.size;
let ds = this.total / this.size;
return isInt == 0 ? Math.floor(ds) : Math.floor(ds) + 1;
},
items: function() {
const totalVisible = parseInt(this.totalVisible, 10)<=5?5:parseInt(this.totalVisible, 10);
if(this.tal<=totalVisible){
return this.range(1, this.tal)
}
if (totalVisible === 0) {
return []
}
const maxLength = Math.min(
Math.max(0, totalVisible) || this.tal,
Math.max(0, this.maxButtons) || this.tal,
this.tal
)
if (this.tal <= maxLength) {
return this.range(1, this.tal)
}
const even = maxLength % 2 === 0 ? 1 : 0
const left = Math.floor(maxLength / 2)
const right = this.tal - left + 1 + even
if (this.page > left && this.page < right) {
const firstItem = 1
const lastItem = this.tal
const start = this.page - left + 2
const end = this.page + left - 2 - even
const secondItem = start - 1 === firstItem + 1 ? 2 : '...'
const beforeLastItem = end + 1 === lastItem - 1 ? end + 1 : '...'
return [1, secondItem, ...this.range(start, end), beforeLastItem, this.tal]
} else if (this.page === left) {
const end = this.page + left - 1 - even
return [...this.range(1, end), '...', this.tal]
} else if (this.page === right) {
const start = this.page - left + 1
return [1, '...', ...this.range(start, this.tal)]
} else {
return [
...this.range(1, left),
'...',
...this.range(right, this.tal),
]
}
},
},
data() {
return {
nowIndex: 1,
maxButtons: 0,
};
},
mounted() {
let t = this;
this.$Querey('.tm-pagination').then(res => {
let w = res[0].width;
t.maxButtons = Math.floor((w - uni.upx2px(20)) / uni.upx2px(64))
})
},
methods: {
clicPages(index) {
if (index == '...') return;
this.$emit('input', index)
this.$emit('update:page', index)
this.$emit('prev')
this.$emit('change',index)
},
tv_pre() {
this.$emit('input', this.page - 1)
this.$emit('update:page', this.page - 1)
this.$emit('prev')
this.$emit('change',this.page - 1)
},
tv_next() {
this.$emit('input', this.page + 1)
this.$emit('update:page', this.page + 1)
this.$emit('next')
this.$emit('change',this.page + 1)
},
range(from = 1, to) {
const range = []
from = from > 0 ? from : 1
for (let i = from; i <= to; i++) {
range.push(i)
}
return range
},
init() {
this.nowIndex = null;
uni.$tm.sleep(100).then(() => (this.nowIndex = this.page))
},
},
}
</script>
<style lang="scss">
</style>