zoukankan      html  css  js  c++  java
  • Pagination组件源码分析整理笔记

    //pagination.js
    import Pager from './pager.vue';
    import ElSelect from 'element-ui/packages/select';
    import ElOption from 'element-ui/packages/option';
    import ElInput from 'element-ui/packages/input';
    import Locale from 'element-ui/src/mixins/locale';
    import { valueEquals } from 'element-ui/src/utils/util';
    
    export default {
      name: 'ElPagination',
    
      props: {
        pageSize: {  //每页显示条目个数,支持.sync 修饰符
          type: Number,
          default: 10
        },
        small: Boolean, //是否使用小型分页样式
        total: Number, //总条目数
        pageCount: Number, //总页数,total 和 page-count 设置任意一个就可以达到显示页码的功能;如果要支持 page-sizes 的更改,则需要使用 total 属性
        pagerCount: {  //页码按钮的数量,当总页数超过该值时会折叠
          type: Number,
          validator(value) {
            return (value | 0) === value && value > 4 && value < 22 && (value % 2) === 1;
          },
          default: 7
        },
        currentPage: { //当前页数,支持 .sync 修饰符
          type: Number,
          default: 1
        },
        layout: { //组件布局,子组件名用逗号分隔
          default: 'prev, pager, next, jumper, ->, total'
        },
        pageSizes: { //每页显示个数选择器的选项设置
          type: Array,
          default() {
            return [10, 20, 30, 40, 50, 100];
          }
        },
        popperClass: String, //每页显示个数选择器的下拉框类名
        prevText: String, //替代图标显示的上一页文字
        nextText: String, //替代图标显示的下一页文字
        background: Boolean, //是否为分页按钮添加背景色
        disabled: Boolean //是否禁用
      },
    
      data() {
        return {
          internalCurrentPage: 1,  //当前的页码
          internalPageSize: 0,  //总页数
          lastEmittedPage: -1,
          userChangePageSize: false
        };
      },
      //render函数生成el-pagination
      render(h) {
        //最外层的div标签
        let template = <div class={['el-pagination', {
          'is-background': this.background,
          'el-pagination--small': this.small
        }] }></div>;
        const layout = this.layout || '';
        if (!layout) return;
        const TEMPLATE_MAP = {
          prev: <prev></prev>,
          jumper: <jumper></jumper>,
          pager: <pager currentPage={ this.internalCurrentPage } pageCount={ this.internalPageCount } pagerCount={ this.pagerCount } on-change={ this.handleCurrentChange } disabled={ this.disabled }></pager>,
          next: <next></next>,
          sizes: <sizes pageSizes={ this.pageSizes }></sizes>,
          slot: <my-slot></my-slot>,
          total: <total></total>
        };
        const components = layout.split(',').map((item) => item.trim());
        const rightWrapper = <div class="el-pagination__rightwrapper"></div>;
        let haveRightWrapper = false;
    
        template.children = template.children || [];
        rightWrapper.children = rightWrapper.children || [];
        components.forEach(compo => {
          // ->这个符号主要是将其后面的组件放在rightWrapper中,然后右浮动;如果存在->符号,就将haveRightWrapper为true
          if (compo === '->') {
            haveRightWrapper = true;
            return;
          }
          // 当haveRightWrapper为true,即在->后面的放入rightWrapper中
          if (!haveRightWrapper) {
            template.children.push(TEMPLATE_MAP[compo]);
          } else {
            rightWrapper.children.push(TEMPLATE_MAP[compo]);
          }
        });
    
        if (haveRightWrapper) {
          //将rightWrapper加在template.children数组的开头,这样rightWrapper浮动之后就是在最右边
          template.children.unshift(rightWrapper);
        }
        return template;
      },
    
      components: {
        MySlot: {
          render(h) {
            return (
              this.$parent.$slots.default
                ? this.$parent.$slots.default[0]
                : ''
            );
          }
        },
        // 上一页组件
        Prev: {
          //上一页; prevText用户设置的替代上一页图标的文字,存在显示文字,不存在显示上一页图标
          render(h) {
            return (
              <button
                type="button"
                class="btn-prev"
                disabled={ this.$parent.disabled || this.$parent.internalCurrentPage <= 1 }
                on-click={ this.$parent.prev }>
                {
                  this.$parent.prevText
                    ? <span>{ this.$parent.prevText }</span>
                    : <i class="el-icon el-icon-arrow-left"></i>
                }
              </button>
            );
          }
        },
       //下一页组件
        Next: {
          // this.$parent.internalCurrentPage === this.$parent.internalPageCount 当前页数等于总页数时 或者 总页数等于0时,下一页按钮被禁用
          render(h) {
            return (
              <button
                type="button"
                class="btn-next"
                disabled={ this.$parent.disabled || this.$parent.internalCurrentPage === this.$parent.internalPageCount || this.$parent.internalPageCount === 0 }
                on-click={ this.$parent.next }>
                {
                  this.$parent.nextText
                    ? <span>{ this.$parent.nextText }</span>
                    : <i class="el-icon el-icon-arrow-right"></i>
                }
              </button>
            );
          }
        },
        // 每页显示条目个数组件
        Sizes: {
          mixins: [Locale],
          props: {
            pageSizes: Array //每页显示个数选择器的选项设置   [10, 20, 30, 40, 50, 100]
          },
          watch: {
            pageSizes: {
              // 确认是否以当前的初始值执行handler的函数
              immediate: true,
              handler(newVal, oldVal) {
                if (valueEquals(newVal, oldVal)) return;
                if (Array.isArray(newVal)) {
                  // 如果用户设置了每页显示的条目个数,并且pageSize在设置的pageSizes中存在的话,就显示pageSize,否则就显示this.pageSizes[0]
                  // 最后将每页显示的条目个数赋值给this.$parent.internalPageSize
                  this.$parent.internalPageSize = newVal.indexOf(this.$parent.pageSize) > -1
                    ? this.$parent.pageSize
                    : this.pageSizes[0];
                }
              }
            }
          },
          render(h) {
            // this.t('el.pagination.pagesize') 返回'条/页'
            return (
              <span class="el-pagination__sizes">
                <el-select
                  value={ this.$parent.internalPageSize }
                  popperClass={ this.$parent.popperClass || '' }
                  size="mini"
                  on-input={ this.handleChange }
                  disabled={ this.$parent.disabled }>
                  {
                    this.pageSizes.map(item =>
                      <el-option
                        value={ item }
                        label={ item + this.t('el.pagination.pagesize') }>
                      </el-option>
                    )
                  }
                </el-select>
              </span>
            );
          },
          components: {
            ElSelect,
            ElOption
          },
          methods: {
            handleChange(val) {
              if (val !== this.$parent.internalPageSize) {
                this.$parent.internalPageSize = val = parseInt(val, 10);
                this.$parent.userChangePageSize = true;
                //如果父组件中pageSize用了.sync 修饰符,这里将会触发父组件的update,改变pageSize的值
                this.$parent.$emit('update:pageSize', val);
                //触发父组件的size-change事件,将改变的每页显示的条目个数的值传递出去
                this.$parent.$emit('size-change', val);
              }
            }
          }
        },
        //前往多少页组件
        Jumper: {
          mixins: [Locale],
          data() {
            return {
              oldValue: null
            };
          },
          components: { ElInput },
          watch: {
            '$parent.internalPageSize'() {
              this.$nextTick(() => {
                this.$refs.input.$el.querySelector('input').value = this.$parent.internalCurrentPage;
              });
            }
          },
          methods: {
            handleFocus(event) {
              this.oldValue = event.target.value;
            },
            handleBlur({ target }) {
              this.resetValueIfNeed(target.value);
              this.reassignMaxValue(target.value);
            },
            // 按下回车,前往多少页
            handleKeyup({ keyCode, target }) {
              if (keyCode === 13 && this.oldValue && target.value !== this.oldValue) {
                this.handleChange(target.value);
              }
            },
            // 改变当前页
            handleChange(value) {
              // 更新页码列表中当前页的值
              this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(value);
              this.$parent.emitChange();
              this.oldValue = null;
              this.resetValueIfNeed(value);
            },
            resetValueIfNeed(value) {
              const num = parseInt(value, 10);
              if (!isNaN(num)) {
                if (num < 1) {
                  // 调用input中的setCurrentValue方法,将input中的值设置为1
                  this.$refs.input.setCurrentValue(1);
                } else {
                  //  如果input中输入的值,大于最大页码,则置为最大页码值
                  this.reassignMaxValue(value);
                }
              }
            },
            reassignMaxValue(value) {
              const { internalPageCount } = this.$parent;
              if (+value > internalPageCount) {
                  // 调用input中的setCurrentValue方法,将input中的值设置为internalPageCount或者为1
                this.$refs.input.setCurrentValue(internalPageCount || 1);
              }
            }
          },
          // 前往多少页
          render(h) {
            return (
              <span class="el-pagination__jump">
                { this.t('el.pagination.goto') }
                <el-input
                  class="el-pagination__editor is-in-pagination"
                  min={ 1 }
                  max={ this.$parent.internalPageCount }
                  value={ this.$parent.internalCurrentPage }
                  domPropsValue={ this.$parent.internalCurrentPage }
                  type="number"
                  ref="input"
                  disabled={ this.$parent.disabled }
                  nativeOnKeyup={ this.handleKeyup }
                  onChange={ this.handleChange }
                  onFocus={ this.handleFocus }
                  onBlur={ this.handleBlur }/>
                { this.t('el.pagination.pageClassifier') }
              </span>
            );
          }
        },
        //总共的页数,组件
        Total: {
          mixins: [Locale],
          render(h) {
            return (
              typeof this.$parent.total === 'number'
                ? <span class="el-pagination__total">{ this.t('el.pagination.total', { total: this.$parent.total }) }</span>
                : ''
            );
          }
        },
    
        Pager
      },
    
      methods: {
        handleCurrentChange(val) {
          this.internalCurrentPage = this.getValidCurrentPage(val);
          this.userChangePageSize = true;
          //触发父组件current-change事件,并传递相应的值
          this.emitChange();
        },
    
        prev() {
          if (this.disabled) return;
          const newVal = this.internalCurrentPage - 1;
          this.internalCurrentPage = this.getValidCurrentPage(newVal);
          //触发父组件的prev-click事件,并将CurrentPage传递出去
          this.$emit('prev-click', this.internalCurrentPage);
          //触发父组件current-change事件,并传递相应的值
          this.emitChange();
        },
    
        next() {
          if (this.disabled) return;
          const newVal = this.internalCurrentPage + 1;
          this.internalCurrentPage = this.getValidCurrentPage(newVal);
          //触发父组件的next-click事件,并将CurrentPage传递出去
          this.$emit('next-click', this.internalCurrentPage);
          this.emitChange();
        },
        //校验需要前往的页码的值
        getValidCurrentPage(value) {
          value = parseInt(value, 10);
          const havePageCount = typeof this.internalPageCount === 'number';
          let resetValue;
          if (!havePageCount) {
            if (isNaN(value) || value < 1) resetValue = 1;
          } else {
            // 如果当前页码小于1,则取1;如果当前页码大于最大页码,则取最大页码
            if (value < 1) {
              resetValue = 1;
            } else if (value > this.internalPageCount) {
              resetValue = this.internalPageCount;
            }
          }
          //如果当前页码是非数字,或者为0,则将当前页码置为1,并返回
          if (resetValue === undefined && isNaN(value)) {
            resetValue = 1;
          } else if (resetValue === 0) {
            resetValue = 1;
          }
          return resetValue === undefined ? value : resetValue;
        },
    
        emitChange() {
          this.$nextTick(() => {
            //用户改变当前PageSize时,触发父组件的current-change事件
            if (this.internalCurrentPage !== this.lastEmittedPage || this.userChangePageSize) {
              this.$emit('current-change', this.internalCurrentPage);
              //lastEmittedPage记录最后传递的CurrentPage的值
              this.lastEmittedPage = this.internalCurrentPage;
              this.userChangePageSize = false;
            }
          });
        }
      },
    
      computed: {
        internalPageCount() {
          if (typeof this.total === 'number') {
            //总页数 = 总条目数 / 每页的显示条数
            return Math.ceil(this.total / this.internalPageSize);
          } else if (typeof this.pageCount === 'number') {
            //总页数
            return this.pageCount;
          }
          return null;
        }
      },
    
      watch: {
        currentPage: {
          immediate: true,
          handler(val) {
            this.internalCurrentPage = val;
          }
        },
    
        pageSize: {
          immediate: true,
          handler(val) {
            this.internalPageSize = isNaN(val) ? 10 : val;
          }
        },
        // internalCurrentPage改变时去触发父组件中currentPage更新
        // 在v2.4.11这里已经改掉了
        internalCurrentPage: {
          immediate: true,
          handler(newVal, oldVal) {
            newVal = parseInt(newVal, 10);
    
            /* istanbul ignore if */
            if (isNaN(newVal)) {
              newVal = oldVal || 1;
            } else {
              newVal = this.getValidCurrentPage(newVal);
            }
            if (newVal !== undefined) {
              this.internalCurrentPage = newVal;
              if (oldVal !== newVal) {
                this.$emit('update:currentPage', newVal);
              }
            } else {
              this.$emit('update:currentPage', newVal);
            }
            this.lastEmittedPage = -1;
          }
        },
    
        internalPageCount(newVal) {
          /* istanbul ignore if */
          const oldPage = this.internalCurrentPage;
          if (newVal > 0 && oldPage === 0) {
            this.internalCurrentPage = 1;
          } else if (oldPage > newVal) {
            this.internalCurrentPage = newVal === 0 ? 1 : newVal;
            this.userChangePageSize && this.emitChange();
          }
          this.userChangePageSize = false;
        }
      }
    };
    //pager.vue
    <template>
      <!--页码列表-->
      <ul @click="onPagerClick" class="el-pager">
          <!--第一页-->
        <li
          :class="{ active: currentPage === 1, disabled }"
          v-if="pageCount > 0"
          class="number">1</li>
          <!--more图标-->
        <li
          class="el-icon more btn-quickprev"
          :class="[quickprevIconClass, { disabled }]"
          v-if="showPrevMore"
          @mouseenter="onMouseenter('left')"
          @mouseleave="quickprevIconClass = 'el-icon-more'">
        </li>
          <!--页码-->
        <li
          v-for="pager in pagers"
          :key="pager"
          :class="{ active: currentPage === pager, disabled }"
          class="number">{{ pager }}</li>
          <!--more图标-->
        <li
          class="el-icon more btn-quicknext"
          :class="[quicknextIconClass, { disabled }]"
          v-if="showNextMore"
          @mouseenter="onMouseenter('right')"
          @mouseleave="quicknextIconClass = 'el-icon-more'">
        </li>
          <!--总页码-->
        <li
          :class="{ active: currentPage === pageCount, disabled }"
          class="number"
          v-if="pageCount > 1">{{ pageCount }}</li>
      </ul>
    </template>
    
    <script type="text/babel">
      export default {
        name: 'ElPager',
    
        props: {
          currentPage: Number, //当前页码
          pageCount: Number, //总页数
          pagerCount: Number, //页码按钮的数量,当总页数超过该值时会折叠
          disabled: Boolean
        },
    
        watch: {
          showPrevMore(val) {
            if (!val) this.quickprevIconClass = 'el-icon-more';
          },
    
          showNextMore(val) {
            if (!val) this.quicknextIconClass = 'el-icon-more';
          }
        },
    
        methods: {
          onPagerClick(event) {
            const target = event.target;
            if (target.tagName === 'UL' || this.disabled) {
              return;
            }
    
            let newPage = Number(event.target.textContent);
            const pageCount = this.pageCount;
            const currentPage = this.currentPage;
            const pagerCountOffset = this.pagerCount - 2;
    
            //点击more图标页码显示计算逻辑
            if (target.className.indexOf('more') !== -1) {
              if (target.className.indexOf('quickprev') !== -1) {
                newPage = currentPage - pagerCountOffset;
              } else if (target.className.indexOf('quicknext') !== -1) {
                newPage = currentPage + pagerCountOffset;
              }
            }
    
            /* istanbul ignore if */
            if (!isNaN(newPage)) {
              if (newPage < 1) {
                newPage = 1;
              }
              if (newPage > pageCount) {
                newPage = pageCount;
              }
            }
    
            if (newPage !== currentPage) {
              this.$emit('change', newPage);
            }
          },
          // 鼠标移入more图标显示向左或者向右的图标
          onMouseenter(direction) {
            if (this.disabled) return;
            if (direction === 'left') {
              this.quickprevIconClass = 'el-icon-d-arrow-left';
            } else {
              this.quicknextIconClass = 'el-icon-d-arrow-right';
            }
          }
        },
    
        computed: {
          pagers() {
            // pagerCount页码按钮的数量(大于等于 5 且小于等于 21 的奇数)
            const pagerCount = this.pagerCount;
            // 按钮的一半数量
            const halfPagerCount = (pagerCount - 1) / 2;
            // 当前页码数
            const currentPage = Number(this.currentPage);
            // 总页数
            const pageCount = Number(this.pageCount);
            // 左边的more图标
            let showPrevMore = false;
            // 右边的more图标
            let showNextMore = false;
    
            // 如果总页码数大于要显示的页码按钮数量
            if (pageCount > pagerCount) {
              //  如果当前页码大于(要显示的页码按钮数量-一半的页码按钮数量)
              if (currentPage > pagerCount - halfPagerCount) {
                //  显示左边的more图标
                showPrevMore = true;
              }
              //  如果当前页码小于(要显示的页码按钮数量-一半的页码按钮数量)
              if (currentPage < pageCount - halfPagerCount) {
                //  显示右边的more图标
                showNextMore = true;
              }
            }
            const array = [];
            //如果左边的more图标存在,右边的more图标不存在
            if (showPrevMore && !showNextMore) {
              const startPage = pageCount - (pagerCount - 2);
              for (let i = startPage; i < pageCount; i++) {
                array.push(i);
              }
            } else if (!showPrevMore && showNextMore) {   //如果左边的more图标不存在,右边的more图标存在
              for (let i = 2; i < pagerCount; i++) {
                array.push(i);
              }
            } else if (showPrevMore && showNextMore) {  //如果左右more图标都存在
              // Math.floor() 返回小于或等于一个给定数字的最大整数。
              const offset = Math.floor(pagerCount / 2) - 1;
              for (let i = currentPage - offset ; i <= currentPage + offset; i++) {
                array.push(i);
              }
            } else {
              for (let i = 2; i < pageCount; i++) {
                array.push(i);
              }
            }
    
            this.showPrevMore = showPrevMore;
            this.showNextMore = showNextMore;
    
            return array;
          }
        },
    
        data() {
          return {
            current: null,
            showPrevMore: false,
            showNextMore: false,
            quicknextIconClass: 'el-icon-more',
            quickprevIconClass: 'el-icon-more'
          };
        }
      };
    </script>
    

      

    import Pager from './pager.vue';
    import ElSelect from 'element-ui/packages/select';
    import ElOption from 'element-ui/packages/option';
    import ElInput from 'element-ui/packages/input';
    import Locale from 'element-ui/src/mixins/locale';
    import { valueEquals } from 'element-ui/src/utils/util';
    
    export default {
      name: 'ElPagination',
    
      props: {
        pageSize: {  //每页显示条目个数,支持.sync 修饰符
          type: Number,
          default: 10
        },
        small: Boolean, //是否使用小型分页样式
        total: Number, //总条目数
        pageCount: Number, //总页数,total 和 page-count 设置任意一个就可以达到显示页码的功能;如果要支持 page-sizes 的更改,则需要使用 total 属性
        pagerCount: {  //页码按钮的数量,当总页数超过该值时会折叠
          type: Number,
          validator(value) {
            return (value | 0) === value && value > 4 && value < 22 && (value % 2) === 1;
          },
          default: 7
        },
        currentPage: { //当前页数,支持 .sync 修饰符
          type: Number,
          default: 1
        },
        layout: { //组件布局,子组件名用逗号分隔
          default: 'prev, pager, next, jumper, ->, total'
        },
        pageSizes: { //每页显示个数选择器的选项设置
          type: Array,
          default() {
            return [10, 20, 30, 40, 50, 100];
          }
        },
        popperClass: String, //每页显示个数选择器的下拉框类名
        prevText: String, //替代图标显示的上一页文字
        nextText: String, //替代图标显示的下一页文字
        background: Boolean, //是否为分页按钮添加背景色
        disabled: Boolean //是否禁用
      },
    
      data() {
        return {
          internalCurrentPage: 1,  //当前的页码
          internalPageSize: 0,  //总页数
          lastEmittedPage: -1,
          userChangePageSize: false
        };
      },
      //render函数生成el-pagination
      render(h) {
        //最外层的div标签
        let template = <div class={['el-pagination', {
          'is-background': this.background,
          'el-pagination--small': this.small
        }] }></div>;
        const layout = this.layout || '';
        if (!layout) return;
        const TEMPLATE_MAP = {
          prev: <prev></prev>,
          jumper: <jumper></jumper>,
          pager: <pager currentPage={ this.internalCurrentPage } pageCount={ this.internalPageCount } pagerCount={ this.pagerCount } on-change={ this.handleCurrentChange } disabled={ this.disabled }></pager>,
          next: <next></next>,
          sizes: <sizes pageSizes={ this.pageSizes }></sizes>,
          slot: <my-slot></my-slot>,
          total: <total></total>
        };
        const components = layout.split(',').map((item) => item.trim());
        const rightWrapper = <div class="el-pagination__rightwrapper"></div>;
        let haveRightWrapper = false;
    
        template.children = template.children || [];
        rightWrapper.children = rightWrapper.children || [];
        components.forEach(compo => {
          // ->这个符号主要是将其后面的组件放在rightWrapper中,然后右浮动;如果存在->符号,就将haveRightWrapper为true
          if (compo === '->') {
            haveRightWrapper = true;
            return;
          }
          // 当haveRightWrapper为true,即在->后面的放入rightWrapper中
          if (!haveRightWrapper) {
            template.children.push(TEMPLATE_MAP[compo]);
          } else {
            rightWrapper.children.push(TEMPLATE_MAP[compo]);
          }
        });
    
        if (haveRightWrapper) {
          //将rightWrapper加在template.children数组的开头,这样rightWrapper浮动之后就是在最右边
          template.children.unshift(rightWrapper);
        }
        return template;
      },
    
      components: {
        MySlot: {
          render(h) {
            return (
              this.$parent.$slots.default
                ? this.$parent.$slots.default[0]
                : ''
            );
          }
        },
        // 上一页组件
        Prev: {
          //上一页; prevText用户设置的替代上一页图标的文字,存在显示文字,不存在显示上一页图标
          render(h) {
            return (
              <button
                type="button"
                class="btn-prev"
                disabled={ this.$parent.disabled || this.$parent.internalCurrentPage <= 1 }
                on-click={ this.$parent.prev }>
                {
                  this.$parent.prevText
                    ? <span>{ this.$parent.prevText }</span>
                    : <i class="el-icon el-icon-arrow-left"></i>
                }
              </button>
            );
          }
        },
       //下一页组件
        Next: {
          // this.$parent.internalCurrentPage === this.$parent.internalPageCount 当前页数等于总页数时 或者 总页数等于0时,下一页按钮被禁用
          render(h) {
            return (
              <button
                type="button"
                class="btn-next"
                disabled={ this.$parent.disabled || this.$parent.internalCurrentPage === this.$parent.internalPageCount || this.$parent.internalPageCount === 0 }
                on-click={ this.$parent.next }>
                {
                  this.$parent.nextText
                    ? <span>{ this.$parent.nextText }</span>
                    : <i class="el-icon el-icon-arrow-right"></i>
                }
              </button>
            );
          }
        },
        // 每页显示条目个数组件
        Sizes: {
          mixins: [Locale],
          props: {
            pageSizes: Array //每页显示个数选择器的选项设置   [10, 20, 30, 40, 50, 100]
          },
          watch: {
            pageSizes: {
              // 确认是否以当前的初始值执行handler的函数
              immediate: true,
              handler(newVal, oldVal) {
                if (valueEquals(newVal, oldVal)) return;
                if (Array.isArray(newVal)) {
                  // 如果用户设置了每页显示的条目个数,并且pageSize在设置的pageSizes中存在的话,就显示pageSize,否则就显示this.pageSizes[0]
                  // 最后将每页显示的条目个数赋值给this.$parent.internalPageSize
                  this.$parent.internalPageSize = newVal.indexOf(this.$parent.pageSize) > -1
                    ? this.$parent.pageSize
                    : this.pageSizes[0];
                }
              }
            }
          },
          render(h) {
            // this.t('el.pagination.pagesize') 返回'条/页'
            return (
              <span class="el-pagination__sizes">
                <el-select
                  value={ this.$parent.internalPageSize }
                  popperClass={ this.$parent.popperClass || '' }
                  size="mini"
                  on-input={ this.handleChange }
                  disabled={ this.$parent.disabled }>
                  {
                    this.pageSizes.map(item =>
                      <el-option
                        value={ item }
                        label={ item + this.t('el.pagination.pagesize') }>
                      </el-option>
                    )
                  }
                </el-select>
              </span>
            );
          },
          components: {
            ElSelect,
            ElOption
          },
          methods: {
            handleChange(val) {
              if (val !== this.$parent.internalPageSize) {
                this.$parent.internalPageSize = val = parseInt(val, 10);
                this.$parent.userChangePageSize = true;
                //如果父组件中pageSize用了.sync 修饰符,这里将会触发父组件的update,改变pageSize的值
                this.$parent.$emit('update:pageSize', val);
                //触发父组件的size-change事件,将改变的每页显示的条目个数的值传递出去
                this.$parent.$emit('size-change', val);
              }
            }
          }
        },
        //前往多少页组件
        Jumper: {
          mixins: [Locale],
          data() {
            return {
              oldValue: null
            };
          },
          components: { ElInput },
          watch: {
            '$parent.internalPageSize'() {
              this.$nextTick(() => {
                this.$refs.input.$el.querySelector('input').value = this.$parent.internalCurrentPage;
              });
            }
          },
          methods: {
            handleFocus(event) {
              this.oldValue = event.target.value;
            },
            handleBlur({ target }) {
              this.resetValueIfNeed(target.value);
              this.reassignMaxValue(target.value);
            },
            // 按下回车,前往多少页
            handleKeyup({ keyCode, target }) {
              if (keyCode === 13 && this.oldValue && target.value !== this.oldValue) {
                this.handleChange(target.value);
              }
            },
            // 改变当前页
            handleChange(value) {
              // 更新页码列表中当前页的值
              this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(value);
              this.$parent.emitChange();
              this.oldValue = null;
              this.resetValueIfNeed(value);
            },
            resetValueIfNeed(value) {
              const num = parseInt(value, 10);
              if (!isNaN(num)) {
                if (num < 1) {
                  // 调用input中的setCurrentValue方法,将input中的值设置为1
                  this.$refs.input.setCurrentValue(1);
                } else {
                  //  如果input中输入的值,大于最大页码,则置为最大页码值
                  this.reassignMaxValue(value);
                }
              }
            },
            reassignMaxValue(value) {
              const { internalPageCount } = this.$parent;
              if (+value > internalPageCount) {
                  // 调用input中的setCurrentValue方法,将input中的值设置为internalPageCount或者为1
                this.$refs.input.setCurrentValue(internalPageCount || 1);
              }
            }
          },
          // 前往多少页
          render(h) {
            return (
              <span class="el-pagination__jump">
                { this.t('el.pagination.goto') }
                <el-input
                  class="el-pagination__editor is-in-pagination"
                  min={ 1 }
                  max={ this.$parent.internalPageCount }
                  value={ this.$parent.internalCurrentPage }
                  domPropsValue={ this.$parent.internalCurrentPage }
                  type="number"
                  ref="input"
                  disabled={ this.$parent.disabled }
                  nativeOnKeyup={ this.handleKeyup }
                  onChange={ this.handleChange }
                  onFocus={ this.handleFocus }
                  onBlur={ this.handleBlur }/>
                { this.t('el.pagination.pageClassifier') }
              </span>
            );
          }
        },
        //总共的页数,组件
        Total: {
          mixins: [Locale],
          render(h) {
            return (
              typeof this.$parent.total === 'number'
                ? <span class="el-pagination__total">{ this.t('el.pagination.total', { total: this.$parent.total }) }</span>
                : ''
            );
          }
        },
    
        Pager
      },
    
      methods: {
        handleCurrentChange(val) {
          this.internalCurrentPage = this.getValidCurrentPage(val);
          this.userChangePageSize = true;
          //触发父组件current-change事件,并传递相应的值
          this.emitChange();
        },
    
        prev() {
          if (this.disabled) return;
          const newVal = this.internalCurrentPage - 1;
          this.internalCurrentPage = this.getValidCurrentPage(newVal);
          //触发父组件的prev-click事件,并将CurrentPage传递出去
          this.$emit('prev-click', this.internalCurrentPage);
          //触发父组件current-change事件,并传递相应的值
          this.emitChange();
        },
    
        next() {
          if (this.disabled) return;
          const newVal = this.internalCurrentPage + 1;
          this.internalCurrentPage = this.getValidCurrentPage(newVal);
          //触发父组件的next-click事件,并将CurrentPage传递出去
          this.$emit('next-click', this.internalCurrentPage);
          this.emitChange();
        },
        //校验需要前往的页码的值
        getValidCurrentPage(value) {
          value = parseInt(value, 10);
          const havePageCount = typeof this.internalPageCount === 'number';
          let resetValue;
          if (!havePageCount) {
            if (isNaN(value) || value < 1) resetValue = 1;
          } else {
            // 如果当前页码小于1,则取1;如果当前页码大于最大页码,则取最大页码
            if (value < 1) {
              resetValue = 1;
            } else if (value > this.internalPageCount) {
              resetValue = this.internalPageCount;
            }
          }
          //如果当前页码是非数字,或者为0,则将当前页码置为1,并返回
          if (resetValue === undefined && isNaN(value)) {
            resetValue = 1;
          } else if (resetValue === 0) {
            resetValue = 1;
          }
          return resetValue === undefined ? value : resetValue;
        },
    
        emitChange() {
          this.$nextTick(() => {
            //用户改变当前PageSize时,触发父组件的current-change事件
            if (this.internalCurrentPage !== this.lastEmittedPage || this.userChangePageSize) {
              this.$emit('current-change', this.internalCurrentPage);
              //lastEmittedPage记录最后传递的CurrentPage的值
              this.lastEmittedPage = this.internalCurrentPage;
              this.userChangePageSize = false;
            }
          });
        }
      },
    
      computed: {
        internalPageCount() {
          if (typeof this.total === 'number') {
            //总页数 = 总条目数 / 每页的显示条数
            return Math.ceil(this.total / this.internalPageSize);
          } else if (typeof this.pageCount === 'number') {
            //总页数
            return this.pageCount;
          }
          return null;
        }
      },
    
      watch: {
        currentPage: {
          immediate: true,
          handler(val) {
            this.internalCurrentPage = val;
          }
        },
    
        pageSize: {
          immediate: true,
          handler(val) {
            this.internalPageSize = isNaN(val) ? 10 : val;
          }
        },
        // internalCurrentPage改变时去触发父组件中currentPage更新
        // 在v2.4.11这里已经改掉了
        internalCurrentPage: {
          immediate: true,
          handler(newVal, oldVal) {
            newVal = parseInt(newVal, 10);
    
            /* istanbul ignore if */
            if (isNaN(newVal)) {
              newVal = oldVal || 1;
            } else {
              newVal = this.getValidCurrentPage(newVal);
            }
            if (newVal !== undefined) {
              this.internalCurrentPage = newVal;
              if (oldVal !== newVal) {
                this.$emit('update:currentPage', newVal);
              }
            } else {
              this.$emit('update:currentPage', newVal);
            }
            this.lastEmittedPage = -1;
          }
        },
    
        internalPageCount(newVal) {
          /* istanbul ignore if */
          const oldPage = this.internalCurrentPage;
          if (newVal > 0 && oldPage === 0) {
            this.internalCurrentPage = 1;
          } else if (oldPage > newVal) {
            this.internalCurrentPage = newVal === 0 ? 1 : newVal;
            this.userChangePageSize && this.emitChange();
          }
          this.userChangePageSize = false;
        }
      }
    };
  • 相关阅读:
    买房的贷款时间是否是越长越好?https://www.zhihu.com/question/20842791
    asp.net cookie and session
    leelazero and google colab
    download file by python in google colab
    physical processor, core, logical processor
    通过powershell操作eventlog
    openxml in sql server
    get the page name from url
    How to Execute Page_Load() in Page's Base Class?
    Difference between HttpContext.Request and Request
  • 原文地址:https://www.cnblogs.com/chenzxl/p/11073095.html
Copyright © 2011-2022 走看看