Browse Source

Merge branch 'dev' of https://github.com/jdf2e/nutui into dev

liaoyanli5 7 years ago
parent
commit
71eec5fa8f

+ 27 - 15
NEXT.md

@@ -1,22 +1,34 @@
-目前NutUI 2.0版正在紧锣密鼓的开发中。
+**NutUI 2.0计划**
 
-主要方向是组件的精品化和跨平台,从网站到组件全面提升用户体验,预计年底发布Beta版本。
+从标题可以看出,我们曾经有过 NutUI 1.0,没错!就是那个无所不能,包罗万象的 NutUI 组件库!!在上版组件库中,多位开发者呕心沥血,共同经历了组件库从无到有的过程。虽然第一个版本已经满足了大部分的业务需求,但是我们并不会止步于此!
+我们决定打磨出更好、更规范、更加优秀的组件库!这就是———— NutUI 2.0!
 
-新版本的NutUI将具备以下特性:
+在 NutUI 2.0 中我们决定重新构建组件库的架构,并且增加多个特性,保证组件质量的同时,优化组件样式,主要方向是组件的**精品化**和**跨平台**,从网站到组件全面提升用户体验。说到这里,有木有很激动?有木有很期待?反正我都快在凳子上激动的坐不住了,快让我来揭开 NutUI2.0 的新特性面纱吧!
 
-* 跨平台,提交的Vue组件自动生成微信小程序组件
-* 脚手架升级webpack 4.0,构建速度大幅提升
-* 网站页面设计由设计师小姐姐把持,组件严格按照京东APP最新UI规范开发
-* 统一的动效
-* 更方便、更灵活、更优雅的按需引用方式
-* 组件内建文案支持多语言(国际化)
-* 支持自定义主题
-* 基于MD文件自动生成文档
-* 支持自动化测试和持续集成
-* 官网将支持PWA
+>新版本的NutUI将具备以下特性:
 
 
+- [ ] 跨平台,提交的Vue组件自动生成微信小程序组件
+- [ ] 脚手架升级webpack 4.0,构建速度大幅提升
+- [ ] 网站页面设计由设计师小姐姐把持,组件严格按照京东APP最新UI规范开发
+- [ ] 统一的动效
+- [ ] 更方便、更灵活、更优雅的按需引用方式
+- [ ] 组件内建文案支持多语言(国际化)
+- [ ] 支持自定义主题
+- [ ] 基于MD文件自动生成文档
+- [ ] 支持自动化测试和持续集成
+- [ ] 官网将支持PWA
 
-如果你有好的建议,欢迎反馈给我们。
+------------------------------------------------------
+听我叨叨叨了这么多,各位看官肯定要问了,说的这么好,是骡子是马牵出来溜溜呀!
+别急,因为目前 NutUI 2.0 版还正在紧锣密鼓的开发中。
 
-nutui@jd.com
+<img src="http://img11.360buyimg.com/uba/jfs/t1/3443/17/12056/37762/5bd17892Ef40b38fd/0154d1c7c651a079.gif">
+2018 年对于 NutUI 组件库来说是不平凡的一年,从它呱呱坠地,到咿呀学语。我们就像看待自己的孩子一样,细心呵护,希望它不负众望,为广大前端开发者带来便利。士不可以不弘毅,任重而道远!在距离 2019 年还有两个月的时间内,我们的目标是:
+
+<img src="http://img11.360buyimg.com/uba/jfs/t1/6849/6/2522/310293/5bd17b79E953215d8/9a7d799ce0ca8b84.png">
+
+虽然只是 BETA 版本,但这是 NuiUI 2.0 的一大步!
+
+------------------------------------------------------
+如果你有好的建议,欢迎反馈给我们。我们的邮箱是 nutui@jd.com,期待您的来信!

+ 1 - 1
README.md

@@ -6,7 +6,7 @@
 
 # NutUI
 
-[![version](https://img.shields.io/badge/version-1.2-blue.svg?style=flat-square)](http://nutui.jd.com/)
+[![version](https://img.shields.io/badge/version-1.3-blue.svg?style=flat-square)](http://nutui.jd.com/)
 [![license](https://img.shields.io/badge/license-MIT-yellow.svg?style=flat-square)](http://nutui.jd.com/)
 
 > 基于Vue 2.0的移动端轻量级UI组件库

+ 29 - 1
config.json

@@ -1,5 +1,5 @@
 {
-  "version": "1.2.9",
+  "version": "1.3.1",
   "packages": [
     {
       "name": "DatePicker",
@@ -340,6 +340,34 @@
       "desc": "6位短密码弹层",
       "type": "component",
       "showDemo": true
+    },
+    {
+      "name": "NavBar",
+      "chnName": "拖动导航栏",
+      "desc": "用来解决深层页面跳转其他页面困难的问题, 初始化的时候是一个圆点,当我们需要跳转其他页面的时候,点击打开就行,同时支持拖动圆点",
+      "type": "component",
+      "showDemo": true
+    },
+    {
+      "name": "Scroller",
+      "chnName": "下拉刷新上拉加载组件",
+      "desc": "可下拉刷新上拉加载的容器组件",
+      "type": "component",
+      "showDemo": true
+    }, 
+    {
+      "name": "FooterCom",
+      "chnName": "公共底部菜单",
+      "desc": "公共底部菜单",
+      "type": "component",
+      "showDemo": true
+    },
+    {
+      "name": "Marquee",
+      "chnName": "跑马灯",
+      "desc": "文字以及内容的横向纵向轮播",
+      "type": "component",
+      "showDemo": true
     }
   ]
 }

+ 1 - 1
package.json

@@ -1,7 +1,7 @@
 {
   "name": "@nutui/nutui",
   "description": "基于Vue2的轻量级移动端UI组件库",
-  "version": "1.2.9",
+  "version": "1.3.1",
   "author": "jdc-fe",
   "main": "dist/nutui.js",
   "keywords": [

+ 1 - 1
src/app.vue

@@ -12,7 +12,7 @@
     	<router-view class="view sys-main" name="main"></router-view>
         <router-view class="view sys-phone" name="phone"></router-view>
     </div>
-    <div class="sys-footer"><div class="sys-inner"><span>Copyright © 2017~2018 <a href="https://jdc.jd.com/" target="_blank">JDC</a>. All Rights Reserved.</span></div></div>
+    <div class="sys-footer"><div class="sys-inner"><span>Copyright © 2017~2018 <a href="https://jdc.jd.com/" target="_blank">JDC</a>-<a href="http://fe.jd.com/" target="_blank">前端开发部</a>. All Rights Reserved.</span></div></div>
   </div>
 </template>
 <script>

BIN
src/asset/img/floatingClose.png


BIN
src/asset/img/nav.png


BIN
src/asset/img/tabCartNormal.png


BIN
src/asset/img/tabCartSelected.png


BIN
src/asset/img/tabCategoryNormal.png


BIN
src/asset/img/tabCategorySelected.png


BIN
src/asset/img/tabHomeNormal.png


BIN
src/asset/img/tabHomeSelected.png


BIN
src/asset/img/tabMeNormal.png


BIN
src/asset/img/tabMeSelected.png


+ 1 - 1
src/default.html

@@ -102,7 +102,7 @@
         <div class="tm-footer" style="background: #252525">
             <div class="uk-container uk-container-center uk-text-center">
                 <div class="uk-panel">
-                    <p>Copyright © 2017~2018 <a href="//jdc.jd.com">JDC-前端开发部</a></p>
+                    <p>Copyright © 2017~2018 <a href="//jdc.jd.com" target="_blank">JDC</a>-<a href="http://fe.jd.com" target="_blank">前端开发部</a></p>
                     <a href="index.html"><img src="../asset/img/nutui-logo-2.png" width="130" height="30" title="NutUI" alt="NutUI"></a>
                 </div>
 

+ 87 - 14
src/demo/dropdown.vue

@@ -1,27 +1,100 @@
 <template>
     <div>
-        <nut-dropdown ></nut-dropdown>
+        <nut-demoheader 
+        :name="$route.name"
+        ></nut-demoheader>
+        <h5>示例</h5>
+
+        <h6>示例1: 单选、简单数组</h6>
+        <nut-dropdown :options="options" @selectedChange='multipleSelected'></nut-dropdown>
+        <nut-codebox :code="demo1"></nut-codebox>
+
+        <h6>示例2: 单选、简单数组、设置默认值</h6>
+        <nut-dropdown :options="options" @selectedChange='multipleSelected' defaultSelected='二'></nut-dropdown>
+        <nut-codebox :code="demo2"></nut-codebox>
+
+        <h6>示例3: 多选、简单数组</h6>
+        <nut-dropdown :options="options" multiple @selectedChange='selectedChange'></nut-dropdown>
+        <nut-codebox :code="demo3"></nut-codebox>
+
+        <h6>示例4: 多选、简单数组、设置默认值</h6>
+        <nut-dropdown :options="options" multiple @selectedChange='selectedChange' :defaultSelected="['一','二']"></nut-dropdown>
+        <nut-codebox :code="demo4"></nut-codebox>
+
+        <h6>示例5: 单选、复杂对象数组、自定义展示字段</h6>
+        <nut-dropdown :options="options2" @selectedChange='selectedChange' optionKey='name'></nut-dropdown>
+        <nut-codebox :code="demo5"></nut-codebox>
+
+        <h6>示例6: 多选、复杂对象数组、自定义展示字段</h6>
+        <nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name'></nut-dropdown>
+        <nut-codebox :code="demo6"></nut-codebox>
+
+        <h6>示例7: 单选、复杂对象数组、自定义展示字段、设置默认值</h6>
+        <nut-dropdown :options="options2" @selectedChange='selectedChange' optionKey='name' :defaultSelected="{name: '李四', id: 2}"></nut-dropdown>
+        <nut-codebox :code="demo7"></nut-codebox>
+
+        <h6>示例8: 多选、复杂对象数组、自定义展示字段、设置默认值</h6>
+        <nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name' :defaultSelected="[{name: '李四', id: 2}]"></nut-dropdown>
+        <nut-codebox :code="demo8"></nut-codebox>
+
+        <h6>示例9: 多选、复杂对象数组、自定义展示字段、支持搜索</h6>
+        <nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name' search></nut-dropdown>
+        <nut-codebox :code="demo9"></nut-codebox>
+
+        <h6>示例10: 单选、简单数组、支持搜索</h6>
+        <nut-dropdown :options="options" @selectedChange='selectedChange' search></nut-dropdown>
+        <nut-codebox :code="demo10"></nut-codebox>
     </div>
+
 </template>
 
 <script>
-//import jsonp from 'jsonp';
-
 export default {
-    data(){
-      return {
-       
-      }
+  data() {
+    return {
+      options: ['一','二','三','四'],
+      options2: [{name: '张三', id: 1}, {name: '李四', id: 2}, {name: '王五', id: 3}, {name: '马六', id: 4}, {name: '王久', id: 5}],
+      code: `
+        export default {
+          data() {
+            retuen {
+              options: ['一','二','三','四'],
+              options2: [{name: '张三', id: 1}, {name: '李四', id: 2}, {name: '王五', id: 3}, {name: '马六', id: 4}, {name: '王久', id: 5}],
+            }
+          },
+          methods: {
+            selectedChange(option) {
+              console.log(option)
+            },
+          }
+        }
+      `,
+      demo1: `<nut-dropdown :options="options" @selectedChange='multipleSelected'></nut-dropdown>`,
+      demo2: `<nut-dropdown :options="options" @selectedChange='selectedChange' defaultSelected='二'></nut-dropdown>`,
+      demo3: `<nut-dropdown :options="options" multiple @selectedChange='selectedChange'></nut-dropdown>`,
+      demo4: `<nut-dropdown :options="options" multiple @selectedChange='selectedChange' :defaultSelected="['一','二']"></nut-dropdown>`,
+      demo5: `<nut-dropdown :options="options2" @selectedChange='selectedChange' optionKey='name' ></nut-dropdown>`,
+      demo6: `<nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name'></nut-dropdown>`,
+      demo7: `<nut-dropdown :options="options2" @selectedChange='selectedChange' optionKey='name' :defaultSelected="{name: '李四', id: 2}"></nut-dropdown>`,
+      demo8: `<nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name' :defaultSelected="[{name: '李四', id: 2}]"></nut-dropdown>`,
+      demo9: `<nut-dropdown :options="options2" multiple @selectedChange='selectedChange' optionKey='name' search></nut-dropdown>`,
+      demo10: `<nut-dropdown :options="options" @selectedChange='selectedChange' search></nut-dropdown>`
+    };
+  },
+  mounted(){
+  },
+  methods: {
+    selectedChange(option) {
+      console.log(option)
     },
-    methods:{
-        
-    },
-    mounted(){
-
+    multipleSelected(options) {
+      console.log(options)
     }
-}
+  }
+};
 </script>
 
-<style>
+<style lang="scss">
 
 </style>
+

+ 134 - 0
src/demo/footercom.vue

@@ -0,0 +1,134 @@
+<template>
+    <div>
+        <nut-demoheader 
+        :name="$route.name"
+        ></nut-demoheader>
+        <h5>示例</h5>
+        <p>默认用法</p>
+       <nut-footercom :menuList='footerMenuList1' @changeMenuFn="changeMenuFn"></nut-footercom>
+        <p>仅显示图标</p>
+        <nut-footercom :menuList='footerMenuList2' @changeMenuFn="changeMenuFn"></nut-footercom>
+    </div>
+</template>
+
+<script>
+import Vue from "vue";
+import FooterCom from '../package/footercom/index.js';
+export default {
+  data() {
+    return {
+      code: `
+            //菜单图标文案 数组对象  使用须知:
+            // 1, 数组内对象可用属性共有: iconselect(选中图标)  icon(默认图标)   url(跳转地址)  text(文案)
+            // 2, text(文案) 要配置请全部配置。
+            // 3,  url(跳转地址) 不配置则不做跳转
+            // 4, iconselect(选中图标)  icon(默认图标)  为必选属性
+            export default {
+              data() {
+                return  {
+                  footerMenuList:[
+                      {
+                        iconselect:
+                          "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+                        icon:
+                          "http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
+                        url: "/orderDetail",
+                        text:'首页'
+                      },
+                      {
+                        iconselect:
+                          "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+                        icon:
+                          "http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
+                        url: "/orderDetail",
+                        text:'测试1'
+                      },
+                      {
+                        iconselect:
+                          "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+                        icon:
+                          "http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
+                        url: "/orderDetail",
+                        text:'测试2'
+                      },
+
+                      {
+                        iconselect:
+                          "http://img12.360buyimg.com/uba/jfs/t26998/32/1861936/1307/776501d8/5b7fc73dNf725ab6d.png",
+                        icon:
+                          "http://img13.360buyimg.com/uba/jfs/t22762/195/2428374466/1450/70f02b6/5b7fc73dN45d94c02.png",
+                        text:'测试3'
+                      }
+                    ]
+                }
+              },
+              methods: {
+                changeMenuFn(item) {
+                  console.log(item)
+                },
+              }
+            }
+          `,
+      footerMenuList1: [
+           {
+             iconselect: "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+             icon:"http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
+             url: "/orderDetail",
+             text:'首页'
+           },
+           {
+             iconselect: "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+             icon:"http://img13.360buyimg.com/uba/jfs/t22762/195/2428374466/1450/70f02b6/5b7fc73dN45d94c02.png",
+             url: "/orderDetail",
+             text:'菜单'
+           },
+           {
+             iconselect: "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+             icon:"http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
+             url: "/orderDetail",
+             text:'我的1'
+           },
+              {
+             iconselect: "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+             icon:"http://img13.360buyimg.com/uba/jfs/t22762/195/2428374466/1450/70f02b6/5b7fc73dN45d94c02.png",
+             url: "/orderDetail",
+             text:'我的'
+           }
+           ],
+      footerMenuList2: [
+           {
+             iconselect: "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+             icon:"http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
+             url: "/orderDetail"
+           },
+           {
+             iconselect: "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+             icon:"http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
+             url: "/orderDetail"
+           },
+           {
+             iconselect: "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
+             icon:"http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
+             url: "/orderDetail"
+           }
+           ]
+    };
+  },
+  methods: {
+    changeMenuFn(item) {
+      console.log(item);
+    }
+  },
+   components: {
+      'nut-footercom': FooterCom
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.footer-wrap{
+    position: relative !important;
+}
+</style>
+
+

+ 76 - 0
src/demo/marquee.vue

@@ -0,0 +1,76 @@
+<template>
+    <div>
+        <nut-demoheader
+        :name="$route.name"
+        ></nut-demoheader>
+        <h5>示例</h5>
+        <p>水平正向内容跑马灯</p>
+        <nut-marquee class="demo1" :gap='gap' :speed="10">
+            <template slot >
+                <div v-for="(d, idx) in slotDatas" :key='idx' class="txt"><a>www.jd.com</a>{{d}}</div>
+            </template>
+        </nut-marquee>
+        <p>水平逆向内容跑马灯</p>
+        <nut-marquee class="demo1" :gap='gap' :reverse="true" :speed='30'>
+            <template slot>
+                <div class="txt">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了1</div>
+            </template>
+        </nut-marquee>
+        <p>垂直正向内容跑马灯</p>
+        <nut-marquee class="demo1" 
+            :speed='30' 
+            :height="demo3Height" 
+            :direction='v'
+            :gap="gap">
+            <div class="txt1">我是垂直轮播图1</div>
+            <div class="txt1">我是垂直轮播图2</div>
+            <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+            <div class="txt1">我是垂直轮播图3</div>
+        </nut-marquee>
+        <p>垂直逆向内容跑马灯</p>
+        <nut-marquee class="demo1" 
+            :speed='10' 
+            :gap= 'gap'
+            :height="demo3Height" 
+            :direction='v'
+            :reverse="true">
+            <div class="txt1">我是垂直轮播图1</div>
+            <div class="txt1">我是垂直轮播图2</div>
+            <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+            <div class="txt1">我是垂直轮播图3</div>
+            <div class="txt1">我是垂直轮播图4</div>
+        </nut-marquee>
+    </div>    
+</template>
+<script>
+export default {
+    data() {
+        return {
+            h: '1.2rem',
+            v: 'vertical',
+            demo3Height: '4rem',
+            gap: '.2rem',
+            slotDatas: [
+                '我是轮播图1',
+                '我是轮播图2',
+                '我是轮播图3',
+                '我是轮播图4'
+            ]
+        }
+    }
+}
+</script>
+<style lang="scss" scoped>
+    .demo1 {
+        background: #fefad8;
+
+    }
+    .img {
+        width: 80%;
+    }
+    .txt {
+        line-height: .4rem;
+        white-space: nowrap;
+    }
+</style>
+

+ 88 - 0
src/demo/navbar.vue

@@ -0,0 +1,88 @@
+<template>
+    <div>
+        <nut-demoheader 
+        :name="$route.name"
+        ></nut-demoheader>
+        <!-- DEMO区域 -->
+        <nut-navBtn>
+
+        </nut-navBtn>
+        <!-- DEMO代码 -->
+    </div>
+</template>
+<script>
+// export default {
+//     data(){
+//         return{
+//             direction: 'h',
+//             boundary: {top: 50, bottom: 20, left: 0, right: 0},
+//             isSide: false,
+//             demo1:`<nut-drag direction="h"></nut-drag>`,
+//             demo2:`<nut-drag :boundary="{top: 20, bottom: 20}"></nut-drag>`,
+//             demo3:`<nut-drag :isSide="false"></nut-drag>`,
+            
+//         }
+//     },
+//     methods:{
+//         changeMove(x, e){
+//             let dom = e.currentTarget;
+//             let siblings = dom.parentElement.children;
+//             this.removeClass(siblings);
+//             dom.classList.add('curr');
+//             this.direction = x;
+//         },
+//         changeBoundary(x, e){
+//             let dom = e.currentTarget;
+//             let siblings = dom.parentElement.children;
+//             this.removeClass(siblings);
+//             dom.classList.add('curr');
+//             if (x=='y') {
+//                 this.boundary = {top: 50, bottom: 20, left: 0, right: 0};
+//             }else{
+//                 this.boundary = {top: 50, bottom: 0, left: 0, right: 0};
+//             }
+            
+//         },
+//         changeSide(b, e){
+//             let dom = e.currentTarget;
+//             let siblings = dom.parentElement.children;
+//             this.removeClass(siblings);
+//             dom.classList.add('curr');
+//             dom.classList.add('curr');
+//             this.isSide = b;
+//         },
+//         removeClass(siblings){  //去除同级的class
+//             for ( let i in siblings) {
+//                 if (siblings.hasOwnProperty(i) === true){
+//                     siblings[i].className = 'button-primary';
+//                 }
+//             }
+//         },
+//     }
+// }
+// </script>
+
+
+<style lang="scss" scoped>
+.button-primary{
+    display: inline-block;
+    height: 38px;
+    padding: 0 10px;
+    color: #555;
+    text-align: center;
+    font-size: 12px;
+    line-height: 38px;
+    text-decoration: none;
+    white-space: nowrap;
+    background-color: transparent;
+    border-radius: 3px;
+    border: 1px solid #bbb;
+    cursor: pointer;
+    box-sizing: border-box;
+    &.curr{
+        background-color: #33C3F0;
+        border-color: #33C3F0; 
+        color: #fff;
+    }
+}
+</style>

+ 60 - 0
src/demo/scroller.vue

@@ -0,0 +1,60 @@
+<template>
+  <div>
+    <nut-docheader 
+    :name="$route.name"
+    :showQrCode="true"></nut-docheader>
+
+    <h5>示例</h5>
+    <div class="scroller-container">
+      <nut-scroller 
+        :onRefresh="onRefresh" :onInfinite="onInfinite">
+        <div v-for="(item, index) in list" :key="index" class="content-item">{{'滚动区域的内容' + (index + 1)}}</div>
+      </nut-scroller>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+     list: [...Array(15)]
+    };
+  },
+  methods: {
+    onRefresh(done) {
+      setTimeout(() => {
+        this.list = [...Array(15)]
+          done()
+      }, 2000)
+    },
+    onInfinite(done) {
+      setTimeout(() => {
+        if (this.list && this.list.length < 30) {
+          this.list = [...this.list, ...Array(10)]
+          done(true);
+          return
+        }
+        done(false)
+      }, 2000)
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+  .scroller-container {
+    position: relative;
+    width: 100%;
+    height: 500px;
+		background: #f2f2f2;
+  }
+  .content-item {
+    padding: 5px;
+    line-height: 20px;
+    background: #cccccc;
+    margin-bottom: 10px;
+    font-size: 14px;
+  }
+</style>
+

+ 5 - 0
src/index.html

@@ -2,12 +2,17 @@
 <html>
 <head>
     <meta charset="utf-8" /> 
+    <meta http-equiv="Expires" content="0">
+    <meta http-equiv="Pragma" content="no-cache">
+    <meta http-equiv="Cache-control" content="no-cache">
+    <meta http-equiv="Cache" content="no-cache">
     <meta content="telephone=no" name="format-detection"/>
     <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
     <title>NutUI - 基于Vue2.0的移动端UI组件库</title> 
     <link rel="stylesheet" href="./asset/css/normalize.css">
     <link rel="stylesheet" href="./asset/css/skeleton.css">
     <!-- <link rel="stylesheet" href="./asset/css/monokai-sublime.css"> -->
+    <link rel="shortcut icon" href="../asset/img/logo.png" type="image/x-icon">
     <link rel="stylesheet" href="./asset/css/highlight.css">
     <link rel="stylesheet" href="./asset/css/main.css">
     <script src="./asset/js/highlight.pack.js"></script>

+ 3 - 2
src/package/addimagesbox/src/addimagesbox.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="nut-addimagesbox">
         <div v-html="icon"></div>
-        <input  @change="addImg" class="addImgs" type="file" name="files" multiple="multiple" accept="image/*">
+        <input ref="uploadInput"  @change="addImg" class="addImgs" type="file" name="files" multiple="multiple" accept="image/*">
     </div>
 </template>
 <script>
@@ -93,7 +93,8 @@ export default {
                         });  
                     }                                        
                 }                
-                                   
+                
+                this.$refs.uploadInput.value = '';                                
         },
          preview(data){
                 let that = this;

+ 7 - 0
src/package/marquee/index.js

@@ -0,0 +1,7 @@
+import Marquee from './src/marquee.vue';
+
+Marquee.install = function(Vue) {
+  Vue.component(Marquee.name, Marquee);
+};
+
+export default Marquee

+ 294 - 0
src/package/marquee/src/marquee.vue

@@ -0,0 +1,294 @@
+<template>
+    <div class="nut-marquee" :style="mainCss" ref="marquee" 
+        @mouseover="mouseover" 
+        @mouseout="mouseout" 
+        @touchenter="clickStop" 
+        @touchleave="clickRun">
+        <div class="nut-marquee-wrapper" ref='wrap'>
+            <!-- <div class="nut-marquee-item"> -->
+                <slot></slot>
+            <!-- </div> -->
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    name: 'nut-marquee',
+    props: {
+        speed: {
+            default: 30,
+            type: Number
+        },
+        height: {
+            default: 'auto',
+            type: String
+        },
+        direction: {
+            default: 'horizontal',
+            type: String,
+            validator: function (value) {
+                // 这个值必须匹配下列字符串中的一个
+                return ['horizontal', 'vertical'].indexOf(value) !== -1
+            }
+        },
+        reverse: {
+            default: false,
+            type: Boolean
+        },
+        gap: {
+            default: '0',
+            type: Number
+        }
+    },
+    data() {
+        return {
+            interval: null,
+            mainCss: {},
+            offset: {
+                x: 0,
+                y: 0
+            },
+            marquee: {
+                height:0,
+                width: 0
+            },
+            wrap: {
+                height: 0,
+                width: 0
+            },
+            realGap: 0
+        }
+    },
+    created() {
+        this.mainCss = {
+            height: this.height 
+        }
+    },
+
+    mounted() {
+        this.$nextTick(() => {
+            this.init()
+        })
+    },
+    methods: {
+        init() {
+            //尺寸不需要启动轮播滚动。
+            this.initStyle();
+            this.initWH();
+            if(!this.needRoll()) return;
+            this.createShadowDom();
+            this.initPosition();
+            this.initOffset();
+            this.start();
+        },
+        //获取出事高度,以便判断是否需要开启轮播功能。
+        initWH() {
+            this.marquee = {
+                height: this.$refs.marquee.clientHeight,
+                width: this.$refs.marquee.clientWidth
+            }
+            this.wrap = {
+                height: this.$refs.wrap.clientHeight,
+                width: this.$refs.wrap.clientWidth
+            }
+        },
+        initGap() {
+            //如果传入的为rem
+            if(this.gap.indexOf('rem') > -1) {
+                this.realGap = document.getElementsByTagName("html")[0].style.fontSize.replace('px', '')*this.gap.replace('rem', '');
+            }else if(this.gap.indexOf('px') > -1) {
+                this.realGap = this.gap.replace('px', '');
+            }
+        },
+        initStyle() {
+            let nodes = this.$refs.wrap.children;
+            for(let i = 0; i < nodes.length; i++) {
+                nodes[i].className += ' nut-marquee-item';
+                if(this.direction === 'horizontal') {
+                    nodes[i].style.setProperty('margin', `0 ${this.gap}`);
+                    nodes[i].style.setProperty('display', `inline`);
+                }else {
+                    nodes[i].style.setProperty('margin', `${this.gap} 0`);
+                    nodes[i].style.setProperty('display', `block`);
+                }
+            }
+        },
+        initPosition() {
+            this.marquee = {
+                height: this.$refs.marquee.clientHeight,
+                width: this.$refs.marquee.clientWidth
+            }
+            if(this.direction == 'horizontal') {
+                this.wrap = {
+                    height: this.$refs.wrap.clientHeight / 2,
+                    width: this.$refs.wrap.clientWidth / 2
+                }
+            }else {
+                this.wrap = {
+                    height: this.$refs.wrap.clientHeight / 2,
+                    width: this.$refs.wrap.clientWidth / 2
+                }
+            }
+            
+            this.offset.x = this.marquee.width;
+            this.offset.y = this.marquee.height;
+            
+        },
+        initOffset() {
+            if(!this.reverse) return;
+            if(this.direction == 'horizontal'){
+                this.offset.x = - this.wrap.width*2;
+            }else{
+                this.offset.y = -this.wrap.height*2;
+            }
+        },
+        mouseover() {
+            clearInterval(this.interval);
+        },
+        mouseout() {
+            this.start();
+        },
+        clickStop() {
+            clearInterval(this.interval);
+        },
+        clickRun() {
+            this.start();
+        },
+        start() {
+            if(['horizontal', 'vertical'].indexOf(this.direction) == -1) console.warn('参数direction有误,执行默认配置horizontal');
+            if(this.direction === 'vertical') {
+                this.startVertical();
+            } else {
+                this.startHorizontal();
+            }
+        },
+        //判断是否需要滚动
+        needRoll() {
+            let need = true;
+            if(this.direction === 'vertical') {
+                if(this.marquee.height > this.wrap.height) {
+                    //容器高于内容
+                    need = false;
+                }
+            }else {
+                if(this.marquee.width > this.wrap.width) {
+                    need = false;
+                }
+            }
+            return need;
+        },
+
+        ///启动水平滚动,水平滚动处理区域
+        startHorizontal() {
+            if(!this.reverse) {
+                this.normalHorizontalRoll();
+            }else {
+                this.reverseHorizontalRoll();
+            }
+        },
+        //横向普通模式运动
+        normalHorizontalRoll() {
+            let _self = this;
+            let width = this.wrap.width;
+            _self.interval = setInterval(function() {
+                _self.setTransform(_self.$refs.wrap, `translate3d(${_self.offset.x}px, 0, 0)`);
+                _self.offset.x = _self.offset.x - 1;
+                if(-(_self.offset.x) > width) {
+                    _self.offset.x = 0;
+                }
+            }, this.speed)
+        },
+        //横向反向模式运动
+        reverseHorizontalRoll() {
+            let _self = this;
+            let width = this.wrap.width;
+            _self.interval = setInterval(function() {
+                _self.setTransform(_self.$refs.wrap, `translate3d(${_self.offset.x}px, 0, 0)`);
+                _self.offset.x = _self.offset.x + 1 ;
+                if((_self.offset.x) > 0) {
+                    _self.offset.x = - width;
+                }
+            }, this.speed)
+        },
+        //启动垂直滚动
+        startVertical() {
+            if(!this.reverse) {
+                this.normalVerticalRoll();
+            }else {
+                this.reverseVerticalRoll();
+            }
+        },
+        //垂直普通模式运动
+        normalVerticalRoll() {
+            let _self = this;
+            let height = this.wrap.height;
+            _self.interval = setInterval(function() {
+                _self.setTransform(_self.$refs.wrap, `translate3d(0, ${_self.offset.y}px, 0)`);
+                _self.offset.y = _self.offset.y - 1 ;
+                if(-(_self.offset.y) > height) {
+                    _self.offset.y = 0 - (_self.realGap/2);
+                }
+            }, this.speed)
+        },
+        //垂直反向模式运动
+        reverseVerticalRoll() {
+            let _self = this;
+            let height = this.wrap.height;
+            _self.interval = setInterval(function() {
+                _self.setTransform(_self.$refs.wrap, `translate3d(0, ${_self.offset.y}px, 0)`);
+                _self.offset.y = _self.offset.y + 1 ;
+                if(-(_self.offset.y) < 0) {
+                    _self.offset.y = - height + (_self.realGap);
+                }
+            }, this.speed)
+        },
+        /*
+         * 功能操作区
+         */
+        //设置transform
+        setTransform (ele, val){
+            ele.style.transform = val;
+            ele.style.WebkitTransform = val;
+            ele.style.MozTransform = val;
+            ele.style.OTransform = val;
+        },
+        //无限模式中,创建dom来保证2次之间的衔接
+        createShadowDom(el) {
+            let con = this.$refs.wrap;
+            let childNodes = this.cloneNodes(this.$refs.wrap.children);
+            for(let i =0; i < childNodes.length; i++) {
+                let node = childNodes[i];
+                con.appendChild(node);
+            }
+        },
+        cloneNodes(nodes) {
+            let destNodes = [];
+            for(let i = 0; i < nodes.length; i++) {
+                nodes[i].className += ' nut-marquee-item';
+                destNodes.push(nodes[i].cloneNode(true));
+            }
+            return destNodes;
+
+        }
+
+    }
+}
+</script>
+<style lang='scss'>
+    .nut-marquee {
+        overflow: hidden;
+        width: 100%;
+        white-space: nowrap;
+        height: inherit;
+    }
+    .nut-marquee-wrapper {
+        display: inline-block;
+        overflow: hidden;
+        transition: transform 0ms linear;
+    }
+    .nut-marquee-item {
+        outline: none;
+        overflow: hidden;
+        margin: 0 10px;
+    }
+</style>

+ 7 - 0
src/package/navbar/index.js

@@ -0,0 +1,7 @@
+import NavBar from './src/navbar.vue';
+
+NavBar.install = function(Vue) {
+  Vue.component(NavBar.name, NavBar);
+};
+
+export default NavBar

+ 372 - 0
src/package/navbar/src/navbar.vue

@@ -0,0 +1,372 @@
+<template>
+  <div id="nut-drag" class="nut-drag" @touchstart="touchStart($event)" >
+      <span>{{visible,boundary.right}}</span>
+    <div v-if="!visible"  class="navBtn_open" @click="openBtnClick($event)"></div>
+    <div class="foot-box-wrapper" v-if="visible">
+        <div class="foot-box">
+            <!-- <router-link to="/index"> -->
+                <a  href="javascript:void(0)" :class="{'active': currChoose == 0}">
+                    <i class="foot-home"></i>
+                    <span>首页</span>
+                </a>
+            <!-- </router-link> -->
+            <!-- <router-link to="/Categroy" v-if="cIndex==0"> -->
+                <a  href="javascript:void(0)" :class="{'active': currChoose == 1}">
+                    <i class="foot-categroy"></i>
+                    <span>分类</span>
+                </a>
+            <!-- </router-link> -->
+            <!-- <router-link to="/cart"> -->
+                <a href="javascript:void(0)" :class="{'active': currChoose == 2}">
+                    <i class="foot-cart"></i>
+                    <span>购物车</span>
+                </a>
+            <!-- </router-link> -->
+            <!-- <router-link to="/my-welfare"> -->
+                <a href="javascript:void(0)"  :class="{'active': currChoose == 3}">
+                    <i class="foot-me"></i>
+                    <span>我的</span>
+                </a>
+            <!-- </router-link> -->
+            <a href="javascript:void(0)">
+                <i class="navBtn-close" @click.stop="closeBtnClick()"></i>
+            </a>
+        </div>
+    </div>
+</div>
+</template>
+<script>
+export default {
+  name: "nut-navBtn",
+  props: {
+    // visible: {
+    //   type: Boolean,
+    //   default: false
+    // },
+    currChoose: {
+      type: Number,
+      default: 0
+    },
+    isSide: {
+      type: Boolean,
+      default: true
+    },
+    unit: {
+      type: String,
+      default: "px"
+    },
+    direction: {
+      type: String,
+      default: "h"
+    },
+    // width: {
+    //   type: [Number, String],
+    //   default: 45
+    // },
+    height: {
+      type: [Number, String],
+      default: 45
+    },
+    zIndex: {
+      type: [Number, String],
+      default: 11
+    },
+    opacity: {
+      type: [Number, String],
+      default: 1
+    },
+    boundary: {
+      type: Object,
+      default: function() {
+        return {
+          top: 0,
+          left: 0,
+          right: 0,
+          bottom: 50
+        };
+      }
+    },
+    callback: {
+      type: Function,
+      default: function() {
+        return function() {};
+      }
+    },
+    href: {
+      //调转链接
+      type: String
+    }
+    // 'bgColor':{
+    //     type:String,
+    //     default:'rgba(0,0,0,.5)'
+    // },
+    // 'closeOnClickModal': {
+    //     type: Boolean,
+    //     default: true
+    // }
+  },
+  data() {
+    return {
+      width: null,
+      // boundary: {
+      //   top: 0,
+      //   left: 0,
+      //   right: 0,
+      //   bottom:50
+      // },
+      visible: false,
+      elWidth: 0,
+      elHeight: 0,
+      screenWidth: 0,
+      screenHeight: 0,
+      startTime: null,
+      endTime: null,
+      startTop: 0,
+      startLeft: 0
+    };
+  },
+  methods: {
+    openBtnClick() {
+      this.visible = true;
+    },
+    closeBtnClick() {
+      this.visible=false;
+      this.boundary.right = null;
+      
+    },
+    // drag中的方法
+    getElementInfo() {
+      let el = document.querySelector(".nut-drag");
+      let domElem = document.documentElement;
+      this.elWidth = el.offsetWidth;
+      this.elHeight = el.offsetHeight;
+      this.screenWidth = domElem.clientWidth;
+      this.screenHeight = domElem.clientHeight;
+      let distance = this.screenWidth - this.elWidth - el.offsetLeft;
+      el.style.zIndex = this.zIndex;
+      el.style.opacity = this.opacity;
+      el.style.width = this.width + this.unit;
+      el.style.height = this.height + this.unit;
+      if (this.boundary.left != 0) {
+        el.style.left = this.boundary.left + "px";
+      } else {
+        el.style.right = this.boundary.right + "px";
+      }
+      if (this.boundary.top != 0) {
+        el.style.top = this.boundary.top + "px";
+      } else {
+        el.style.bottom = this.boundary.bottom + "px";
+      }
+    },
+    touchStart(e) {
+      let target = e.currentTarget;
+      this.startTime = new Date();
+      this.startTop = target.offsetTop;
+      this.startLeft = target.offsetLeft;
+      target.addEventListener("touchmove", this.touchMove, false);
+      target.addEventListener("touchend", this.touchEnd, false);
+    },
+    touchMove(e) {
+      // e.preventDefault();
+      let target = e.currentTarget;
+      if (e.targetTouches.length == 1) {
+        let touch = e.targetTouches[0];
+        let currX = touch.clientX;
+        let currY = touch.clientY;
+        let rightLocation =
+          this.screenWidth - this.elWidth - this.boundary.right;
+        if (Math.abs(currX) > rightLocation) {
+          currX = rightLocation;
+        } else if (currX <= this.boundary.left) {
+          currX = this.boundary.left;
+        }
+        if (currY < this.elHeight / 2 + this.boundary.top) {
+          currY = this.elHeight / 2 + this.boundary.top;
+        } else if (
+          currY >
+          this.screenHeight - this.elHeight - this.boundary.bottom
+        ) {
+          currY = this.screenHeight - this.elHeight / 2 - this.boundary.bottom;
+        }
+        if (this.direction != "h") {
+          target.style.left = currX + this.unit;
+        }
+        if (this.direction != "v") {
+          target.style.top = currY - this.elHeight / 2 + this.unit;
+        }
+      }
+    },
+    touchEnd(e) {
+      // e.preventDefault();
+      let target = e.currentTarget;
+      this.endTime = new Date();
+      let touch = e.changedTouches[0];
+      let currX = touch.clientX;
+      let currY = touch.clientY;
+      let distanceTime = this.endTime - this.startTime;
+      let distanceX = currX - this.startLeft;
+      let distanceY = currY - this.startTop;
+      if (distanceTime > 500 && distanceTime < 2000) {
+        // if(this.visible){
+        //   this.closeBtnClick();
+        // }else{
+        //   this.openBtnClick();
+        // }
+      }
+      let rightLocation = this.screenWidth - this.elWidth - this.boundary.right;
+      if (this.isSide) {
+        if (currX > rightLocation) {
+          currX = rightLocation;
+        } else if (currX < this.boundary.left) {
+          currX = this.boundary.left;
+        } else {
+          currX =
+            currX < this.screenWidth / 2 + this.elWidth / 2
+              ? this.boundary.left
+              : rightLocation;
+        }
+        if (currY < this.elHeight / 2 + this.boundary.top) {
+          currY = this.elHeight / 2 + this.boundary.top;
+        } else if (
+          currY >
+          this.screenHeight - this.elHeight - this.boundary.bottom
+        ) {
+          currY = this.screenHeight - this.elHeight / 2 - this.boundary.bottom;
+        }
+      } else {
+        if (currX > rightLocation) {
+          currX = rightLocation;
+        } else if (currX < this.boundary.left) {
+          currX = this.boundary.left;
+        }
+        if (currY < this.elHeight / 2 + this.boundary.top) {
+          currY = this.elHeight / 2 + this.boundary.top;
+        } else if (
+          currY >
+          this.screenHeight - this.elHeight - this.boundary.bottom
+        ) {
+          currY = this.screenHeight - this.elHeight / 2 - this.boundary.bottom;
+        }
+      }
+      if (this.direction != "h" && Math.abs(distanceX) > 20) {
+        target.style.left = currX + this.unit;
+      }
+      if (this.direction != "v" && Math.abs(distanceY) > 20) {
+        target.style.top = currY - this.elHeight / 2 + this.unit;
+      }
+    }
+  },
+  computed: {
+    // cIndex() {
+    //   return this.$store.state.cIndex;
+    // }
+  },
+  watch: {},
+  mounted() {
+    this.$nextTick(() => {
+      this.getElementInfo();
+    });
+  }
+};
+</script>
+<style lang="scss" scoped>
+// @import '../asset/css/common.scss';
+.nut-drag {
+  position: fixed;
+  // bottom: 0.5rem;
+}
+.navBtn_open {
+  width: 0.41rem;
+  height: 0.41rem;
+  opacity: 1;
+  background-image: url("../../../asset/img/nav.png");
+  background-size: 0.4rem 0.4rem;
+  // position: fixed;
+  // right: 0.2rem;
+  bottom: 0.5rem;
+  // 兼容的处理iphoeX
+  bottom: calc(0.4rem + constant(safe-area-inset-bottom));
+  bottom: calc(0.4rem + env(safe-area-inset-bottom));
+}
+$warmGrey: rgb(153, 153, 153);
+@mixin bgpic($bgw, $bgh) {
+  width: $bgw;
+  height: $bgh;
+  background-size: $bgw $bgh;
+}
+.foot-box-wrapper {
+  width: 100%;
+  height: 0.65rem;
+  // calc动态计算长度值,safe-area-inset-bottom适配iphoneX
+  height: calc(0.65rem + constant(safe-area-inset-bottom));
+  height: calc(0.65rem + env(safe-area-inset-bottom));
+}
+.foot-box {
+  display: border-box;
+  max-width: 640px;
+  width: 3.55rem;
+  height: 0.65rem;
+  // position: fixed;
+
+  margin: 0 0.1rem;
+  // 适配iphoneX,前面的小数和高度有关
+  height: calc(0.65rem + constant(safe-area-inset-bottom));
+  height: calc(0.65rem + env(safe-area-inset-bottom));
+  border-top: 1px solid #d7d7d7;
+  display: flex;
+  background: #fdfdfd;
+  border-radius: 0.4rem;
+  padding: 0 0.1rem;
+  a {
+    flex: 1;
+    flex-direction: column;
+    display: flex;
+    height: 0.65rem;
+    align-items: center;
+    justify-content: center;
+    .foot-home {
+      @include bgpic(0.25rem, 0.25rem);
+      background-image: url("../../../asset/img/tabHomeNormal.png");
+    }
+    .foot-categroy {
+      @include bgpic(0.25rem, 0.25rem);
+      background-image: url("../../../asset/img/tabCategoryNormal.png");
+    }
+    .foot-cart {
+      @include bgpic(0.25rem, 0.25rem);
+      background-image: url("../../../asset/img/tabCartNormal.png");
+    }
+    .foot-me {
+      @include bgpic(0.25rem, 0.25rem);
+      background-image: url("../../../asset/img/tabMeNormal.png");
+    }
+    .navBtn-close {
+      @include bgpic(0.45rem, 0.45rem);
+      background-image: url("../../../asset/img/floatingClose.png");
+    }
+    span {
+      color: $warmGrey;
+      margin-top: 0.04rem;
+      font-size: 10px;
+    }
+  }
+  .active {
+    .foot-home {
+      background-image: url("../../../asset/img/tabHomeSelected.png");
+    }
+    .foot-categroy {
+      @include bgpic(0.21rem, 0.21rem);
+      background-image: url("../../../asset/img/tabCategorySelected.png");
+    }
+    .foot-cart {
+      background-image: url("../../../asset/img/tabCartSelected.png");
+    }
+    .foot-me {
+      background-image: url("../../../asset/img/tabMeSelected.png");
+    }
+    span {
+      color: #ec3b26;
+    }
+  }
+}
+</style>

+ 2 - 2
src/package/pictureview/src/pictureview.vue

@@ -7,7 +7,7 @@
                 direction="horizontal"
                 :paginationVisible="pagination"
                 ref="picReload">
-                <div class="nut-swiper-silde" v-for="(item, index) in imgArr">
+                <div class="nut-swiper-slide" v-for="(item, index) in imgArr" :key="index">
                     <img :src="item">
                 </div>
             </nut-swiper>
@@ -82,7 +82,7 @@ export default {
     justify-content:center;
     .nut-swiper{
         height: 4rem;
-        .nut-swiper-silde{
+        .nut-swiper-slide{
             display: flex;
             align-items: center;
             justify-content:center;

+ 7 - 0
src/package/scroller/index.js

@@ -0,0 +1,7 @@
+import Scroller from './src/scroller.vue';
+
+Scroller.install = function(Vue) {
+  Vue.component(Scroller.name, Scroller);
+};
+
+export default Scroller

+ 62 - 0
src/package/scroller/src/module/animate.js

@@ -0,0 +1,62 @@
+
+window.requestAnimFrame = (function(){
+  return  window.requestAnimationFrame       || 
+          window.webkitRequestAnimationFrame || 
+          window.mozRequestAnimationFrame    || 
+          window.oRequestAnimationFrame      || 
+          window.msRequestAnimationFrame     || 
+          function( callback ){
+            window.setTimeout(callback, 1000 / 60);
+          };
+})();
+
+export default content => {
+
+  let global = window;
+
+  let docStyle = document.documentElement.style;
+
+  let engine;
+  if (global.opera && Object.prototype.toString.call(opera) === '[object Opera]') {
+    engine = 'presto';
+  } else if ('MozAppearance' in docStyle) {
+    engine = 'gecko';
+  } else if ('WebkitAppearance' in docStyle) {
+    engine = 'webkit';
+  } else if (typeof navigator.cpuClass === 'string') {
+    engine = 'trident';
+  }
+
+  let vendorPrefix = {
+    trident: 'ms',
+    gecko: 'Moz',
+    webkit: 'Webkit',
+    presto: 'O'
+  }[engine];
+
+  return (end, start) => {
+    if (typeof start === 'undefined') {
+      content.style[vendorPrefix + 'Transform'] = 'translate3d(0, ' + end + 'px, 0)'
+      return
+    }
+    let _end = end
+    let _start = start
+    let dis 
+    let tar 
+    let step
+    let _move = () => {
+      dis = _end - _start
+      step = dis / 10
+      tar = _start + step
+      _start = tar
+      if (Math.abs(dis - step) < 1) {
+        content.style.WebkitTransform = 'translate3d(0, ' + end + 'px, 0)'
+        return
+      }
+      content.style.WebkitTransform = 'translate3d(0, ' + tar + 'px, 0)'
+      window.requestAnimFrame(_move)
+    }
+    window.requestAnimFrame(_move)
+  }
+}
+

+ 116 - 0
src/package/scroller/src/module/scroller.js

@@ -0,0 +1,116 @@
+export default class Scroller {
+  constructor(callback, options) {
+    let _options = {
+      top : 0,
+      pullH : 0,
+      loadH: 0,
+      outerH : 0,
+      prevTop : 0,
+      startY : 0,
+      offset : 100,
+      fetching : false,
+      hasMore: true
+    }
+    this.__animate = callback
+    for (let key in _options) {
+			this[key] = _options[key];
+    }
+    for (let key in options) {
+			this[key] = options[key];
+    }
+    this.innerH = this.innerContent.clientHeight
+    this.moveY = 0
+  }
+
+  initPullToRefresh(startPullCallback, arrivalFreedCallback, freedCallback) {
+    this.pullStart = startPullCallback
+    this.arrivalFreed = arrivalFreedCallback
+    this.freed = freedCallback
+  }
+
+  initPullToInfinite(infiniteCallback) {
+    this.onInfinite = infiniteCallback
+  }
+
+  doTouchStart(touches) {
+    this.prevTop = this.top
+    this.startY = touches[0].pageY
+    this.innerH = this.innerContent.clientHeight
+    this.moveY = 0
+  }
+
+  doTouchMove(touches) {
+    if (this.fetching) return
+
+    let _moveY = touches[0].pageY - this.startY
+    this.moveY = _moveY
+   
+    let _top = this.moveY + this.prevTop
+    this.__animate(_top)
+    this.top = _top
+    this.moveY = _moveY
+    if (this.fetching) return
+
+    let isBottom = Math.abs(_top) + this.outerH > this.innerH ? true : false
+    if (_moveY > 0) {
+      if (!this.enableRefresh) return
+      _top >= this.offset ? this.arrivalFreed() : this.pullStart()
+    } else {
+      if (!isBottom || !this.hasMore || !this.enableInfinite) return
+      this.fetching = true
+      this.onInfinite()
+    }
+  }
+
+  doTouchEnd(e) {
+    this.innerH = this.innerContent.clientHeight
+    let _normalEndTop = this.outerH - this.innerH
+    let isBottom = Math.abs(this.top) + this.outerH >= this.innerH ? true : false
+    if (this.top >= this.offset) {
+      if (!this.enableRefresh) {
+        this.__animate(0, this.top) 
+        this.top = 0
+        return
+      }
+      this.__animate(this.pullH, this.top)
+      this.top = this.pullH
+      this.freed()
+      return
+    }
+    if (this.top < 0 && !isBottom) {
+      this.__animate(this.top, this.top - this.moveY)
+      return
+    }
+    if (this.top < 0 && isBottom) {
+      if (this.outerH >= this.innerH) {
+        this.__animate(0, this.top)
+        this.top = 0
+        return
+      }
+      let _h = _normalEndTop
+      if (this.fetching) {
+        _h = _normalEndTop - this.loadH
+      }
+      this.__animate(_h, this.top)
+      this.top = _h
+      return
+    }
+    this.__animate(0, this.top)
+    this.top = 0
+  }
+
+  startRefresh() {
+    this.fetching = true
+  }
+
+  finishedRefesh() {
+    this.fetching = false
+    this.__animate(0, this.top)
+    this.top = 0
+  }
+
+  finishedInfinite(hasMore) {
+    this.fetching = false
+    this.hasMore = hasMore
+  }
+}

File diff suppressed because it is too large
+ 238 - 0
src/package/scroller/src/scroller.vue


+ 3 - 3
src/package/select/src/dateSwiper.vue

@@ -19,7 +19,7 @@
                             :speed="250"
                             @slideChangeEnd="slideEnd"
                             >
-                                <div class="nut-swiper-silde" v-for="item in d.data"><span>{{item[nodeKey]}}</span></div>
+                                <div class="nut-swiper-slide" v-for="item in d.data"><span>{{item[nodeKey]}}</span></div>
                             </nut-swiper>
                         </template>                    
                     </div>                
@@ -90,7 +90,7 @@
     }
 </script>
 <style lang="scss" scoped>
-    .nut-swiper-silde {
+    .nut-swiper-slide {
         height: 0.7rem!important;
         line-height: 0.7rem;
         text-align: center;
@@ -124,7 +124,7 @@
             padding-top: 1.40rem!important;
             transition: .5s all;
         }
-        .nut-swiper-silde-selected {
+        .nut-swiper-slide-selected {
             color: #333!important;
         }
     }

+ 1 - 1
src/view/cases.vue

@@ -629,7 +629,7 @@ p{
         width: 267px;
         height: 454px;
     }
-    .nut-swiper .nut-swiper-silde{
+    .nut-swiper .nut-swiper-slide{
         display: flex;
         justify-content: center;
     }

+ 4 - 9
src/view/footercom.vue

@@ -8,14 +8,11 @@
         :showQrCode="true"></nut-docheader>
         <!-- DEMO区域 -->
         <h6>默认用法(图标+文字)</h6>
-        <nut-codebox :code="demo1"  imgUrl="../asset/img/demo/footercom2.png"></nut-codebox>
-
+        <nut-codebox imgUrl="../asset/img/demo/footercom4.png" :code="demo1"></nut-codebox>
         <h6>仅显示图标</h6>
         <nut-footercom :menuList='footerMenuList'></nut-footercom>
         <nut-codebox imgUrl="../asset/img/demo/footercom3.png" :code="demo2"></nut-codebox>
-        <h6>均支持2个到4个子菜单</h6>
         <nut-footercom :menuList='footerMenuList'></nut-footercom>
-        <nut-codebox imgUrl="../asset/img/demo/footercom4.png" :code="demo3"></nut-codebox>
         <h6>使用须知与通用数据代码和回调示例</h6>
         <nut-codebox :code="code"></nut-codebox>
         <h5>Props</h5>
@@ -123,8 +120,8 @@ export default {
               }
             }
           `,
-      demo1: `<nut-footercom :menuList='footerMenuList'  @changeMenuFn="changeMenuFn"></nut-footercom>
-            //配置数据每一项为
+      demo1: `<nut-footercom :menuList='footerMenuList'  @changeMenuFn="changeMenuFn"></nut-footercom>//配置数据footerMenuList 数组长度支持2到4个子对象,具体看下方使用须知
+            //配置数据每一项为  
            {
              iconselect: "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
              icon:"http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
@@ -139,9 +136,7 @@ export default {
              iconselect: "http://img13.360buyimg.com/uba/jfs/t27010/39/1558743/896/9e3c3096/5b7fc73dN636e01f4.png",
              icon:"http://img20.360buyimg.com/uba/jfs/t24202/290/2428485933/1010/db808515/5b7fc6afN8d31330b.png",
              url: "/orderDetail"
-           }  `,
-      demo3: `<nut-footercom :menuList='footerMenuList'  @changeMenuFn="changeMenuFn"></nut-footercom>//配置数据footerMenuList 数组长度支持2到4个
-      `
+           }`
     };
   },
   methods: {

+ 187 - 0
src/view/marquee.vue

@@ -0,0 +1,187 @@
+<template>
+    <div>
+        <nut-docheader 
+        :name="$route.name" 
+        :chName="$route.params.chnName" 
+        type="Component" 
+        desc="跑马灯-支持文字以及内容的横向纵向轮播(当内容过少时不启动轮播)" 
+        :showQrCode="true"></nut-docheader>
+        <h5>示例</h5>
+        <h6>水平正向内容跑马灯</h6>
+        <nut-marquee class="demo1" :gap='gap' :speed="10">
+            <template slot >
+                <div v-for="(d, idx) in slotDatas" :key='idx' class="txt"><a>www.jd.com</a>{{d}}</div>
+            </template>
+        </nut-marquee>
+        <nut-codebox :code="demo1"></nut-codebox>
+
+        <h6>水平逆向内容跑马灯</h6>
+        <nut-marquee class="demo1" :gap='gap' :reverse="true" :speed='30'>
+            <template slot>
+                <div class="txt">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了1,前提是我必须超过屏幕容器的宽度才可以哦,这么长的文字都没有超过</div>
+            </template>
+        </nut-marquee>
+        <nut-codebox :code="demo2"></nut-codebox>
+
+        <h6>垂直正向内容跑马灯</h6>
+       <nut-marquee class="demo1" 
+            :speed='30' 
+            :height="demo3Height" 
+            :direction='v'
+            :gap="gap">
+            <div class="txt1">我是垂直轮播图1</div>
+            <div class="txt1">我是垂直轮播图2</div>
+            <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+            <div class="txt1">我是垂直轮播图3</div>
+        </nut-marquee>
+        <nut-codebox :code="demo3"></nut-codebox>
+
+        <h6>垂直逆向内容跑马灯</h6>
+        <nut-marquee class="demo1" 
+            :speed='10' 
+            :gap= 'gap'
+            :height="demo3Height" 
+            :direction='v'
+            :reverse="true">
+            <div class="txt1">我是垂直轮播图1</div>
+            <div class="txt1">我是垂直轮播图2</div>
+            <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+            <div class="txt1">我是垂直轮播图3</div>
+            <div class="txt1">我是垂直轮播图4</div>
+        </nut-marquee>
+        <nut-codebox :code="demo4"></nut-codebox>
+
+        <h5>Props</h5>
+        <div class="tbl-wrapper">
+        <table class="u-full-width">
+          <thead>
+            <tr>
+              <th>参数</th>
+              <th>说明</th>
+              <th>类型</th>
+              <th>默认值</th>
+              <th>可选值</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>direction</td>
+              <td>用来控制轮播方向</td>
+              <td>String</td>
+              <td>horizontal</td>
+              <td>horizontal/vertical</td>
+            </tr>
+            <tr>
+              <td>speed</td>
+              <td>轮播的速率-移动1px的时间,单位为ms</td>
+              <td>Number</td>
+              <td>30</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>height</td>
+              <td>direction设置为horizontal时,用来控制外层容器高度的</td>
+              <td>Number</td>
+              <td>auto</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>reverse</td>
+              <td>是否为逆向,正向指的是:从右向左,从下向上。</td>
+              <td>Boolean</td>
+              <td>false</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>gap</td>
+              <td>2个元素之间的间距,仅支持rem或者px,如0.2rem或20px,必须指明单位。</td>
+              <td>String</td>
+              <td>0</td>
+              <td>--</td>
+            </tr>
+          </tbody>
+        </table>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    data(){
+        return{
+            h: '1.2rem',
+            v: 'vertical',
+            demo3Height: '8rem',
+            gap: '.2rem',
+            slotDatas: [
+                '我是轮播图1',
+                '我是轮播图2',
+                '我是轮播图3',
+                '我是轮播图4',
+                '我是轮播图6',
+                '我是轮播图7',
+                '我是轮播图8',
+                '我是轮播图9',
+                '我是轮播图10'
+            ],
+          demo1: `<nut-marquee class="demo1" :gap='gap' :speed="10">
+    <template slot >
+        <div v-for="(d, idx) in slotDatas" :key='idx' class="txt"><a>www.jd.com</a>{{d}}</div>
+    </template>
+</nut-marquee>`,
+          demo2: `<nut-marquee class="demo1" :gap='gap' :reverse="true" :speed='30'>
+    <template slot>
+        <div class="txt">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了1,前提是我必须超过屏幕容器的宽度才可以哦,这么长的文字都没有超过</div>
+    </template>
+</nut-marquee>`,
+          demo3: `<nut-marquee class="demo1" 
+    :speed='30' 
+    :height="demo3Height" 
+    :direction='v'
+    :gap="gap">
+    <div class="txt1">我是垂直轮播图1</div>
+    <div class="txt1">我是垂直轮播图2</div>
+    <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+    <div class="txt1">我是垂直轮播图3</div>
+</nut-marquee>`,
+          demo4: `<nut-marquee class="demo1" 
+    :speed='10' 
+    :gap= 'gap'
+    :height="demo3Height" 
+    :direction='v'
+    :reverse="true">
+    <div class="txt1">我是垂直轮播图1</div>
+    <div class="txt1">我是垂直轮播图2</div>
+    <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+    <div class="txt1">我是垂直轮播图3</div>
+    <div class="txt1">我是垂直轮播图4</div>
+</nut-marquee>`
+        }
+    },
+    methods:{
+      showMask(){
+        this.maskShow = true;
+      },
+      hideMask(){
+        this.maskShow = false;
+      }
+    }
+}
+</script>
+
+<style>
+    .item {
+        display: inline-block;
+    }
+    .demo1 {
+        background: #fefad8;
+
+    }
+    .img {
+        width: 80%;
+    }
+    .txt {
+        line-height: .4rem;
+        white-space: nowrap;
+    }
+</style>

+ 209 - 0
src/view/navbar.vue

@@ -0,0 +1,209 @@
+<template>
+    <div>
+        <!-- 组件名和描述 -->
+        <nut-docheader 
+        :name="$route.name"
+        :chName="$route.params.chnName" 
+        type="Component" 
+        :showQrCode="true"
+        ></nut-docheader>
+
+        <h5>示例</h5>
+        <h6>基本用法</h6>
+        <nut-codebox :code="demo1" imgUrl="../asset/img/demo/choose.png"></nut-codebox>
+        <h6>事件</h6>
+        <nut-codebox :code="demo2"></nut-codebox>
+        <h5>Props</h5>
+        <div class="tbl-wrapper">
+        <table class="u-full-width">
+          <thead>
+            <tr>
+              <th>参数</th>
+              <th>说明</th>
+              <th>类型</th>
+              <th>默认值</th>
+              <th>可选值</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>visibile</td>
+              <td>打开和关闭选择弹层</td>
+              <td>Boolean</td>
+              <td>false</td>
+              <td>true</td>
+            </tr>
+            <tr>
+              <td>short</td>
+              <td>短的面板还是长的面板</td>
+              <td>Boolean</td>
+              <td>false</td>
+              <td>true</td>
+            </tr>
+            <tr>
+              <td>loading</td>
+              <td>是否还在异步加载数据中</td>
+              <td>Boolean</td>
+              <td>false</td>
+              <td>true</td>
+            </tr>
+            <tr>
+              <td>needCache</td>
+              <td>弹层打开后再关闭是否需要缓存下来数据,以备下次打开使用</td>
+              <td>Boolean</td>
+              <td>false</td>
+              <td>true</td>
+            </tr>
+            <tr>
+              <td>title</td>
+              <td>选择弹层标题</td>
+              <td>String</td>
+              <td>所在地区</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>onlyKey</td>
+              <td>列表数据对象中,区分每条数据的key名,如'id'</td>
+              <td>String</td>
+              <td>id</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>contentKey</td>
+              <td>列表数据对象中,用于显示到列表中的字段key名,如'name'</td>
+              <td>String</td>
+              <td>name</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>listData</td>
+              <td>弹层列表数据</td>
+              <td>Array</td>
+              <td>[]</td>
+              <td>--</td>
+            </tr>
+            
+          </tbody>
+        </table>
+        </div>
+        <h5>Events</h5>
+        <div class="tbl-wrapper">
+        <table class="u-full-width">
+          <thead>
+            <tr>
+              <th>事件名</th>
+              <th>说明</th>
+              <th>回调参数</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>init-choose</td>
+              <td>打开选择弹层时给列表初始化数据入口</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>close-choose</td>
+              <td>关闭选择弹层时的回调</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>choose-item</td>
+              <td>选择某一条选项时的回调</td>
+              <td>item:当前选中的数据,index: 当前操作的所处层级</td>
+            </tr>
+          </tbody>
+        </table>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    data(){
+        return{
+            demo1:`<nut-choose 
+        :visibile="showChoose"
+        :needCache="true"
+        @init-choose="initChoose" 
+        @close-choose="closeChoose" 
+        @choose-item="closeItem"
+        :listData="chooseData"></nut-choose> `,
+            demo2: `export default {
+    data(){
+      return {
+        showChoose: false,
+        loading: false,
+        chooseData: []
+      }
+    },
+    methods:{
+        initChoose() {
+            this.chooseData = [{ 'name': '北京', 'id': 1 },
+                { 'name': '上海', 'id': 2 },
+                { 'name': '天津', 'id': 3 },
+                { 'name': '重庆', 'id': 4 },
+                { 'name': '河北', 'id': 5 },
+                { 'name': '山西', 'id': 6 },
+                { 'name': '河南', 'id': 7 },
+                { 'name': '辽宁', 'id': 8 },
+                { 'name': '吉林', 'id': 9 },
+                { 'name': '黑龙江', 'id': 10 },
+                { 'name': '内蒙古', 'id': 11 },
+                { 'name': '江苏', 'id': 12 },
+                { 'name': '山东', 'id': 13 },
+                { 'name': '安徽', 'id': 14 },
+                { 'name': '浙江', 'id': 15 },
+                { 'name': '福建', 'id': 16 },
+                { 'name': '湖北', 'id': 17 },
+                { 'name': '湖南', 'id': 18 },
+                { 'name': '广东', 'id': 19 },
+                { 'name': '广西', 'id': 20 },
+                { 'name': '江西', 'id': 21 },
+                { 'name': '四川', 'id': 22 },
+                { 'name': '海南', 'id': 23 },
+                { 'name': '贵州', 'id': 24 },
+                { 'name': '云南', 'id': 25 },
+                { 'name': '西藏', 'id': 26 },
+                { 'name': '陕西', 'id': 27 },
+                { 'name': '甘肃', 'id': 28 },
+                { 'name': '青海', 'id': 29 },
+                { 'name': '宁夏', 'id': 30 },
+                { 'name': '新疆', 'id': 31 },
+                { 'name': '台湾', 'id': 32 }];
+        },
+        closeChoose() {
+            this.showChoose = false;
+            console.log('关闭了弹框');
+        },
+        closeItem(item,level) {
+            console.log('当前选中的数据:');
+            console.log(item);
+            let self = this;
+            if(level == 1) {
+                self.chooseData = [
+                    {
+                    "id": 2816,
+                    "name": "密云区"
+                    },
+                    {
+                    "id": 72,
+                    "name": "朝阳区"
+                    }
+                ];
+            }
+            if(level == 2) {
+                self.closeChoose();
+            }
+        }
+    }
+}`
+        }
+    },
+    methods:{
+    }
+}
+</script>
+
+<style lang="scss">
+</style>

+ 214 - 0
src/view/scroller.vue

@@ -0,0 +1,214 @@
+<template>
+    <div>
+        <nut-docheader 
+        :name="$route.name"
+        :showQrCode="true"></nut-docheader>
+        <h5>示例</h5>
+        <h6>通用数据代码和回调示例</h6>
+        <nut-codebox :code="code"></nut-codebox>
+
+        <h6>示例</h6>
+        <div class="scroller-container">
+          <nut-scroller 
+            :onRefresh="onRefresh" :onInfinite="onInfinite">
+            <div v-for="(item, index) in list" :key="index" class="content-item">{{'滚动区域的内容' + (index + 1)}}</div>
+          </nut-scroller>
+        </div>
+      
+        <h5>Props</h5>
+        <div class="tbl-wrapper">
+        <table class="u-full-width">
+          <thead>
+            <tr>
+              <th>参数</th>
+              <th>说明</th>
+              <th>类型</th>
+              <th>默认值</th>
+              <th>是否必传</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>offset</td>
+              <td>触发下拉刷新的阈值</td>
+              <td>Number</td>
+              <td>100</td>
+              <td>否</td>
+            </tr>
+            <tr>
+              <td>enableInfinite</td>
+              <td>是否开启上拉加载</td>
+              <td>Boolean</td>
+              <td>true</td>
+              <td>否</td>
+            </tr>
+            <tr>
+              <td>enableRefresh</td>
+              <td>是否开启下拉刷新</td>
+              <td>Boolean</td>
+              <td>true</td>
+              <td>否</td>
+            </tr>
+            <tr>
+              <td>onRefresh</td>
+              <td>下拉刷新执行的函数</td>
+              <td>Function</td>
+              <td>--</td>
+              <td>如果开启下拉刷新功能,必传</td>
+            </tr>
+            <tr>
+              <td>onInfinite</td>
+              <td>加载更多执行的函数</td>
+              <td>Function</td>
+              <td>--</td>
+              <td>如果开启上拉加载功能,必传</td>
+            </tr>
+            <tr>
+              <td>noDataText</td>
+              <td>没有更多数据时的提示语</td>
+              <td>String</td>
+              <td>没有更多数据了</td>
+              <td>否</td>
+            </tr>
+            <tr>
+              <td>refreshText</td>
+              <td>下拉刷新提示</td>
+              <td>String</td>
+              <td>下拉刷新</td>
+              <td>否</td>
+            </tr>
+            <tr>
+              <td>freedRefreshText</td>
+              <td>释放下拉提示语</td>
+              <td>String</td>
+              <td>松开刷新数据</td>
+              <td>否</td>
+            </tr>
+          </tbody>
+        </table>
+        </div>
+
+        <h5>插槽</h5>
+        <div class="tbl-wrapper">
+        <table class="u-full-width">
+          <thead>
+            <tr>
+              <th>插槽名</th>
+              <th>说明</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>refresh</td>
+              <td>刷新时的效果或文字</td>
+            </tr>
+            <tr>
+              <td>load-more</td>
+              <td>加载时的效果或文字</td>
+            </tr>
+          </tbody>
+        </table>
+        </div>
+    </div>
+
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      list: [...Array(10)],
+      code: `
+        <template>
+          <div class="scroller-container">
+            <nut-scroller 
+              :on-refresh="onRefresh"
+              :on-infinite="onInfinite">
+              <div v-for="(item, index) in list" :key="index" class="content-item">{{'滚动区域的内容' + (index + 1)}}</div>
+            </nut-scroller>
+          </div>
+        </template>
+        <style lang="scss">
+          .scroller-container {
+            position: relative;
+            width: 100%;
+            height: 300px;
+            background: #f2f2f2;
+          }
+          .content-item {
+            padding: 5px;
+            line-height: 20px;
+            background: #cccccc;
+            margin-bottom: 10px;
+            font-size: 14px;
+          }
+        </style>
+        
+          export default {
+            data() {
+              retuen {
+                list: [...Array(10)]
+              }
+            },
+            methods: {
+              onRefresh(done) {
+                setTimeout(() => {
+                  this.list = [...Array(10)]
+                    done()
+                }, 2000)
+              },
+              onInfinite(done) {
+                setTimeout(() => {
+                  if (this.list && this.list.length < 30) {
+                    this.list = [...this.list, ...Array(10)]
+                    done(true);
+                    return
+                  }
+                  done(false) // 回传没有更多数据的标识
+                }, 2000)
+              }
+            }
+          }
+        
+      `
+    };
+  },
+  mounted() {
+    
+  },
+  methods: {
+    onRefresh(done) {
+      setTimeout(() => {
+        this.list = [...Array(10)]
+          done()
+      }, 2000)
+    },
+    onInfinite(done) {
+      setTimeout(() => {
+        if (this.list && this.list.length < 30) {
+          this.list = [...this.list, ...Array(10)]
+          done(true);
+          return
+        }
+        done(false)
+      }, 2000)
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+  .scroller-container {
+    position: relative;
+    width: 100%;
+    height: 300px;
+		background: #f2f2f2;
+  }
+  .content-item {
+    padding: 5px;
+    line-height: 20px;
+    background: #cccccc;
+    margin-bottom: 10px;
+    font-size: 14px;
+  }
+</style>

+ 16 - 16
src/view/swiper.vue

@@ -212,16 +212,16 @@ export default {
    :performanceMode="true"
    ref="demo1"
    @slideChangeEnd="slideChangeEnd">
-    <div v-for="item in dataItem" class="nut-swiper-silde"><span>page{{item.name}}</span></div>
+    <div v-for="item in dataItem" class="nut-swiper-slide"><span>page{{item.name}}</span></div>
 </nut-swiper>`,
           demo2:
 `<nut-swiper
     :pagination-visible="false"
     :performanceMode="true"
     direction="vertical">
-    <div class="nut-swiper-silde"><span>page 1</span></div>
-    <div class="nut-swiper-silde"><span>page 2</span></div>
-    <div class="nut-swiper-silde"><span>page 3</span></div>
+    <div class="nut-swiper-slide"><span>page 1</span></div>
+    <div class="nut-swiper-slide"><span>page 2</span></div>
+    <div class="nut-swiper-slide"><span>page 3</span></div>
 </nut-swiper>`,
           demo3:
 `<nut-swiper
@@ -229,27 +229,27 @@ export default {
     @slideChangeEnd="slideChangeEnd"
     @slideChangeStart="slideChangeStart"
     direction="horizontal">
-    <div class="nut-swiper-silde"><span>page 1</span></div>
-    <div class="nut-swiper-silde"><span>page 2</span></div>
-    <div class="nut-swiper-silde"><span>page 3</span></div>
+    <div class="nut-swiper-slide"><span>page 1</span></div>
+    <div class="nut-swiper-slide"><span>page 2</span></div>
+    <div class="nut-swiper-slide"><span>page 3</span></div>
 </nut-swiper>`,
           demo4:
 `<nut-swiper
     :pagination-visible="true"
     :loop="true"
     direction="horizontal">
-    <div class="nut-swiper-silde"><span>page 1</span></div>
-    <div class="nut-swiper-silde"><span>page 2</span></div>
-    <div class="nut-swiper-silde"><span>page 3</span></div>
+    <div class="nut-swiper-slide"><span>page 1</span></div>
+    <div class="nut-swiper-slide"><span>page 2</span></div>
+    <div class="nut-swiper-slide"><span>page 3</span></div>
 </nut-swiper>`,
           demo5:
 `<nut-swiper
     :pagination-visible="false"
     :autoPlay="1000"
     direction="vertical">
-    <div class="nut-swiper-silde"><span>page 1</span></div>
-    <div class="nut-swiper-silde"><span>page 2</span></div>
-    <div class="nut-swiper-silde"><span>page 3</span></div>
+    <div class="nut-swiper-slide"><span>page 1</span></div>
+    <div class="nut-swiper-slide"><span>page 2</span></div>
+    <div class="nut-swiper-slide"><span>page 3</span></div>
 </nut-swiper>`,
           demo6:
 `<nut-swiper
@@ -259,7 +259,7 @@ export default {
     :lazyLoad="true"
     lazyLoadingUrl="//static.360buyimg.com/exploit/mplus/2.1.81/css/i/loading.gif"
     lazyLoaderrorUrl="">
-    <div class="nut-swiper-silde">
+    <div class="nut-swiper-slide">
       <div>
         <img data-src="//img11.360buyimg.com/n3/s300x300_jfs/t2029/269/1342378600/94347/c088416b/56581d53Ne97b6442.jpg" class="nut-swiper-lazyload"/>
         <p>牙膏牙膏吃牙膏</p>
@@ -273,7 +273,7 @@ export default {
         <p>妙洁 保鲜袋背心型食品袋中号200只装 可提携易打结</p>
       </div>
     </div>
-    <div class="nut-swiper-silde">
+    <div class="nut-swiper-slide">
       <div>
         <img data-src="//img11.360buyimg.com/n3/s300x300_jfs/t3826/185/3277282028/320781/8fbf1015/587c2fcaNc3741a59.jpg" class="nut-swiper-lazyload"/>
         <p>全棉灭菌免换洗</p>
@@ -287,7 +287,7 @@ export default {
         <p>训练宝宝咀嚼力</p>
       </div>
     </div>
-    <div class="nut-swiper-silde">
+    <div class="nut-swiper-slide">
       <div>
         <img data-src="//img11.360buyimg.com/n3/s300x300_jfs/t13924/18/765396019/118800/71bda7ea/5a13878fN35292d9b.jpg" class="nut-swiper-lazyload"/>
         <p>得力(deli)S01黑色0.5mm经典办公按动中性笔水性笔子弹头签字笔 12支/盒</p>

+ 3 - 1
webpack.config.js

@@ -20,7 +20,8 @@ webpackConfig.entry = {
 webpackConfig.output = {
     path: path.resolve(__dirname, 'dist'),
     publicPath: "/",
-    filename: '[name].js',
+    filename: "[name].js",
+    chunkFilename: "[name].[hash].js",
     library: 'nutui',
     libraryTarget: 'umd',
     umdNamedDefine: true
@@ -72,6 +73,7 @@ webpackConfig.plugins = [
     new HtmlWebpackPlugin({
         filename: path.resolve(__dirname, './dist/index.html'),
         template: './src/index.html',
+        hash:true,
         chunks: ['app']
     }),
     new HtmlWebpackPlugin({