diff --git a/components.json b/components.json
index 68e60b653..9a639f624 100644
--- a/components.json
+++ b/components.json
@@ -22,6 +22,9 @@
"badge": "./packages/badge/index.js",
"search": "./packages/search/index.js",
"step": "./packages/step/index.js",
+ "tabs": "./packages/tabs/index.js",
+ "tab": "./packages/tab/index.js",
+ "lazyload": "./packages/lazyload/index.js",
"image-preview": "./packages/image-preview/index.js",
"col": "./packages/col/index.js",
"row": "./packages/row/index.js",
diff --git a/docs/examples-docs/tab.md b/docs/examples-docs/tab.md
new file mode 100644
index 000000000..5df9777ab
--- /dev/null
+++ b/docs/examples-docs/tab.md
@@ -0,0 +1,126 @@
+## Tab 组件
+
+### 基础用法
+
+:::demo 基础用法
+```html
+
+ 内容一
+ 内容二
+ 内容三
+ 内容四
+ 内容五
+
+```
+
+
+:::
+### 禁用用法
+:::demo 禁用用法
+```html
+
+ 内容一
+ 内容二
+ 内容三
+ 内容四
+ 内容五
+
+
+```
+:::
+
+### card样式用法
+:::demo card样式用法
+```html
+
+ 内容一
+ 内容二
+ 内容三
+ 内容四
+ 内容五
+
+```
+:::
+
+
+### 自定义样式用法
+:::demo 自定义样式用法
+```html
+
+ 内容一
+ 内容二
+ 内容三
+ 内容四
+ 内容五
+
+
+```
+:::
+
+### zan-tabs API
+
+| 参数 | 说明 | 类型 | 默认值 | 可选 |
+|-----------|-----------|-----------|-------------|-------------|
+| classtype | 两种UI | string | line | card |
+| active | 默认激活的tab | string || number | 0 | |
+| navclass | tabs的内部nav上的自定义classname | string | '' | |
+
+
+### zan-tab API
+| 参数 | 说明 | 类型 | 默认值 | 必须 |
+|-----------|-----------|-----------|-------------|-------------|
+| title | tab的标题 | string | '' | required |
+| disable | 是否禁用这个tab | Boolean | false | |
+
diff --git a/docs/examples/tab.vue b/docs/examples/tab.vue
new file mode 100644
index 000000000..789d1210d
--- /dev/null
+++ b/docs/examples/tab.vue
@@ -0,0 +1,49 @@
+
+
+
Tab
+
+
基础用法line
+
+ 内容一
+ 内容二
+ 内容三
+ 内容四
+ 内容五
+
+
+
基础用法card
+
+ 内容一
+ 内容二
+
+
+
+
自定义样式用法
+
+ 内容一
+ 内容二
+ 内容三
+ 内容四
+ 内容五
+
+
+
+
\ No newline at end of file
diff --git a/packages/lazyload/CHANGELOG.md b/packages/lazyload/CHANGELOG.md
new file mode 100644
index 000000000..e88c472b3
--- /dev/null
+++ b/packages/lazyload/CHANGELOG.md
@@ -0,0 +1,8 @@
+## 0.0.2 (2017-01-20)
+
+* 改了bug A
+* 加了功能B
+
+## 0.0.1 (2017-01-10)
+
+* 第一版
diff --git a/packages/lazyload/README.md b/packages/lazyload/README.md
new file mode 100644
index 000000000..4c6172563
--- /dev/null
+++ b/packages/lazyload/README.md
@@ -0,0 +1,26 @@
+# @youzan/<%= name %>
+
+!!! 请在此处填写你的文档最简单描述 !!!
+
+[![version][version-image]][download-url]
+[![download][download-image]][download-url]
+
+[version-image]: http://npm.qima-inc.com/badge/v/@youzan/<%= name %>.svg?style=flat-square
+[download-image]: http://npm.qima-inc.com/badge/d/@youzan/<%= name %>.svg?style=flat-square
+[download-url]: http://npm.qima-inc.com/package/@youzan/<%= name %>
+
+## Demo
+
+## Usage
+
+## API
+
+| 参数 | 说明 | 类型 | 默认值 | 可选值 |
+|-----------|-----------|-----------|-------------|-------------|
+| className | 自定义额外类名 | string | '' | '' |
+
+
+
+
+## License
+[MIT](https://opensource.org/licenses/MIT)
diff --git a/packages/lazyload/index.js b/packages/lazyload/index.js
new file mode 100644
index 000000000..6f6f48f56
--- /dev/null
+++ b/packages/lazyload/index.js
@@ -0,0 +1,79 @@
+export default {
+ install: function(Vue, options) {
+ options = options || { fade: false, nohori: false };
+ // scroll结束的时候触发scrollend事件
+ var timer = null;
+ var topValue = 0;
+ var bodyEle = document.body;
+ var scrollEnd = document.createEvent('HTMLEvents');
+ scrollEnd.initEvent('scrollEnd', true, false);
+ function enterFrame() {
+ if (bodyEle.scrollTop === topValue) {
+ window.cancelAnimationFrame(timer);
+ window.dispatchEvent(scrollEnd);
+ } else {
+ topValue = bodyEle.scrollTop;
+ }
+ window.requestAnimationFrame(enterFrame);
+ }
+ document.addEventListener('scroll', function() {
+ if (!timer) {
+ timer = window.requestAnimationFrame(enterFrame);
+ }
+ }, true);
+ // vue指令
+ function update(value) {
+ if (!value) {
+ return;
+ }
+ var isFadeIn = this.modifiers.fade || options.fade;
+ var isNoHori = this.modifiers.nohori || options.nohori;
+ // 用css3来控制过渡效果
+ if (isFadeIn) {
+ this.el.style.opacity = 0;
+ this.el.style.transition = 'opacity .3s';
+ this.el.style.webkitTransition = 'opacity .3s';
+ }
+ var compute = function() {
+ if (this.el === null) {
+ return;
+ }
+ var rect = this.el.getBoundingClientRect();
+ var vpWidth = document.head.parentNode.clientWidth;
+ var vpHeight = document.head.parentNode.clientHeight;
+ var loadImg = function() {
+ this.el.src = value;
+ this.el.addEventListener('load', onloadEnd);
+ window.removeEventListener('scrollEnd', compute, true);
+ window.removeEventListener('resize', compute, true);
+ }.bind(this);
+ if (this.el.src === value) return;
+ if (isNoHori) {
+ if (rect.bottom >= 0 && rect.top <= vpHeight) {
+ loadImg();
+ }
+ } else if (rect.bottom >= 0 && rect.top <= vpHeight && rect.right >= 0 && rect.left <= vpWidth) {
+ loadImg();
+ }
+ }.bind(this);
+ var onload = function() {
+ compute();
+ this.el && this.el.removeEventListener('load', onload);
+ window.addEventListener('scrollEnd', compute, true);
+ window.addEventListener('resize', compute, true);
+ }.bind(this);
+ var onloadEnd = function() {
+ if (this.el === null) {
+ return;
+ }
+ if (isFadeIn) {
+ this.el.style.opacity = 1;
+ }
+ this.el.removeEventListener('load', onloadEnd);
+ }.bind(this);
+ // 元素load触发事件
+ this.el.addEventListener('load', onload);
+ }
+ Vue.directive('lazyload', update);
+ }
+};
diff --git a/packages/lazyload/package.json b/packages/lazyload/package.json
new file mode 100644
index 000000000..7dbfa2900
--- /dev/null
+++ b/packages/lazyload/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "<%= name %>",
+ "version": "<%= version %>",
+ "description": "<%= description %>",
+ "main": "./lib/index.js",
+ "author": "<%= author %>",
+ "license": "<%= license %>",
+ "devDependencies": {},
+ "dependencies": {}
+}
diff --git a/packages/tab/CHANGELOG.md b/packages/tab/CHANGELOG.md
new file mode 100644
index 000000000..e88c472b3
--- /dev/null
+++ b/packages/tab/CHANGELOG.md
@@ -0,0 +1,8 @@
+## 0.0.2 (2017-01-20)
+
+* 改了bug A
+* 加了功能B
+
+## 0.0.1 (2017-01-10)
+
+* 第一版
diff --git a/packages/tab/README.md b/packages/tab/README.md
new file mode 100644
index 000000000..4c6172563
--- /dev/null
+++ b/packages/tab/README.md
@@ -0,0 +1,26 @@
+# @youzan/<%= name %>
+
+!!! 请在此处填写你的文档最简单描述 !!!
+
+[![version][version-image]][download-url]
+[![download][download-image]][download-url]
+
+[version-image]: http://npm.qima-inc.com/badge/v/@youzan/<%= name %>.svg?style=flat-square
+[download-image]: http://npm.qima-inc.com/badge/d/@youzan/<%= name %>.svg?style=flat-square
+[download-url]: http://npm.qima-inc.com/package/@youzan/<%= name %>
+
+## Demo
+
+## Usage
+
+## API
+
+| 参数 | 说明 | 类型 | 默认值 | 可选值 |
+|-----------|-----------|-----------|-------------|-------------|
+| className | 自定义额外类名 | string | '' | '' |
+
+
+
+
+## License
+[MIT](https://opensource.org/licenses/MIT)
diff --git a/packages/tab/index.js b/packages/tab/index.js
new file mode 100644
index 000000000..551749afb
--- /dev/null
+++ b/packages/tab/index.js
@@ -0,0 +1,2 @@
+import Tab from './src/tab';
+export default Tab;
diff --git a/packages/tab/package.json b/packages/tab/package.json
new file mode 100644
index 000000000..7dbfa2900
--- /dev/null
+++ b/packages/tab/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "<%= name %>",
+ "version": "<%= version %>",
+ "description": "<%= description %>",
+ "main": "./lib/index.js",
+ "author": "<%= author %>",
+ "license": "<%= license %>",
+ "devDependencies": {},
+ "dependencies": {}
+}
diff --git a/packages/tab/src/tab.vue b/packages/tab/src/tab.vue
new file mode 100644
index 000000000..cf533df2b
--- /dev/null
+++ b/packages/tab/src/tab.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
diff --git a/packages/tab/src/tabs.vue b/packages/tab/src/tabs.vue
new file mode 100644
index 000000000..0cabeec72
--- /dev/null
+++ b/packages/tab/src/tabs.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
diff --git a/packages/tabs/index.js b/packages/tabs/index.js
new file mode 100644
index 000000000..5db150464
--- /dev/null
+++ b/packages/tabs/index.js
@@ -0,0 +1,3 @@
+import Tabs from '../tab/src/tabs';
+
+export default Tabs;
diff --git a/packages/zanui-css/src/index.css b/packages/zanui-css/src/index.css
index 90e722150..765d285c2 100644
--- a/packages/zanui-css/src/index.css
+++ b/packages/zanui-css/src/index.css
@@ -18,6 +18,7 @@
@import './steps.css';
@import './tag.css';
@import './checkbox.css';
+@import './tab.css';
@import './col.css';
@import './row.css';
@import './image_preview.css';
diff --git a/packages/zanui-css/src/tab.css b/packages/zanui-css/src/tab.css
new file mode 100644
index 000000000..9286383c4
--- /dev/null
+++ b/packages/zanui-css/src/tab.css
@@ -0,0 +1,100 @@
+@import "./common/var.css";
+@import "./mixins/border_retina.css";
+@component-namespace zan {
+ @b tabs {
+ position: relative;
+ }
+ @b tabs-line {
+ height: 44px;
+ background-color: $c-white;
+ &::after {
+ @mixin border-retina (top);
+ @mixin border-retina (bottom);
+ }
+ @b tabs-nav-bar {
+ display: block;
+ }
+ }
+ @b tabs-card {
+ height: 28px;
+ margin: 0 15px;
+ background-color: $c-white;
+ border-radius: 2px;
+ border: 1px solid #666666;
+ overflow: hidden;
+ .zan-tabs-nav-bar {
+ display: none;
+ }
+ .zan-tab {
+ color: #666666;
+ line-height: 28px;
+ border-right: 1px solid #666666;
+ &:last-child {
+ border-right: none;
+ }
+ &.zan-tab-active {
+ background-color: #666666;
+ color: $c-white;
+ }
+ }
+ }
+ @b tabs-nav {
+ display: flex;
+ transition: transform .5s cubic-bezier(.645, .045, .355, 1);
+ position: relative;
+ /*float: left*/
+ &::after, &::before {
+ display: table;
+ content: " "
+ }
+ &::after {
+ clear: both
+ }
+ }
+ @b tabs-nav-bar {
+ z-index: 1;
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ height: 2px;
+ background-color: #f13e3a;
+ transition: transform .3s cubic-bezier(.645, .045, .355, 1);
+ transform-origin: 0 0;
+ }
+ @b tab {
+ color: $c-black;
+ font-size: 14px;
+ line-height: 44px;
+ flex: 1;
+ display: inline-block;
+ box-sizing: border-box;
+ transition: color .3s cubic-bezier(.645, .045, .355, 1);
+ cursor: pointer;
+ text-align: center;
+ }
+ @b tab-active {
+ color: #FF4444;
+ }
+ @b tabs-pane {
+ display: none;
+ @when select {
+ display: block;
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/index.js b/src/index.js
index 798759425..25d0d9431 100644
--- a/src/index.js
+++ b/src/index.js
@@ -21,6 +21,9 @@ import BadgeGroup from '../packages/badge-group/index.js';
import Badge from '../packages/badge/index.js';
import Search from '../packages/search/index.js';
import Step from '../packages/step/index.js';
+import Tabs from '../packages/tabs/index.js';
+import Tab from '../packages/tab/index.js';
+import Lazyload from '../packages/lazyload/index.js';
import ImagePreview from '../packages/image-preview/index.js';
import Col from '../packages/col/index.js';
import Row from '../packages/row/index.js';
@@ -50,6 +53,8 @@ const install = function(Vue) {
Vue.component(Badge.name, Badge);
Vue.component(Search.name, Search);
Vue.component(Step.name, Step);
+ Vue.component(Tabs.name, Tabs);
+ Vue.component(Tab.name, Tab);
Vue.component(Col.name, Col);
Vue.component(Row.name, Row);
Vue.component(Actionsheet.name, Actionsheet);
@@ -86,6 +91,9 @@ module.exports = {
Badge,
Search,
Step,
+ Tabs,
+ Tab,
+ Lazyload,
ImagePreview,
Col,
Row,