Browse Source

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

suzigang 5 years ago
parent
commit
10a52210b8

+ 1 - 1
README-zh_CN.md

@@ -61,7 +61,7 @@ https://nutui.jd.com
 
 
 NutUI 已经投入了我们的生产环境中使用,业界也在广泛地使用。
 NutUI 已经投入了我们的生产环境中使用,业界也在广泛地使用。
 
 
-<img src="https://img12.360buyimg.com/imagetools/jfs/t1/103711/28/17214/247343/5e854d2aE0d93051b/f475b25de9b63972.png" />
+<img src="https://raw.githubusercontent.com/richard1015/nutui-user-cases/master/user-cases.jpg" />
 
 
 [征集更多优秀案例](https://github.com/richard1015/nutui-user-cases)
 [征集更多优秀案例](https://github.com/richard1015/nutui-user-cases)
 
 

+ 1 - 1
README.md

@@ -61,7 +61,7 @@ Documents:[2.X](https://nutui.jd.com/default.html#/start) | [1.X](https://nutu
 
 
 NutUI has been put into use in our production environment and is widely used in developing countries at the same time.
 NutUI has been put into use in our production environment and is widely used in developing countries at the same time.
 
 
-<img src="https://img12.360buyimg.com/imagetools/jfs/t1/103711/28/17214/247343/5e854d2aE0d93051b/f475b25de9b63972.png" />
+<img src="https://raw.githubusercontent.com/richard1015/nutui-user-cases/master/user-cases.jpg" />
 
 
 [Call for more excellent cases](https://github.com/richard1015/nutui-user-cases)
 [Call for more excellent cases](https://github.com/richard1015/nutui-user-cases)
 
 

+ 10 - 0
src/config.json

@@ -603,6 +603,16 @@
       "sort": "3",
       "sort": "3",
       "showDemo": false,
       "showDemo": false,
       "author": "szg2008"
       "author": "szg2008"
+    },
+    {
+      "version": "1.0.0",
+      "name": "Drag",
+      "chnName": "拖拽",
+      "desc": "实现可拖拽的任意元素",
+      "type": "component",
+      "sort": "5",
+      "showDemo": true,
+      "author": "张宇"
     }
     }
   ]
   ]
 }
 }

+ 4 - 1
src/nutui.js

@@ -118,6 +118,8 @@ import SubSideNavBar from "./packages/subsidenavbar/index.js";
 import "./packages/subsidenavbar/subsidenavbar.scss";
 import "./packages/subsidenavbar/subsidenavbar.scss";
 import SideNavBarItem from "./packages/sidenavbaritem/index.js";
 import SideNavBarItem from "./packages/sidenavbaritem/index.js";
 import "./packages/sidenavbaritem/sidenavbaritem.scss";
 import "./packages/sidenavbaritem/sidenavbaritem.scss";
+import Drag from "./packages/drag/index.js";
+import "./packages/drag/drag.scss";
 
 
 const packages = {
 const packages = {
   Cell,
   Cell,
@@ -177,7 +179,8 @@ const packages = {
   TimeLineItem: TimeLineItem,
   TimeLineItem: TimeLineItem,
   SideNavBar: SideNavBar,
   SideNavBar: SideNavBar,
   SubSideNavBar: SubSideNavBar,
   SubSideNavBar: SubSideNavBar,
-  SideNavBarItem: SideNavBarItem
+  SideNavBarItem: SideNavBarItem,
+  Drag: Drag
 };
 };
 
 
 const components = {};
 const components = {};

+ 74 - 0
src/packages/drag/demo.vue

@@ -0,0 +1,74 @@
+<template>
+  <div class="demo-list">
+    <nut-noticebar :closeMode="true" v-if="!isMobile"
+      >此 Demo 仅能在移动端浏览器体验,建议在 Android 或 iOS 设备上体验。
+    </nut-noticebar>
+    <h4>基本用法</h4>
+    <nut-drag name="demo1" :style="{ top: '100px', left: '8px' }">
+      <div class="touch-dom">基本用法</div>
+    </nut-drag>
+    <h4 :style="{ top: '150px' }">限制拖拽方向</h4>
+    <nut-drag name="demo2" direction="x" :style="{ top: '200px', left: '8px' }">
+      <div class="touch-dom">只能在X轴拖动</div>
+    </nut-drag>
+    <h4 :style="{ top: '250px' }">自动吸边</h4>
+    <nut-drag
+      name="demo3"
+      direction="x"
+      :attract="true"
+      :style="{ top: '300px', left: '8px' }"
+    >
+      <div class="touch-dom">拖动我</div>
+    </nut-drag>
+    <h4 :style="{ top: '350px' }">限制拖动边界</h4>
+    <div class="drag-boundary"></div>
+    <nut-drag
+      :boundary="{ top: 401, left: 9, bottom: bottom(), right: right() }"
+      name="demo4"
+      :attract="true"
+      :style="{ top: '400px', left: '8px' }"
+    >
+      <div class="touch-dom">拖动我</div>
+    </nut-drag>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  data() {
+    return {};
+  },
+  methods: {
+    right() {
+      return document.documentElement.clientWidth - 300 - 9;
+    },
+    bottom() {
+      return document.documentElement.clientHeight - 601;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.touch-dom {
+  height: 30px;
+  padding: 10px;
+  line-height: 30px;
+  text-align: center;
+  color: #fff;
+  background: red;
+  overflow: hidden;
+}
+h4 {
+  position: absolute;
+}
+.drag-boundary {
+  position: absolute;
+  top: 400px;
+  left: 8px;
+  width: 300px;
+  height: 200px;
+  border: 1px solid red;
+}
+</style>

+ 0 - 0
src/packages/drag/doc.md


+ 9 - 0
src/packages/drag/drag.scss

@@ -0,0 +1,9 @@
+.nut-drag {
+  position: fixed;
+  display: inline-block;
+  top: 0;
+  right: 0;
+  z-index: 9997 !important;
+  width: fit-content;
+  height: fit-content;
+}

+ 206 - 0
src/packages/drag/drag.vue

@@ -0,0 +1,206 @@
+<template>
+  <div class="nut-drag" @touchstart="touchStart($event)">
+    <slot></slot>
+  </div>
+</template>
+<script>
+import requestAniFrame from "../../utils/raf.js";
+/**
+ * @module drag
+ * @description 拖拽组件,用于页面中需要拖拽的元素
+ * @vue-prop {Boolean} [attract=false] - 拖拽元素是否需要自动吸边
+ * @vue-prop {String} [direction='all'] - 拖拽元素的拖拽方向
+ * @vue-prop {Number | String} [zIndex=11] - 拖拽元素的堆叠顺序
+ * @vue-prop {Object} [boundary={top: 0,left: 0,right: 0,bottom: 0}] - 拖拽元素的拖拽边界
+ * @vue-data {Number} elWidth 拖拽元素的宽度
+ * @vue-data {Number} elHeight 拖拽元素的高度
+ * @vue-data {Number} screenWidth 屏幕的宽度
+ * @vue-data {Number} screenHeight 屏幕的高度
+ * @vue-data {Number} startTop 拖拽元素距离顶部的距离
+ * @vue-data {Number} startLeft 拖拽元素距离左侧的距离
+ * @vue-data {Object} position 鼠标点击的位置,包含距离x轴和y轴的距离
+ */
+export default {
+  name: "nut-drag",
+  props: {
+    attract: {
+      type: Boolean,
+      default: false,
+    },
+    direction: {
+      type: String,
+      default: "all",
+    },
+    zIndex: {
+      type: [Number, String],
+      default: 11,
+    },
+    boundary: {
+      type: Object,
+      default: function() {
+        return {
+          top: 0,
+          left: 0,
+          right: 0,
+          bottom: 0,
+        };
+      },
+    },
+  },
+  data() {
+    return {
+      elWidth: 0,
+      elHeight: 0,
+      screenWidth: 0,
+      screenHeight: 0,
+      startTop: 0,
+      startLeft: 0,
+      position: { x: 0, y: 0 },
+    };
+  },
+  methods: {
+    /**
+     * 获取拖拽元素的属性和屏幕的宽高,初始化拖拽元素的位置
+     */
+    getElementInfo() {
+      const el = this.$el;
+      const domElem = document.documentElement;
+      this.elWidth = el.offsetWidth;
+      this.elHeight = el.offsetHeight;
+      this.screenWidth = domElem.clientWidth;
+      this.screenHeight = domElem.clientHeight;
+      el.style.zIndex = this.zIndex;
+      if (this.boundary.left) {
+        el.style.left = this.boundary.left + "px";
+      } else {
+        el.style.right = this.boundary.right + "px";
+      }
+      if (this.boundary.top) {
+        el.style.top = this.boundary.top + "px";
+      } else {
+        el.style.bottom = this.boundary.bottom + "px";
+      }
+    },
+    touchStart(e) {
+      const target = e.currentTarget;
+      this.startTop = target.offsetTop; // 元素距离顶部的距离
+      this.startLeft = target.offsetLeft; // 元素距离左侧的距离
+      this.position.x = e.touches[0].clientX; // 鼠标点击的x轴的距离
+      this.position.y = e.touches[0].clientY; // 鼠标点击的y轴的距离
+      this.$el.addEventListener("touchmove", this.touchMove, false);
+      this.$el.addEventListener("touchend", this.touchEnd, false);
+    },
+    touchMove(e) {
+      e.preventDefault();
+      const target = e.currentTarget;
+      if (e.targetTouches.length == 1) {
+        const touch = e.targetTouches[0];
+        this.nx = touch.clientX - this.position.x;
+        this.ny = touch.clientY - this.position.y;
+        this.xPum = this.startLeft + this.nx;
+        this.yPum = this.startTop + this.ny;
+        const rightLocation =
+          this.screenWidth - this.elWidth - this.boundary.right;
+        // 限制左右拖拽边界
+        if (Math.abs(this.xPum) > rightLocation) {
+          this.xPum = rightLocation;
+        } else if (this.xPum <= this.boundary.left) {
+          this.xPum = this.boundary.left;
+        }
+        // 限制上下拖拽边界
+        if (this.yPum < this.boundary.top) {
+          this.yPum = this.boundary.top;
+        } else if (
+          this.yPum >
+          this.screenHeight - this.elHeight - this.boundary.bottom
+        ) {
+          this.yPum = this.screenHeight - this.elHeight - this.boundary.bottom;
+        }
+        if (this.direction != "y") {
+          target.style.left = this.xPum + "px";
+        }
+        if (this.direction != "x") {
+          target.style.top = this.yPum + "px";
+        }
+      }
+    },
+    touchEnd(e) {
+      const target = e.currentTarget;
+      const touch = e.changedTouches[0];
+      let currX = touch.clientX;
+      const rightLocation =
+        this.screenWidth - this.elWidth - this.boundary.right;
+      if (currX > rightLocation) {
+        currX = rightLocation;
+        // console.log('往右划出边界');
+      } else if (currX < this.boundary.left) {
+        currX = this.boundary.left;
+        // console.log('往左划出边界');
+      } else {
+        currX =
+          currX < this.screenWidth / 2 ? this.boundary.left : rightLocation;
+        // console.log('在边界内滑动');
+      }
+      if (this.direction != "y" && this.attract) {
+        if (currX < this.screenWidth / 2) {
+          this.goLeft(target);
+        } else {
+          this.goRight(target, rightLocation);
+        }
+      }
+      if (this.direction != "x") {
+        target.style.top = this.yPum + "px";
+      }
+    },
+    goLeft(target) {
+      if (this.boundary.left) {
+        if (target.style.left.split("px")[0] > this.boundary.left) {
+          target.style.left = target.style.left.split("px")[0] - 10 + "px";
+          requestAniFrame(() => {
+            this.goLeft(target);
+          });
+        } else {
+          target.style.left = `${this.boundary.left}px`;
+        }
+      } else {
+        if (target.style.left.split("px")[0] > 10) {
+          target.style.left = target.style.left.split("px")[0] - 10 + "px";
+          requestAniFrame(() => {
+            this.goLeft(target);
+          });
+        } else {
+          target.style.left = "0px";
+        }
+      }
+    },
+    goRight(target, rightLocation) {
+      if (rightLocation - parseInt(target.style.left.split("px")[0]) > 10) {
+        target.style.left =
+          parseInt(target.style.left.split("px")[0]) + 10 + "px";
+        requestAniFrame(() => {
+          this.goRight(target, rightLocation);
+        });
+      } else {
+        target.style.left = rightLocation + "px";
+      }
+    },
+  },
+  mounted() {
+    this.getElementInfo();
+  },
+  activated() {
+    if (this.keepAlive) {
+      this.keepAlive = false;
+    }
+  },
+  deactivated() {
+    this.keepAlive = true;
+    this.$el.removeEventListener("touchmove", this.handleScroll, false);
+    this.$el.removeEventListener("touchend", this.handleScroll, false);
+  },
+  destroyed() {
+    this.$el.removeEventListener("touchmove", this.handleScroll, false);
+    this.$el.removeEventListener("touchend", this.handleScroll, false);
+  },
+};
+</script>

+ 8 - 0
src/packages/drag/index.js

@@ -0,0 +1,8 @@
+import Drag from './drag.vue';
+import './drag.scss';
+
+Drag.install = function(Vue) {
+  Vue.component(Drag.name, Drag);
+};
+
+export default Drag

+ 42 - 23
src/packages/price/price.vue

@@ -1,23 +1,25 @@
 <template>
 <template>
-    <div class="nut-price"  v-html="priceShow"><span></span></div>
+    <div class="nut-price" v-html="priceShow">
+        <span></span>
+    </div>
 </template>
 </template>
 <script>
 <script>
 export default {
 export default {
-    name:'nut-price',
+    name: "nut-price",
     props: {
     props: {
-        'price':{
-            type: [Number,String],
+        price: {
+            type: [Number, String],
             default: 0
             default: 0
         },
         },
-        'needSymbol':{
+        needSymbol: {
             type: Boolean,
             type: Boolean,
             default: true
             default: true
         },
         },
-        'decimalDigits':{
-            type: [Number,String],
+        decimalDigits: {
+            type: [Number, String],
             default: 2
             default: 2
         },
         },
-        'thousands': {
+        thousands: {
             type: Boolean,
             type: Boolean,
             default: false
             default: false
         }
         }
@@ -25,7 +27,9 @@ export default {
     computed: {
     computed: {
         priceShow() {
         priceShow() {
             let self = this;
             let self = this;
-            let symbol = self.needSymbol?'<span class="price-symbol">¥</span>':'';
+            let symbol = self.needSymbol
+                ? '<span class="price-symbol">¥</span>'
+                : "";
             return symbol + self.formatToHump(self.price);
             return symbol + self.formatToHump(self.price);
         }
         }
     },
     },
@@ -35,18 +39,31 @@ export default {
     methods: {
     methods: {
         //判断是否为小数点
         //判断是否为小数点
         checkPoint(num) {
         checkPoint(num) {
-            return (String(num)).indexOf('.') > 0;
+            return String(num).indexOf(".") > 0;
         },
         },
 
 
         //将数字转换成驼峰形式
         //将数字转换成驼峰形式
         formatToHump(num) {
         formatToHump(num) {
             let self = this;
             let self = this;
-            num = String(num).replace('¥','');
-            if(self.checkPoint(num)) {
-                let numArray = String(num).split('.');
-                return '<span class="price-big">'+self.formatThousands(numArray[0]) +'</span><span class="price-point">.</span><span class="price-small">' + self.formatDecimal(numArray[1]) + '</span>';
+            num = String(num).replace("¥", "");
+            if (self.checkPoint(num)) {
+                let numArray = Number(num).toFixed(this.decimalDigits);
+                numArray = String(numArray).split(".");
+                return (
+                    '<span class="price-big">' +
+                    self.formatThousands(numArray[0]) +
+                    '</span><span class="price-point">.</span><span class="price-small">' +
+                    self.formatDecimal(numArray[1]) +
+                    "</span>"
+                );
             } else {
             } else {
-                return '<span class="price-big">'+ self.formatThousands(num) +'</span><span class="price-point">.</span><span class="price-small">' + self.formatDecimal(0) + '</span>';
+                return (
+                    '<span class="price-big">' +
+                    self.formatThousands(num) +
+                    '</span><span class="price-point">.</span><span class="price-small">' +
+                    self.formatDecimal(0) +
+                    "</span>"
+                );
             }
             }
         },
         },
 
 
@@ -54,21 +71,23 @@ export default {
         formatDecimal(decimalNum) {
         formatDecimal(decimalNum) {
             let self = this;
             let self = this;
             let decimalDigits = self.decimalDigits;
             let decimalDigits = self.decimalDigits;
-            let result = '0.' + String(decimalNum);
-            let resultFixed = (result/1).toFixed(decimalDigits);
-            return String(resultFixed).substring(2,resultFixed.length);
+            let result = "0." + String(decimalNum);
+            let resultFixed = (result / 1).toFixed(decimalDigits);
+            return String(resultFixed).substring(2, resultFixed.length);
         },
         },
         //千分位显示
         //千分位显示
         formatThousands(num) {
         formatThousands(num) {
             let self = this;
             let self = this;
-            let result = '';
-            // let 
-            if(self.thousands) {
-                return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
+            let result = "";
+            // let
+            if (self.thousands) {
+                return (num || 0)
+                    .toString()
+                    .replace(/(\d)(?=(?:\d{3})+$)/g, "$1,");
             } else {
             } else {
                 return num;
                 return num;
             }
             }
         }
         }
     }
     }
-}
+};
 </script>
 </script>

+ 23 - 5
src/packages/scroller/horizontal-scroll.vue

@@ -20,6 +20,10 @@ export default {
         scrollTo: {
         scrollTo: {
             type: Number,
             type: Number,
             default: 1
             default: 1
+        },
+	listWidth: {
+            type: Number,
+            default: 0
         }
         }
     },
     },
     watch: {
     watch: {
@@ -49,7 +53,10 @@ export default {
     },
     },
     methods: {
     methods: {
         isShow() {
         isShow() {
-            let wrapH = this.$refs.wrapper.clientWidth;
+            let wrapH = this.listWidth ? this.listWidth : 
+                (window.innerWidth ||
+                document.documentElement.clientWidth ||
+                document.body.clientWidth);
             let listH = this.$refs.list.offsetWidth;
             let listH = this.$refs.list.offsetWidth;
             if (wrapH <= listH) {
             if (wrapH <= listH) {
                 this.isShowLoadMore =  true;
                 this.isShowLoadMore =  true;
@@ -72,7 +79,10 @@ export default {
 
 
         setMove(move, type, time) {
         setMove(move, type, time) {
             let updateMove = move + this.transformX;
             let updateMove = move + this.transformX;
-            let w = this.$refs.wrapper.clientWidth;
+            let w = this.listWidth ? this.listWidth :
+                (window.innerWidth ||
+                document.documentElement.clientWidth ||
+                document.body.clientWidth);
             let offsetWidth = this.$refs.list.offsetWidth;
             let offsetWidth = this.$refs.list.offsetWidth;
             if (type === 'end') {
             if (type === 'end') {
                 if (updateMove > 0) {
                 if (updateMove > 0) {
@@ -119,18 +129,25 @@ export default {
             if (!(Math.abs(move) > 20 && Math.abs(move) > Math.abs(moveY))) {
             if (!(Math.abs(move) > 20 && Math.abs(move) > Math.abs(moveY))) {
                 return false;
                 return false;
             } else {
             } else {
-                let w = this.$refs.wrapper.clientWidth;
+                let w = this.listWidth ? this.listWidth :
+                    (window.innerWidth ||
+                    document.documentElement.clientWidth ||
+                    document.body.clientWidth);
                 let maxMove = -this.$refs.list.offsetWidth + w;
                 let maxMove = -this.$refs.list.offsetWidth + w;
                 callback && callback(move, maxMove, moveY);
                 callback && callback(move, maxMove, moveY);
             }
             }
         },
         },
 
 
         touchMove(event) {
         touchMove(event) {
-            event.preventDefault();
+            //event.preventDefault();
             let changedTouches = event.changedTouches[0];
             let changedTouches = event.changedTouches[0];
             this.touchParams.lastTime = event.timestamp || Date.now();
             this.touchParams.lastTime = event.timestamp || Date.now();
             let moveTime = this.touchParams.lastTime - this.touchParams.startTime;
             let moveTime = this.touchParams.lastTime - this.touchParams.startTime;
             this.touchEvent(changedTouches, (move, maxMove, moveY) => {
             this.touchEvent(changedTouches, (move, maxMove, moveY) => {
+                event.preventDefault();
+                if (event.cancelable) {
+                    event.preventDefault();
+                }
                 if (move > 0 && this.isFirstShow) {
                 if (move > 0 && this.isFirstShow) {
                     this.isFirstShow = false;
                     this.isFirstShow = false;
                 }
                 }
@@ -139,13 +156,14 @@ export default {
         },
         },
 
 
         touchEnd(event) {
         touchEnd(event) {
+            event.stopPropagation();
             let changedTouches = event.changedTouches[0];
             let changedTouches = event.changedTouches[0];
             this.touchParams.lastTime = event.timestamp || Date.now();
             this.touchParams.lastTime = event.timestamp || Date.now();
             let moveTime = this.touchParams.lastTime - this.touchParams.startTime;
             let moveTime = this.touchParams.lastTime - this.touchParams.startTime;
             this.touchEvent(changedTouches, (move, maxMove) => {
             this.touchEvent(changedTouches, (move, maxMove) => {
                 //if (moveTime <= 300) {
                 //if (moveTime <= 300) {
                 if (Math.abs(move) > 100) {
                 if (Math.abs(move) > 100) {
-                    move = move * 2;
+                   move = move * 1.5;
                 }
                 }
 
 
                 // 释放跳转之类
                 // 释放跳转之类

+ 8 - 5
src/packages/scroller/scroller.scss

@@ -2,20 +2,23 @@
 .nut-scroller{
 .nut-scroller{
     display: flex;
     display: flex;
     height: 100%;
     height: 100%;
+    width: 100%;
     overflow: hidden;
     overflow: hidden;
 }
 }
 // 横向滚动 
 // 横向滚动 
 .nut-hor-scroll{
 .nut-hor-scroll{
     height: 100%;
     height: 100%;
     width: 100%;
     width: 100%;
-    // overflow: hidden;
+    overflow: hidden;
+    //touch-action: none; 
     .nut-hor-list{
     .nut-hor-list{
         height: 100%;
         height: 100%;
-        touch-action: none;
+        width: auto;
         display: inline-flex;
         display: inline-flex;
-        flex-direction: row;
-        box-orient: horizontal;
-        box-direction: normal;
+        // display: flex;
+        // flex-direction: row;
+        // box-orient: horizontal;
+        // box-direction: normal;
     }
     }
     .nut-hor-control{
     .nut-hor-control{
         height: 100%;
         height: 100%;

+ 45 - 44
src/packages/tabselect/doc.md

@@ -39,93 +39,93 @@ export default {
   components: {},
   components: {},
   data() {
   data() {
     return {
     return {
-      mainTitle: '配送',
-      subTitle: '送达时间',
+      mainTitle: "配送",
+      subTitle: "送达时间",
       defaultContent: [
       defaultContent: [
-        '9:00——10:00',
-        '10:00——11:00',
-        '11:00——12:00',
-        '12:00——13:00',
-        '13:00——15:00',
-        '15:00——17:00',
-        '17:00——19:00'
+        "9:00——10:00",
+        "10:00——11:00",
+        "11:00——12:00",
+        "12:00——13:00",
+        "13:00——15:00",
+        "15:00——17:00",
+        "17:00——19:00",
       ],
       ],
       tabList: [
       tabList: [
         {
         {
-          tabTitle: '京东快递', // 一级tab标题
+          tabTitle: "京东快递", // 一级tab标题
           children: [
           children: [
             // 一级tab内容
             // 一级tab内容
             {
             {
-              tabTitle: '1月13日 (星期一)', // 二级tab标题
+              tabTitle: "1月13日 (星期一)", // 二级tab标题
               content: [
               content: [
                 // 二级tab内容,不传默认使用defaultContent字段
                 // 二级tab内容,不传默认使用defaultContent字段
-                '11:00——12:00',
-                '12:00——13:00',
-                '13:00——15:00',
-                '15:00——17:00',
-                '17:00——19:00'
-              ]
+                "11:00——12:00",
+                "12:00——13:00",
+                "13:00——15:00",
+                "15:00——17:00",
+                "17:00——19:00",
+              ],
             },
             },
             {
             {
-              tabTitle: '1月14日 (星期二)'
+              tabTitle: "1月14日 (星期二)",
             },
             },
             {
             {
-              tabTitle: '1月15日 (星期三)'
+              tabTitle: "1月15日 (星期三)",
             },
             },
             {
             {
-              tabTitle: '1月16日 (星期四)'
+              tabTitle: "1月16日 (星期四)",
             },
             },
             {
             {
-              tabTitle: '1月17日 (星期五)'
+              tabTitle: "1月17日 (星期五)",
             },
             },
             {
             {
-              tabTitle: '1月18日 (星期六)'
+              tabTitle: "1月18日 (星期六)",
             },
             },
             {
             {
-              tabTitle: '1月19日 (星期天)'
-            }
-          ]
+              tabTitle: "1月19日 (星期天)",
+            },
+          ],
         },
         },
         {
         {
-          tabTitle: '上门自提',
+          tabTitle: "上门自提",
           children: [
           children: [
             {
             {
-              tabTitle: '2月13日 (星期一)',
-              content: ['13:00——15:00', '15:00——17:00', '17:00——19:00']
+              tabTitle: "2月13日 (星期一)",
+              content: ["13:00——15:00", "15:00——17:00", "17:00——19:00"],
             },
             },
             {
             {
-              tabTitle: '2月14日 (星期二)'
+              tabTitle: "2月14日 (星期二)",
             },
             },
             {
             {
-              tabTitle: '2月15日 (星期三)'
+              tabTitle: "2月15日 (星期三)",
             },
             },
             {
             {
-              tabTitle: '2月16日 (星期四)'
+              tabTitle: "2月16日 (星期四)",
             },
             },
             {
             {
-              tabTitle: '2月17日 (星期五)'
+              tabTitle: "2月17日 (星期五)",
             },
             },
             {
             {
-              tabTitle: '2月18日 (星期六)'
+              tabTitle: "2月18日 (星期六)",
             },
             },
             {
             {
-              tabTitle: '2月19日 (星期天)'
-            }
-          ]
-        }
+              tabTitle: "2月19日 (星期天)",
+            },
+          ],
+        },
       ],
       ],
-      show: false
-    }
+      show: false,
+    };
   },
   },
   methods: {
   methods: {
     choose(title, item) {
     choose(title, item) {
-      console.log(title, item)
+      console.log(title, item);
     },
     },
     onOkBtn(event) {
     onOkBtn(event) {
-      console.log(event)
-    }
-  }
-}
+      console.log(event);
+    },
+  },
+};
 ```
 ```
 
 
 ### Prop
 ### Prop
@@ -140,6 +140,7 @@ export default {
 | show              | 是否显示                                   | Boolean | false    |
 | show              | 是否显示                                   | Boolean | false    |
 | max               | 多选时最多可选个数                         | Number  | Infinity |
 | max               | 多选时最多可选个数                         | Number  | Infinity |
 | isDefaultSelected | 单选时是否默认选中第一项(多选默认不选中) | Boolean | false    |
 | isDefaultSelected | 单选时是否默认选中第一项(多选默认不选中) | Boolean | false    |
+| isLockBgScroll    | 是否锁定背景滚动                           | Boolean | true     |
 
 
 ### Event
 ### Event
 
 

+ 1 - 1
src/packages/tabselect/tabselect.scss

@@ -43,7 +43,7 @@
       min-width: 158px;
       min-width: 158px;
     }
     }
     .nut-title-nav {
     .nut-title-nav {
-      height: 40px;
+      min-height: 40px;
       line-height: 40px;
       line-height: 40px;
       background: #f4f4f4;
       background: #f4f4f4;
       padding-left: 18px;
       padding-left: 18px;

+ 32 - 24
src/packages/tabselect/tabselect.vue

@@ -6,6 +6,7 @@
       v-model="isShow"
       v-model="isShow"
       position="bottom"
       position="bottom"
       :style="{ height: '457px' }"
       :style="{ height: '457px' }"
+      :lock-scroll="isLockBgScroll"
     >
     >
       <div class="nut-tabselect-main-title" v-html="mainTitle"></div>
       <div class="nut-tabselect-main-title" v-html="mainTitle"></div>
       <nut-tab @tab-switch="tabSwitchOuter" :init-data="list">
       <nut-tab @tab-switch="tabSwitchOuter" :init-data="list">
@@ -35,7 +36,7 @@
                     @click="choose(idx, index, sIndex, item, sitem)"
                     @click="choose(idx, index, sIndex, item, sitem)"
                     class="nut-tab-panel-list"
                     class="nut-tab-panel-list"
                     :class="{
                     :class="{
-                      'nut-tab-panel-list-active': isActive(idx, index, sIndex)
+                      'nut-tab-panel-list-active': isActive(idx, index, sIndex),
                     }"
                     }"
                   >
                   >
                     {{ sitem }}
                     {{ sitem }}
@@ -48,7 +49,7 @@
                     @click="choose(idx, index, sIndex, item, sitem)"
                     @click="choose(idx, index, sIndex, item, sitem)"
                     class="nut-tab-panel-list"
                     class="nut-tab-panel-list"
                     :class="{
                     :class="{
-                      'nut-tab-panel-list-active': isActive(idx, index, sIndex)
+                      'nut-tab-panel-list-active': isActive(idx, index, sIndex),
                     }"
                     }"
                   >
                   >
                     {{ sitem }}
                     {{ sitem }}
@@ -75,36 +76,40 @@ export default {
   props: {
   props: {
     mainTitle: {
     mainTitle: {
       type: String,
       type: String,
-      default: ""
+      default: "",
     },
     },
     subTitle: {
     subTitle: {
       type: String,
       type: String,
-      default: ""
+      default: "",
+    },
+    isLockBgScroll: {
+      type: Boolean,
+      default: true,
     },
     },
     defaultContent: {
     defaultContent: {
       type: Array,
       type: Array,
-      default: () => []
+      default: () => [],
     },
     },
     tabList: {
     tabList: {
       type: Array,
       type: Array,
-      default: () => []
+      default: () => [],
     },
     },
     show: {
     show: {
       type: Boolean,
       type: Boolean,
-      default: false
+      default: false,
     },
     },
     multiple: {
     multiple: {
       type: Boolean,
       type: Boolean,
-      default: false
+      default: false,
     },
     },
     max: {
     max: {
       type: Number,
       type: Number,
-      default: Infinity
+      default: Infinity,
     },
     },
     isDefaultSelected: {
     isDefaultSelected: {
       type: Boolean,
       type: Boolean,
-      default: false
-    }
+      default: false,
+    },
   },
   },
   data() {
   data() {
     return {
     return {
@@ -114,12 +119,12 @@ export default {
       level2: this.isDefaultSelected ? new Set(["0-0"]) : new Set(),
       level2: this.isDefaultSelected ? new Set(["0-0"]) : new Set(),
       allChoose: this.getText(0, 0, this.isDefaultSelected ? 0 : null),
       allChoose: this.getText(0, 0, this.isDefaultSelected ? 0 : null),
       list: [],
       list: [],
-      defIndex: 0
+      defIndex: 0,
     };
     };
   },
   },
   components: {
   components: {
     [nuttab.name]: nuttab,
     [nuttab.name]: nuttab,
-    [nutpop.name]: nutpop
+    [nutpop.name]: nutpop,
   },
   },
   watch: {
   watch: {
     show(val) {
     show(val) {
@@ -139,8 +144,8 @@ export default {
         this.allChoose = this.getText(0, 0, this.isDefaultSelected ? 0 : null);
         this.allChoose = this.getText(0, 0, this.isDefaultSelected ? 0 : null);
         this.emit();
         this.emit();
       },
       },
-      deep: true
-    }
+      deep: true,
+    },
   },
   },
   mounted() {
   mounted() {
     this.list = this.tabList;
     this.list = this.tabList;
@@ -196,7 +201,13 @@ export default {
     choose(idx, index, sIndex) {
     choose(idx, index, sIndex) {
       if (this.multiple && this.isActive(idx, index, sIndex)) {
       if (this.multiple && this.isActive(idx, index, sIndex)) {
         this.unChoose(index, sIndex);
         this.unChoose(index, sIndex);
-        this.allChoose.delete(this.getText(idx, index, sIndex));
+        this.getText(idx, index, sIndex).forEach((o) => {
+          for (let indexdel of this.allChoose.values()) {
+            if (JSON.stringify(o) === JSON.stringify(indexdel)) {
+              this.allChoose.delete(indexdel);
+            }
+          }
+        });
         this.emit();
         this.emit();
         return;
         return;
       }
       }
@@ -216,12 +227,9 @@ export default {
       }
       }
       this.emit();
       this.emit();
     },
     },
-    clickHandler (event) {
-      this.$emit(
-        "onOkBtn",
-        event
-      )
-      this.isShow = false
+    clickHandler(event) {
+      this.$emit("onOkBtn", event);
+      this.isShow = false;
     },
     },
     isActive(idx, index, sIndex) {
     isActive(idx, index, sIndex) {
       if (
       if (
@@ -232,7 +240,7 @@ export default {
         return true;
         return true;
       }
       }
       return false;
       return false;
-    }
-  }
+    },
+  },
 };
 };
 </script>
 </script>

+ 1 - 0
types/nutui.d.ts

@@ -78,3 +78,4 @@ export declare class TimeLineItem extends UIComponent {}
 export declare class SideNavBar extends UIComponent {}
 export declare class SideNavBar extends UIComponent {}
 export declare class SubSideNavBar extends UIComponent {}
 export declare class SubSideNavBar extends UIComponent {}
 export declare class SideNavBarItem extends UIComponent {}
 export declare class SideNavBarItem extends UIComponent {}
+export declare class Drag extends UIComponent {}