Forráskód Böngészése

Merge pull request #1052 from baiyaaaaa/feat-layout

responsive layout
SkyAo 8 éve
szülő
commit
fa334a09d4

+ 1 - 0
CHANGELOG.en-US.md

@@ -16,6 +16,7 @@
 - Fixed Table render error using vue-loader 9.9.0
 - Added `align-center` prop for Step, #994
 - Fixed Upload missing progress component, #1013
+- Layout: support the responsive layout
 
 ### 1.0.0
 

+ 1 - 0
CHANGELOG.zh-CN.md

@@ -15,6 +15,7 @@
 - 修复 Table 的 inline-template 在 vue-loader 9.9.0 渲染报错
 - 新增 Step 支持内容居中对齐, #994
 - 修复 Upload 单独引入时提示 progress 组件不存在, #1013
+- Layout 支持响应式布局
 
 ### 1.0.0
 

+ 4 - 0
examples/docs/en-US/layout.md

@@ -146,4 +146,8 @@ Flexible alignment of columns.
 | offset | number of spacing on the left side of the grid | number | — | 0 |
 | push |  number of columns that grid moves to the right | number | — | 0 |
 | pull |  number of columns that grid moves to the left | number | — | 0 |
+| xs | `<768px` Responsive columns or column props object | number/object (i.e: {span: 4, offset: 4}) | — | — |
+| sm | `≥768px` Responsive columns or column props object | number/object (i.e: {span: 4, offset: 4}) | — | — |
+| md | `≥992` Responsive columns or column props object | number/object (i.e: {span: 4, offset: 4}) | — | — |
+| lg | `≥1200` Responsive columns or column props object | number/object (i.e: {span: 4, offset: 4}) | — | — |
 

+ 5 - 1
examples/docs/zh-CN/layout.md

@@ -134,7 +134,7 @@
 ::: demo 将 `type` 属性赋值为 'flex',可以启用 flex 布局,并可通过 `justify` 属性来指定 start, center, end, space-between, space-around 其中的值来定义子元素的排版方式。
 ```html
 <el-row type="flex" class="row-bg">
-  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
+  <el-col :span="6" :sm="8" :md="{span: 4, offset: 2}"><div class="grid-content bg-purple"></div></el-col>
   <el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
   <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
 </el-row>
@@ -176,3 +176,7 @@
 | offset | 栅格左侧的间隔格数 | number | — | 0 |
 | push |  栅格向右移动格数 | number | — | 0 |
 | pull |  栅格向左移动格数 | number | — | 0 |
+| xs | `<768px` 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
+| sm | `≥768px` 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
+| md | `≥992` 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
+| lg | `≥1200` 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |

+ 48 - 15
packages/col/src/col.vue

@@ -1,17 +1,3 @@
-<template>
-  <div
-    class="el-col"
-    :class="[
-      'el-col-' + span,
-      offset ? 'el-col-offset-' + offset : '',
-      pull ? 'el-col-pull-' + pull : '',
-      push ? 'el-col-push-' + push : ''
-    ]"
-    :style="style"
-  >
-    <slot></slot>
-  </div>
-</template>
 <script>
   export default {
     name: 'ElCol',
@@ -23,7 +9,11 @@
       },
       offset: Number,
       pull: Number,
-      push: Number
+      push: Number,
+      xs: [Number, Object],
+      sm: [Number, Object],
+      md: [Number, Object],
+      lg: [Number, Object]
     },
 
     computed: {
@@ -41,6 +31,49 @@
 
         return ret;
       }
+    },
+    render(h) {
+      let { style } = this;
+      let classList = [];
+
+      ['span', 'offset', 'pull', 'push'].forEach(prop => {
+        if (this[prop]) {
+          classList.push(
+            prop !== 'span'
+            ? `el-col-${prop}-${this[prop]}`
+            : `el-col-${this[prop]}`
+          );
+        }
+      });
+
+      ['xs', 'sm', 'md', 'lg'].forEach(size => {
+        if (typeof this[size] === 'number') {
+          classList.push(`el-col-${size}-${this[size]}`);
+        } else if (typeof this[size] === 'object') {
+          let props = this[size];
+          Object.keys(props).forEach(prop => {
+            classList.push(
+              prop !== 'span'
+              ? `el-col-${size}-${prop}-${props[prop]}`
+              : `el-col-${size}-${props[prop]}`
+            );
+          });
+        }
+      });
+
+      const data = {
+        class: classList,
+        style
+      };
+
+      return (
+        <div
+          class="el-col"
+          {...data}
+        >
+          {this.$slots.default}
+        </div>
+      );
     }
   };
 </script>

+ 63 - 4
packages/theme-default/src/col.css

@@ -7,18 +7,77 @@
 }
 
 @for $i from 1 to 24 {
-  .el-col-$i {
+  .el-col-$i,
+  .el-col-xs-$i {
     width: calc(1 / 24 * $(i) * 100)%;
   }
-  .el-col-offset-$i {
+  .el-col-offset-$i,
+  .el-col-xs-offset-$i {
     margin-left: calc(1 / 24 * $(i) * 100)%;
   }
-  .el-col-pull-$i {
+  .el-col-pull-$i,
+  .el-col-xs-pull-$i {
     position: relative;
     right: calc(1 / 24 * $(i) * 100)%;
   }
-  .el-col-push-$i {
+  .el-col-push-$i,
+  .el-col-xs-push-$i {
     position: relative;
     left: calc(1 / 24 * $(i) * 100)%;
   }
 }
+
+@media (min-width: 768px) {
+  @for $i from 1 to 24 {
+    .el-col-sm-$i {
+      width: calc(1 / 24 * $(i) * 100)%;
+    }
+  }
+  .el-col-xs-offset-$i {
+    margin-left: calc(1 / 24 * $(i) * 100)%;
+  }
+  .el-col-xs-pull-$i {
+    position: relative;
+    right: calc(1 / 24 * $(i) * 100)%;
+  }
+  .el-col-xs-push-$i {
+    position: relative;
+    left: calc(1 / 24 * $(i) * 100)%;
+  }
+}
+@media (min-width: 992px) {
+  @for $i from 1 to 24 {
+    .el-col-md-$i {
+      width: calc(1 / 24 * $(i) * 100)%;
+    }
+  }
+  .el-col-md-offset-$i {
+    margin-left: calc(1 / 24 * $(i) * 100)%;
+  }
+  .el-col-md-pull-$i {
+    position: relative;
+    right: calc(1 / 24 * $(i) * 100)%;
+  }
+  .el-col-md-push-$i {
+    position: relative;
+    left: calc(1 / 24 * $(i) * 100)%;
+  }
+}
+@media (min-width: 1200px) {
+  @for $i from 1 to 24 {
+    .el-col-lg-$i {
+      width: calc(1 / 24 * $(i) * 100)%;
+    }
+  }
+  .el-col-xs-offset-$i {
+    margin-left: calc(1 / 24 * $(i) * 100)%;
+  }
+  .el-col-xs-pull-$i {
+    position: relative;
+    right: calc(1 / 24 * $(i) * 100)%;
+  }
+  .el-col-xs-push-$i {
+    position: relative;
+    left: calc(1 / 24 * $(i) * 100)%;
+  }
+}

+ 16 - 0
test/unit/specs/col.spec.js

@@ -59,4 +59,20 @@ describe('Col', () => {
     expect(colElm.style.paddingLeft === '10px').to.be.true;
     expect(colElm.style.paddingRight === '10px').to.be.true;
   });
+  it('responsive', () => {
+    vm = createVue({
+      template: `
+        <el-row :gutter="20">
+          <el-col ref="col" :sm="{ span: 4, offset: 2 }" :md="8" :lg="{ span: 6, offset: 3 }">
+          </el-col>
+        </el-row>
+      `
+    }, true);
+    let colElm = vm.$refs.col.$el;
+    expect(colElm.classList.contains('el-col-sm-4')).to.be.true;
+    expect(colElm.classList.contains('el-col-sm-offset-2')).to.be.true;
+    expect(colElm.classList.contains('el-col-lg-6')).to.be.true;
+    expect(colElm.classList.contains('el-col-lg-offset-3')).to.be.true;
+    expect(colElm.classList.contains('el-col-md-8')).to.be.true;
+  });
 });