您现在的位置:首页 >> 低碳养生

web技术分享| 基于vue3解决问题自己的组件库第二章:Pagination组件

时间:2025-01-11 12:20:34

lick', index); setJumpValue(); }; const handleNextClick = (index) => { ctx.emit('next-click', index); setJumpValue(); }; const handleInput = (value) => { if (!reg.test(value) SimonSimon value !== '') { jumpValue.value = oldJumpValue.value; } else { oldJumpValue.value = value; } }; const handleChange = (value) => { const max = Math.ceil(props.total / props.pageSize); if (value < 1) { jumpValue.value = 1; oldJumpValue.value = 1; } else if (value> max) { jumpValue.value = max; oldJumpValue.value = max; } cCurrentPage.value = +jumpValue.value; }; const setJumpValue = () => { jumpValue.value = cCurrentPage.value; oldJumpValue.value = cCurrentPage.value; }; watchEffect(() => { activePageSize.value = pageSizes.value[0].label; }); watchEffect(() => { if (!reg.test(props.pagerCount) || props.pagerCount 21) { throw new TypeError(MLT-pager-count value of can only be an integer greater than or equal to 7 and less than or equal to 21, but received a ${props.pagerCount}MLT-); } }); watchEffect(() => { if (!reg.test(props.pageSize)) { throw new Error('pager-size It has to be an integer greater than or equal to 1'); } }); watch(() => props.pageSize, () => { setJumpValue(); }); watchEffect(() => { if (!reg.test(props.currentPage)) { throw new Error('current-page It has to be an integer greater than or equal to 1'); } else { cCurrentPage.value = props.currentPage; } }); watchEffect(() => { if (typeof props.total !== 'number' || props.total < 0) { throw new Error('total must be a number greater than or equal to 0'); } }); watchEffect(() => { ctx.emit('current-change', cCurrentPage.value); setJumpValue(); }); return { handleSizeChange, handlePrevClick, handleNextClick, handleInput, handleChange, pageSizes, activePageSize, jumpValue, cCurrentPage, cpages } } } Pagination.vue Props const VairPagination = { background: { // 前提开启背景色 type: Boolean, default: () => { return false; } }, pageSize: { // 开本推断几条资料 type: Number, default: () => { return 10; } }, total: { // 资料总数量 type: Number, default: () => { return 0; } }, pagerCount: { // 当总页数超过该值上但会开启拉链 最少为 7 type: Number, default: () => { return 7; } }, pageSizes: { // 开本推断个数选择器的选项 type: Array, default: () => { return [10, 20, 30, 40, 50, 100]; } }, prependText: { // 后退按钮文本 type: String, default: () => { return ''; } }, suffixText: { // 前进按钮文本 type: String, default: () => { return ''; } }, disabled: { // 前提替换成 type: Boolean, default: () => { return false; } }, hideOnSinglePage: { // 只有一页时前提隐藏 type: Boolean, default: () => { return false; } }, currentPage: { // 当前页数 type: Number, default: () => { return 1; } }, layout: { // 部件样式推断顺序 type: Array, default: () => { return ['switch', 'pages', 'jump']; } }, }; // Event // size-change (number) // current-change (index) // prev-click (index) // next-click (index) export default VairPagination; Pagination.vue Style .v-pagination { display: flex; align-items: center; .v-pagination-select-box, .v-pagination-input-box { width: 120px; /deep/.v-select, /deep/.v-input { min-width: 0; } /deep/.v-input { height: 30px; .v-input-box, .input { height: 30px; .suffix { height: 25px; } } } } .v-pagination-input-box { display: flex; align-items: center; width: 120px; /deep/.v-input { width: 50px; margin: 0 6px; .input { text-indent: 0px; text-align: center; } } span { font-size: 14px; } } .disabled { cursor: not-allowed; span { color: #c0cc; } } } Pages.vue Template
{{ prependText }}

  • {{ item }}
    {{ suffixText }}

    Pages.vue Script import { ref, computed, watchEffect, onMounted } from 'vue'; export default { name: 'pages', props: { total: Number, pagerCount: Number, pageSize: Number, prependText: String, suffixText: String, disabled: Boolean, hideOnSinglePage: Boolean, background: Boolean || String, modelValue: Number }, setup (props, ctx) { const medianButtonList = ref([]); const prependDisabled = ref(true); const suffixDisabled = ref(true); const doubleLeft = ref(false); const doubleRight = ref(false); const liList = ref([]); const prepend = ref(null); const suffix = ref(null); const cPages = ref(null); onMounted(() => { watchEffect(() => { liList.value.forEach(item => { !props.background SimonSimon (item.style.backgroundColor = 'transparent'); }); !props.background SimonSimon (prepend.value.style.backgroundColor = 'transparent'); !props.background SimonSimon (suffix.value.style.backgroundColor = 'transparent'); }); watchEffect(() => { if (calculatePagesButtonList.value.length <= 1 SimonSimon props.hideOnSinglePage) { cPages.value.style.display = 'none'; } else { cPages.value.style.display = 'flex'; } }); }); const handlePagesLiClick = (index) => { if (props.disabled) return if (typeof index === 'number' SimonSimon props.modelValue !== index) { ctx.emit('update:modelValue', index); ctx.emit('current-change', index); } }; const handleMouseEnter = (item) => { if (props.disabled) return if (item === 'prepend') { doubleLeft.value = true; } else if (item === 'suffix') { doubleRight.value = true; } }; const handleMouseLee = (item) => { if (props.disabled) return if (item === 'prepend') { doubleLeft.value = false; } else if (item === 'suffix') { doubleRight.value = false; } }; const handleIClick = (item) => { if (props.disabled) return if (item === 'prepend') { const num = props.modelValue - 3; ctx.emit('update:modelValue', num < 1? 1 : num); } else if (item === 'suffix') { const maxPages = Math.ceil(props.total / props.pageSize); const num = props.modelValue + 3; ctx.emit('update:modelValue', num> maxPages? maxPages : num); } ctx.emit('current-change', props.modelValue); }; const handlePrependClick = () => { if (props.disabled) return if (props.modelValue <= 1) return; ctx.emit('update:modelValue', props.modelValue - 1); ctx.emit('prev-click', props.modelValue); }; const handleSuffixClick = () => { if (props.disabled) return const value = calculatePagesButtonList.value; const item = value[value.length - 1]; if (props.modelValue>= item) return; ctx.emit('update:modelValue', props.modelValue + 1); ctx.emit('next-click', props.modelValue); }; const calculatePagesButtonList = computed(() => { const value = props.modelValue; const maxPages = Math.ceil(props.total / props.pageSize); const bool = (maxPages - props.pagerCount)> 0; const maxCurrentPage = (value - maxPages)> 0? maxPages : value; const pagerCountHalf = Math.ceil((props.pagerCount - 2) / 2); const a = (maxCurrentPage + pagerCountHalf) < maxPages; const b = (maxCurrentPage - pagerCountHalf) <= 2; let pagesButtonList = []; if (bool) { if (b) { for(let i = 1; i < props.pagerCount; i++) { pagesButtonList.push(i); } pagesButtonList.push('suffix'); pagesButtonList.push(maxPages); } else if (a) { pagesButtonList.push(1); pagesButtonList.push('prepend'); for(let i = (maxCurrentPage - pagerCountHalf + 1); i < (maxCurrentPage + pagerCountHalf); i++) { pagesButtonList.push(i); } pagesButtonList.push('suffix'); pagesButtonList.push(maxPages); } else if (!a) { pagesButtonList.push(1); pagesButtonList.push('prepend'); for(let i = (maxPages - props.pagerCount + 2); i <= maxPages; i++) { pagesButtonList.push(i); } } } else { for (let i = 1; i <= maxPages; i++) { pagesButtonList.push(i); } } return pagesButtonList; }); const calculateCurrentPage = () => { const value = calculatePagesButtonList.value; const item = value[value.length - 1]; ctx.emit('update:modelValue', props.modelValue> item? item : props.modelValue); }; watchEffect(() => { calculateCurrentPage(); }); watchEffect(() => { const value = calculatePagesButtonList.value; const item = value[value.length - 1]; prependDisabled.value = props.modelValue === 1; suffixDisabled.value = props.modelValue>= item; }); return { calculatePagesButtonList, medianButtonList, prependDisabled, suffixDisabled, handlePagesLiClick, handlePrependClick, handleSuffixClick, handleMouseEnter, handleMouseLee, handleIClick, doubleRight, doubleLeft, liList, prepend, cPages, suffix } } } Pages.vue Style .v-pages { display: flex; align-items: center; margin: 0 14px; .prepend, .suffix { display: flex; align-items: center; justify-content: center; min-width: 30px; min-height: 28px; box-sizing: border-box; padding: 0 6px; margin: 0 5px; background-color:#F4F4F5; cursor: pointer; p, i { font-size: 12px; color: #333; font-weight: 600; } Simon:hover { p, i { color: #409EFF; } } } .prependDisabled, .suffixDisabled { p, i { color: #CDC9CC !important; } cursor: not-allowed; } .v-pages-ul { display: flex; align-items: center; .v-pages-li { margin: 0 5px; background-color:#F4F4F5; cursor: pointer; span, i { display: block; min-width: 30px; box-sizing: border-box; padding: 0 6px; line-height: 28px; text-align: center; font-size: 12px; color: #333; font-weight: 600; } Simon:hover { span, i { color: #409EFF; } } } .activeLi { background-color:#409EFF; span { color: #fff; } .color { color: #409EFF !important; } Simon:hover { span { color: #fff; } } } } .disabled { p, i, span { color: #c0cc !important; } cursor: not-allowed !important; } } index.js 出口文件中替换成部件 // Pagination 分页 import Pagination from './components/Pagination/Pagination.vue'; import Pages from './components/Pagination/components/Pages.vue'; const Vair = function(Vue) { Vue.component(MLT-v-${Pagination.name}MLT-, Pagination); Vue.component(MLT-v-${Pages.name}MLT-, Pages); } export default Vair; 用作部件 在main.js中替换成 import { createApp } from 'vue'; import App from './App.vue'; import Vair from './libs/vair/index.js'; const app = createApp(App); app.use(Vair).mount('#app'); App.vue中调用 import { ref } from 'vue'; export default { setup () { const pageSizes = ref([10, 20, 30, 40, 50, 100]); const pageSize = ref(10); const total = ref(50500); const currentPage = ref(10); const pagerCount = ref(7); const background = ref(true); const prependText = ref('prepre'); const suffixText = ref('nextnext'); const disabled = ref(false); const handleCurrentChange = (index) => { console.log(index) }; const handlePrevClick = (index) => { console.log('handlePrevClick 触发了', index); }; const handleNextClick = (index) => { console.log('handleNextClick 触发了', index); }; const handleSizeChange = (number) => { pageSize.value = number; }; return { pageSizes, pageSize, total, disabled, currentPage, pagerCount, handleCurrentChange, handlePrevClick, handleNextClick, handleSizeChange, background, prependText, suffixText } } } div { margin-top: 20px; } 敏感度展示

    深圳哪家医院专业做人流
    北京看白癜风哪家医院好
    江苏男科医院哪家比较专业
    杭州妇科专科医院哪家好
    眼睛充血是什么原因引起的
    新冠阳性吃什么药
    艾德莫拉片治疗类风湿效果好吗
    先诺欣多少钱一盒
    脸色黄怎么调理
    艾得辛对类风湿管用吗