Răsfoiți Sursa

Merge pull request #35 from eleme/feat/next-pagination

update pagination
FuryBean 9 ani în urmă
părinte
comite
47293a131d

+ 1 - 0
.babelrc

@@ -1,4 +1,5 @@
 {
   "presets": ["es2015"],
+  "plugins": ["transform-vue-jsx"],
   "comments": false
 }

+ 2 - 1
.eslintrc

@@ -3,7 +3,8 @@
   "extends": 'elemefe',
   "parserOptions": {
     "ecmaFeatures": {
-      "experimentalObjectRestSpread": true
+      "experimentalObjectRestSpread": true,
+      "jsx": true
     }
   }
 }

+ 1 - 1
examples/index.template.html

@@ -2,7 +2,7 @@
 <html lang="en">
   <head>
     <meta charset="utf-8">
-    <title>test-vue2</title>
+    <title>ELEMENT</title>
   </head>
   <body>
     <div id="app"></div>

+ 4 - 1
package.json

@@ -30,6 +30,9 @@
     "object-assign": "^4.1.0"
   },
   "devDependencies": {
+    "babel-helper-vue-jsx-merge-props": "^1.0.1",
+    "babel-plugin-syntax-jsx": "^6.8.0",
+    "babel-plugin-transform-vue-jsx": "^1.1.1",
     "file-save": "^0.2.0",
     "gh-pages": "^0.11.0",
     "highlight.js": "^9.3.0",
@@ -42,7 +45,7 @@
     "q": "^1.4.1",
     "uppercamelcase": "^1.1.0",
     "vue": "^2.0.0-beta.5",
-    "vue-loader": "^9.2.0",
+    "vue-loader": "^9.2.3",
     "vue-markdown-loader": "^0.4.0",
     "vue-popup": "^0.1.8",
     "vue-router": "^2.0.0-beta.2"

+ 8 - 8
packages/pagination/src/pager.vue

@@ -1,11 +1,12 @@
 <template>
-  <ul @click="onPagerClick($event)" class="el-pager">
+  <ul @click="onPagerClick" class="el-pager">
     <li
       :class="{ active: currentPage === 1 }"
       v-if="pageCount > 0"
       class="number">1</li>
     <li
-      class="el-icon ellipsis btn-quickprev {{quickprevIconClass}}"
+      class="el-icon ellipsis btn-quickprev"
+      :class="[quickprevIconClass]"
       v-if="showPrevMore"
       @mouseenter="quickprevIconClass = 'el-icon-d-arrow-left'"
       @mouseleave="quickprevIconClass = 'el-icon-ellipsis'"
@@ -13,10 +14,11 @@
     </li>
     <li
       v-for="pager in pagers"
-      :class="{ active: $parent.currentPage === pager }"
+      :class="{ active: currentPage === pager }"
       class="number">{{ pager }}</li>
     <li
-      class="el-icon ellipsis btn-quicknext {{quicknextIconClass}}"
+      class="el-icon ellipsis btn-quicknext"
+      :class="[quicknextIconClass]"
       v-if="showNextMore"
       @mouseenter="quicknextIconClass = 'el-icon-d-arrow-right'"
       @mouseleave="quicknextIconClass = 'el-icon-ellipsis'"
@@ -29,7 +31,7 @@
   </ul>
 </template>
 
-<script type="text/ecmascript-6">
+<script type="text/babel">
   export default {
     name: 'ElPager',
 
@@ -68,10 +70,8 @@
           }
         }
 
-        this.currentPage = newPage;
-
         if (newPage !== currentPage) {
-          this.$emit('current-change', newPage);
+          this.$emit('currentChange', newPage);
         }
       }
     },

+ 328 - 0
packages/pagination/src/pagination.js

@@ -0,0 +1,328 @@
+import Vue from 'vue';
+import Pager from './pager.vue';
+import ElSelect from 'packages/select/index.js';
+import ElOption from 'packages/option/index.js';
+
+export default {
+  name: 'ElPagination',
+
+  props: {
+    pageSize: {
+      type: Number,
+      default: 10
+    },
+
+    small: Boolean,
+
+    total: {
+      type: Number,
+      default: 0
+    },
+
+    currentPage: {
+      type: Number,
+      default: 1
+    },
+
+    layout: {
+      default: 'prev, pager, next, jumper, slot, ->, total'
+    },
+
+    pageSizes: {
+      type: Array,
+      default() {
+        return [10, 20, 30, 40, 50, 100];
+      }
+    }
+  },
+
+  data() {
+    return {
+      internalCurrentPage: 1,
+      internalPageSize: 0
+    };
+  },
+
+  render(h) {
+    let template = <div class='el-pagination'></div>;
+    const layout = this.$options.layout || this.layout || '';
+    const TEMPLATE_MAP = {
+      prev: <prev></prev>,
+      jumper: <jumper></jumper>,
+      pager: <pager prop-currentPage={ this.internalCurrentPage } prop-pageCount={ this.pageCount } on-currentChange={ this.handleCurrentChange }></pager>,
+      next: <next></next>,
+      sizes: <sizes></sizes>,
+      slot: <slot></slot>,
+      total: <total></total>
+    };
+    const components = layout.split(',').map((item) => item.trim());
+    const rightWrapper = <div class="el-pagination__rightwrapper"></div>;
+    let haveRightWrapper = false;
+
+    if (this.small) {
+      template.data.class += ' el-pagination--small';
+    }
+
+    components.forEach(compo => {
+      if (compo === '->') {
+        haveRightWrapper = true;
+        return;
+      }
+
+      if (!haveRightWrapper) {
+        template.children.push(TEMPLATE_MAP[compo]);
+      } else {
+        rightWrapper.children.push(TEMPLATE_MAP[compo]);
+      }
+    });
+
+    if (haveRightWrapper) {
+      template.children.push(rightWrapper);
+    }
+
+    return template;
+  },
+
+  components: {
+    Prev: {
+      render(h) {
+        return (
+          <button
+            class={['btn-prev', { disabled: this.$parent.internalCurrentPage <= 1 }]}
+            on-click={ this.$parent.prev }>
+            <i class="el-icon el-icon-arrow-left"></i>
+          </button>
+        );
+      }
+    },
+
+    Next: {
+      render(h) {
+        return (
+          <button
+            class={
+              [
+                'btn-next',
+                { disabled: this.$parent.internalCurrentPage === this.$parent.pageCount }
+              ]
+            }
+            on-click={ this.$parent.next }>
+            <i class="el-icon el-icon-arrow-right"></i>
+          </button>
+        );
+      }
+    },
+
+    Sizes: {
+      render(h) {
+        return (
+          <span class="el-pagination__sizes">
+            <el-select
+              prop-size="small"
+              prop-value={ this.$parent.internalPageSize }
+              on-change={ this.handleChange }
+              prop-width={ 110 }>
+              {
+                this.$parent.pageSizes.map(item =>
+                    <el-option
+                      prop-value={ item }
+                      prop-label={ item + ' 条/页' }>
+                    </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.$emit('size-change', val);
+          }
+        }
+      }
+    },
+
+    Jumper: {
+      data() {
+        return {
+          oldValue: null
+        };
+      },
+
+      methods: {
+        handleFocus(event) {
+          this.oldValue = event.target.value;
+        },
+
+        handleChange(event) {
+          const target = event.target;
+          this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(target.value);
+
+          if (target.value !== this.oldValue && Number(target.value) === this.$parent.internalCurrentPage) {
+            this.$parent.$emit('current-change', this.$parent.internalCurrentPage);
+          }
+
+          this.oldValue = null;
+        }
+      },
+
+      render(h) {
+        return (
+          <span class="el-pagination__jump">
+            前往
+            <input
+              class="el-pagination__editor"
+              type="number"
+              min={ 1 }
+              max={ this.pageCount }
+              value={ this.$parent.internalCurrentPage }
+              on-change={ this.handleChange }
+              on-focus={ this.handleFocus }
+              style={{ width: '30px' }}
+              number
+              lazy/>
+            页
+          </span>
+        );
+      }
+    },
+
+    Total: {
+      render(h) {
+        return (
+          <span class="el-pagination__total">共 { this.$parent.total } 条</span>
+        );
+      }
+    },
+
+    Pager
+  },
+
+  methods: {
+    handleCurrentChange(val) {
+      this.internalCurrentPage = this.getValidCurrentPage(val);
+      this.$emit('current-change', this.internalCurrentPage);
+    },
+
+    prev() {
+      const oldPage = this.internalCurrentPage;
+      const newVal = this.internalCurrentPage - 1;
+      this.internalCurrentPage = this.getValidCurrentPage(newVal);
+
+      if (this.internalCurrentPage !== oldPage) {
+        this.$emit('current-change', this.internalCurrentPage);
+      }
+    },
+
+    next() {
+      const oldPage = this.internalCurrentPage;
+      const newVal = this.internalCurrentPage + 1;
+      this.internalCurrentPage = this.getValidCurrentPage(newVal);
+
+      if (this.internalCurrentPage !== oldPage) {
+        this.$emit('current-change', this.internalCurrentPage);
+      }
+    },
+
+    first() {
+      const oldPage = this.internalCurrentPage;
+      const newVal = 1;
+      this.internalCurrentPage = this.getValidCurrentPage(newVal);
+
+      if (this.internalCurrentPage !== oldPage) {
+        this.$emit('current-change', this.internalCurrentPage);
+      }
+    },
+
+    last() {
+      const oldPage = this.internalCurrentPage;
+      const newVal = this.pageCount;
+      this.internalCurrentPage = this.getValidCurrentPage(newVal);
+
+      if (this.internalCurrentPage !== oldPage) {
+        this.$emit('current-change', this.internalCurrentPage);
+      }
+    },
+
+    getValidCurrentPage(value) {
+      value = parseInt(value, 10);
+
+      var resetValue;
+      if (value < 1) {
+        resetValue = this.pageCount > 0 ? 1 : 0;
+      } else if (value > this.pageCount) {
+        resetValue = this.pageCount;
+      }
+
+      if (resetValue === undefined && isNaN(value)) {
+        value = this.pageCount > 0 ? 1 : 0;
+      }
+
+      return resetValue === undefined ? value : resetValue;
+    }
+  },
+
+  computed: {
+    pageCount() {
+      return Math.ceil(this.total / this.internalPageSize);
+    },
+
+    startRecordIndex() {
+      const result = (this.internalCurrentPage - 1) * this.internalPageSize + 1;
+      return result > 0 ? result : 0;
+    },
+
+    endRecordIndex() {
+      const result = this.internalCurrentPage * this.internalPageSize;
+      return result > this.total ? this.total : result;
+    }
+  },
+
+  watch: {
+    pageCount(newVal) {
+      if (newVal > 0 && this.internalCurrentPage === 0) {
+        this.internalCurrentPage = 1;
+      } else if (this.internalCurrentPage > newVal) {
+        this.internalCurrentPage = newVal;
+      }
+    },
+
+    currentPage: {
+      immediate: true,
+      handler(val) {
+        this.internalCurrentPage = val;
+      }
+    },
+
+    pageSize: {
+      immediate: true,
+      handler(val) {
+        this.internalPageSize = val;
+      }
+    },
+
+    internalCurrentPage(newVal, oldVal) {
+      newVal = parseInt(newVal, 10);
+
+      if (isNaN(newVal)) {
+        newVal = oldVal || 1;
+      } else {
+        newVal = this.getValidCurrentPage(newVal);
+      }
+
+      if (newVal !== undefined) {
+        Vue.nextTick(() => {
+          this.internalCurrentPage = newVal;
+        });
+      }
+    }
+  }
+};

+ 0 - 267
packages/pagination/src/pagination.vue

@@ -1,267 +0,0 @@
-<template>
-  <div class="el-pagination"></div>
-</template>
-
-<script type="text/ecmascript-6">
-  import Vue from 'vue';
-  import Pager from './pager.vue';
-  import ElSelect from 'packages/select/index.js';
-  import ElOption from 'packages/option/index.js';
-
-  var TEMPLATE_MAP = {
-    prev: '<span is="prev"></span>',
-    jumper: '<span is="jumper"></span>',
-    pager: '<span is="pager" :current-page="currentPage" :page-count="pageCount" @current-change="handleCurrentChange"></span>',
-    next: '<span is="next"></span>',
-    sizes: '<span is="sizes"></span>',
-    slot: '<slot></slot>',
-    total: '<span is="total"></span>'
-  };
-
-  export default {
-    name: 'ElPagination',
-
-    props: {
-      pageSize: {
-        type: Number,
-        default: 10
-      },
-
-      small: Boolean,
-
-      total: {
-        type: Number,
-        default: 0
-      },
-
-      currentPage: {
-        type: Number,
-        default: 1
-      },
-
-      layout: {
-        default: 'prev, pager, next, jumper, slot, ->, total'
-      },
-
-      pageSizes: {
-        type: Array,
-        default() {
-          return [10, 20, 30, 40, 50, 100];
-        }
-      }
-    },
-
-    components: {
-      ElSelect,
-      ElOption,
-
-      Prev: {
-        template: `<button class="btn-prev" @click="$parent.prev()" :class="{ disabled: $parent.currentPage <= 1 }">
-          <i class="el-icon el-icon-arrow-left"></i>
-        </button>`
-      },
-
-      Next: {
-        template: `<button class="btn-next" @click="$parent.next()" :class="{ disabled: $parent.currentPage === $parent.pageCount }">
-          <i class="el-icon el-icon-arrow-right"></i>
-        </button>`
-      },
-
-      Sizes: {
-        template: `<span class="el-pagination__sizes">
-          <el-select size="small" :value="$parent.pageSize" @change="handleChange" :width="110">
-            <el-option v-for="item in $parent.pageSizes" :value="item" :label="item + ' 条/页'"></el-option>
-          </el-select>
-        </span>`,
-
-        methods: {
-          handleChange(val) {
-            if (val !== this.$parent.pageSize) {
-              this.$parent.pageSize = val = parseInt(val, 10);
-              this.$parent.$emit('size-change', val);
-            }
-          }
-        }
-      },
-
-      Jumper: {
-        data() {
-          return {
-            oldValue: null
-          };
-        },
-
-        methods: {
-          handleFocus(event) {
-            this.oldValue = event.target.value;
-          },
-
-          handleChange(event) {
-            const target = event.target;
-            if (target.value !== this.oldValue && Number(target.value) === this.$parent.currentPage) {
-              this.$parent.$emit('current-change', this.$parent.currentPage);
-            }
-
-            this.oldValue = null;
-          }
-        },
-
-        template: `<span class="el-pagination__jump">前往<input class="el-pagination__editor"
-          type="number"
-          :min="1"
-          :max="pageCount"
-          v-model="$parent.currentPage"
-          @change="handleChange($event)"
-          @focus="handleFocus($event)"
-          style="width: 30px;"
-          number
-          lazy />页</span>`
-      },
-
-      Total: {
-        template: '<span class="el-pagination__total">共 {{$parent.total}} 条</span>'
-      },
-
-      Pager
-    },
-
-    methods: {
-      handleCurrentChange(val) {
-        this.currentPage = this.getValidCurrentPage(val);
-        this.$emit('current-change', this.currentPage);
-      },
-
-      prev() {
-        const oldPage = this.currentPage;
-        const newVal = this.currentPage - 1;
-        this.currentPage = this.getValidCurrentPage(newVal);
-
-        if (this.currentPage !== oldPage) {
-          this.$emit('current-change', this.currentPage);
-        }
-      },
-
-      next() {
-        const oldPage = this.currentPage;
-        const newVal = this.currentPage + 1;
-        this.currentPage = this.getValidCurrentPage(newVal);
-
-        if (this.currentPage !== oldPage) {
-          this.$emit('current-change', this.currentPage);
-        }
-      },
-
-      first() {
-        const oldPage = this.currentPage;
-        const newVal = 1;
-        this.currentPage = this.getValidCurrentPage(newVal);
-
-        if (this.currentPage !== oldPage) {
-          this.$emit('current-change', this.currentPage);
-        }
-      },
-
-      last() {
-        const oldPage = this.currentPage;
-        const newVal = this.pageCount;
-        this.currentPage = this.getValidCurrentPage(newVal);
-
-        if (this.currentPage !== oldPage) {
-          this.$emit('current-change', this.currentPage);
-        }
-      },
-
-      getValidCurrentPage(value) {
-        value = parseInt(value, 10);
-
-        var resetValue;
-        if (value < 1) {
-          resetValue = this.pageCount > 0 ? 1 : 0;
-        } else if (value > this.pageCount) {
-          resetValue = this.pageCount;
-        }
-
-        if (resetValue === undefined && isNaN(value)) {
-          value = this.pageCount > 0 ? 1 : 0;
-        }
-
-        return resetValue === undefined ? value : resetValue;
-      }
-    },
-
-    created() {
-      this.$options._linkerCachable = false;
-      let template = `<div class="el-pagination ${this.small ? 'el-pagination--small' : ''}" >`;
-      const layout = this.$options.layout || this.layout || '';
-
-      const components = layout.split(',').map((item) => item.trim());
-
-      let haveRightWrapper = false;
-
-      components.forEach((component) => {
-        if (component === '->') {
-          haveRightWrapper = true;
-          template += '<div class="el-pagination__rightwrapper">';
-        } else {
-          if (!TEMPLATE_MAP[component]) {
-            console.warn('layout component not resolved:' + component);
-          }
-          template += TEMPLATE_MAP[component] || '';
-        }
-      });
-
-      if (haveRightWrapper) {
-        template += '</div>';
-      }
-      template += '</div>';
-
-      this.$options.template = template;
-    },
-
-    computed: {
-      pageCount() {
-        return Math.ceil(this.total / this.pageSize);
-      },
-
-      startRecordIndex() {
-        const result = (this.currentPage - 1) * this.pageSize + 1;
-        return result > 0 ? result : 0;
-      },
-
-      endRecordIndex() {
-        const result = this.currentPage * this.pageSize;
-        return result > this.total ? this.total : result;
-      }
-    },
-
-    watch: {
-      pageCount(newVal) {
-        if (newVal > 0 && this.currentPage === 0) {
-          this.currentPage = 1;
-        } else if (this.currentPage > newVal) {
-          this.currentPage = newVal;
-        }
-      },
-
-      currentPage(newVal, oldVal) {
-        newVal = parseInt(newVal, 10);
-
-        if (isNaN(newVal)) {
-          newVal = oldVal || 1;
-        } else {
-          newVal = this.getValidCurrentPage(newVal);
-        }
-
-        if (newVal !== undefined) {
-          Vue.nextTick(() => {
-            this.currentPage = newVal;
-          });
-        }
-      }
-    },
-
-    ready() {
-      this.currentPage = this.getValidCurrentPage(this.currentPage);
-    }
-  };
-</script>

+ 5 - 1
packages/select/src/select.vue

@@ -228,7 +228,10 @@
             return;
           }
           this.valueChangeBySelected = true;
-          this.$emit('input', val.map(item => item.value));
+          const result = val.map(item => item.value);
+
+          this.$emit('input', result);
+          this.$emit('change', result);
           if (this.selected.length > 0) {
             this.currentPlaceholder = '';
           } else {
@@ -246,6 +249,7 @@
         } else {
           if (val.value) {
             this.$emit('input', val.value);
+            this.$emit('change', val.value);
           }
         }
       },