Browse Source

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

Your Name 5 years ago
parent
commit
f3b2ff0ae3

+ 5 - 5
src/config.json

@@ -556,13 +556,13 @@
     },
     {
       "version": "1.0.0",
-      "name": "TimeLine",
-      "chnName": "时间轴",
-      "desc": "对一系列数据进行展示,垂直展示",
+      "name": "CircleProgress",
+      "chnName": "圆形进度条",
+      "desc": "显示当前任务的操作进度",
       "type": "component",
-      "sort": "0",
+      "sort": "2",
       "showDemo": true,
-      "author": "yangxiaolu"
+      "author": "zyf"
     },
     {
       "version": "1.0.0",

+ 3 - 0
src/nutui.js

@@ -106,6 +106,8 @@ import Video from "./packages/video/index.js";
 import "./packages/video/video.scss";
 import Signature from "./packages/signature/index.js";
 import "./packages/signature/signature.scss";
+import CircleProgress from "./packages/circleprogress/index.js";
+import "./packages/circleprogress/circleprogress.scss";
 import TimeLine from "./packages/timeline/index.js";
 import "./packages/timeline/timeline.scss";
 import TimeLineItem from "./packages/timelineitem/index.js";
@@ -170,6 +172,7 @@ const packages = {
   LuckDraw: LuckDraw,
   Video: Video,
   Signature: Signature,
+  CircleProgress: CircleProgress,
   TimeLine: TimeLine,
   TimeLineItem: TimeLineItem,
   SideNavBar: SideNavBar,

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

@@ -0,0 +1,9 @@
+.nut-circleprogress{
+    position: relative;
+    .nut-circleprogress-content {
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%,-50%);
+    }
+}

+ 85 - 0
src/packages/circleprogress/circleprogress.vue

@@ -0,0 +1,85 @@
+<template>
+<div class="nut-circleprogress" :style="{height:option.size + 'px' , width:option.size + 'px'}">
+  <svg
+    :height="option.size"
+    :width="option.size"
+    x-mlns="http://www.w3.org/200/svg"
+  >
+    <circle
+      :r="option.radius"
+      :cx="option.cx"
+      :cy="option.cy"
+      :stroke="option.backColor"
+      :stroke-width="option.strokeOutWidth"
+      fill="none"
+    />
+    <circle
+      :r="option.radius"
+      :cx="option.cx"
+      :cy="option.cy"
+      :stroke="option.progressColor"
+      :stroke-dasharray="arcLength"
+      :stroke-width="strokeInnerWidth"
+      fill="none"
+      transform="rotate(-90)"
+      transform-origin="center"
+      stroke-linecap="round"
+      style="transition: stroke-dasharray 0.6s ease 0s, stroke 0.6s ease 0s;"
+    />
+  </svg>
+  <div class="nut-circleprogress-content">
+    <template v-if="!isAuto"><slot>{{progress}}%</slot></template>
+    <template v-else><slot></slot></template>
+  </div>
+  </div>
+</template>
+<script>
+export default {
+  name: 'nut-circleprogress',
+  props: {
+    progress: {
+      type: [Number , String ] ,
+      required: true,
+    },
+    strokeInnerWidth: {
+      type: [Number , String ] ,
+      default:10
+    },
+    isAuto: {
+      tyep: Boolean,
+      default:false
+    },
+    progressOption: {
+      type: Object,
+      default: () => { },
+    },
+  },
+  data () {
+    return {
+    }
+  },
+  computed: {
+    
+    arcLength () {
+      let circleLength = Math.floor(2 * Math.PI * this.option.radius)
+      let progressLength = (this.progress) / 100 * circleLength
+      // console.log(this.progress,progressLength)
+      return `${progressLength},${circleLength}`
+    },
+    option () {
+      // 所有进度条的可配置项
+      let baseOption = {
+        radius: 50,
+        strokeOutWidth: 10,
+        backColor: '#d9d9d9',
+        progressColor: 'red'
+      }
+      Object.assign(baseOption, this.progressOption)
+      // 圆心位置自动生成
+      baseOption.cy = baseOption.cx = baseOption.radius + baseOption.strokeOutWidth
+      baseOption.size = (baseOption.radius + baseOption.strokeOutWidth) * 2
+      return baseOption
+    },
+  },
+}
+</script>

+ 91 - 0
src/packages/circleprogress/demo.vue

@@ -0,0 +1,91 @@
+<template>
+  <div class="demo-list">
+    <p>基本用法</p>
+    <div>
+      <nut-cell>
+      <span slot="title">
+          <nut-circleprogress :progress="10">
+          </nut-circleprogress>
+      </span>
+      </nut-cell>
+    </div>
+    <p>环形进度条自定义样式</p>
+    <div>
+      <nut-cell>
+      <span slot="title">
+          <nut-circleprogress :progress="50" :progressOption="progressOption" >
+          </nut-circleprogress>
+      </span>
+      </nut-cell>
+    </div>
+    <p>环形进度条自定义内容</p>
+    <div>
+      <nut-cell>
+      <span slot="title">
+          <nut-circleprogress :progress="50" :isAuto="isAuto">
+            <slot>自定义</slot>
+          </nut-circleprogress>
+      </span>
+      </nut-cell>
+    </div>
+    <p>动态改变环形进度条的进度</p>
+    <div>
+      <nut-cell>
+        <span slot="title">
+          <nut-circleprogress :progress="percent"  :progressOption="progressOption" :strokeInnerWidth="strokeInnerWidth">
+            
+          </nut-circleprogress>
+        </span>
+      </nut-cell>
+      <nut-cell>
+        <span slot="title">
+          <nut-button type="default" shape="circle" @click="setReduceVal" small>减少</nut-button>
+          <nut-button type="red" shape="circle" @click="setAddVal" small>增加</nut-button>
+        </span>
+      </nut-cell>
+    </div>
+    
+  </div>
+</template>
+
+<script>
+export default {
+  components: {
+
+  },
+  data() {
+     return {
+        progressOption : {
+          radius: 50,
+          strokeOutWidth:10,
+          backColor: '#d9d9d9',
+          progressColor: 'red',
+        },
+        percent:50, 
+        strokeInnerWidth:10,
+        isAuto:true
+    }
+  },
+  methods: {
+    setAddVal() {
+      this.strokeInnerWidth = 10
+      if(this.percent  >= 100 ) {
+        return
+      }
+      this.percent += 10;
+    },
+    setReduceVal() {
+      if (this.percent - 10 <= 0) {
+        this.strokeInnerWidth = 0
+        this.percent = 0 
+        return;
+      }
+      this.percent -= 10;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 35 - 0
src/packages/circleprogress/doc.md

@@ -0,0 +1,35 @@
+## CirecleProgress 环形进度条
+
+显示任务的当前操作进度。
+
+## 基本用法
+
+```html
+    
+    <nut-circleprogress progress="10">
+    </nut-circleprogress>
+```
+## 环形进度条自定义样式
+
+```htmL
+    
+    <nut-circleprogress progress="50" :progressOption="progressOption">
+    </nut-circleprogress>
+```
+
+## 环形进度条自定义内容
+
+```htmL
+    
+    <nut-circleprogress progress="50" :isAuto="true">
+    </nut-circleprogress>
+```
+
+## Prop
+
+| 字段 | 说明 | 类型 | 默认值
+|----- | ----- | ----- | -----
+| progress | 百分比 | Number,String | 必传项,无默认值
+| strokeInnerWidth | 圆弧的宽度 | Number,String | 10
+| isAuto | 是否自定义内容显示 | Boolean | false
+| progressOption | 外圆相关参数对象,其中包括半径,宽度,背景颜色,进度色值 | Object | {radius: 50,strokeOutWidth: 10, backColor: '#d9d9d9',progressColor: 'red'}

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

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

+ 9 - 5
src/packages/infiniteloading/doc.md

@@ -1,4 +1,4 @@
-# InfiniteLoading 无限加载
+# Infiniteloading 无限加载
 列表滚动到底部自动加载更多数据。
 
 ## 基本用法
@@ -16,7 +16,7 @@
             class="list-item" 
             v-for="(item, index) of data" 
             :key="item"
-        >我是测试数据{{index + 1}}</li>
+        >我是测试数据{{index + 1} }</li>
     </ul>
 </nut-infiniteloading>
 ```
@@ -57,13 +57,17 @@ export default {
 
 | 字段 | 说明 | 类型 | 默认值
 |----- | ----- | ----- | -----
-| hasMore | 是否还有更多数据 | Boolean | true
-| isLoading | 是否加载中 | Boolean | false
+| has-more | 是否还有更多数据 | Boolean | true
+| is-loading | 是否加载中 | Boolean | false
 | threshold | 距离底部多远加载 | Number | 200
-| isShowMod | 是否展示懒加载模块内容,一般适用于选项卡切换 | Boolean | false
+| is-showMod | 是否展示懒加载模块内容,一般适用于选项卡切换 | Boolean | false
+| use-window | 将滚动侦听器添加到 window 否则侦听组件的父节点 | Boolean | true
+| use-capture | 是否使用捕获模式 true捕获 false冒泡 | Boolean | false
+| unload-more-txt | 没有更多数据展示文案 | String | 哎呀,这里是底部了啦
 
 ## Event
 
 | 字段 | 说明 | 回调参数
 |----- | ----- | -----
 | loadmore | 继续加载的回调函数 | -
+| scrollChange | 实时监听滚动高度 | 滚动高度

+ 35 - 11
src/packages/infiniteloading/infiniteloading.vue

@@ -10,7 +10,7 @@
                 <template v-if="isLoading" >
                    <i class="loading-hint"></i><span class="loading-txt">加载中...</span>
                 </template>
-                <span v-else-if="!hasMore" class="tips-txt">哎呀,这里是底部了啦</span>
+                <span v-else-if="!hasMore" class="tips-txt">{{unloadMoreTxt}}</span>
             </div>
         </div>
     </div>
@@ -35,9 +35,20 @@ export default {
             type: Boolean,
             default: true
         },
+        useCapture: {
+            type: Boolean,
+            default: false
+        },
         isShowMod: {
             type: Boolean,
             default: false
+        },
+        unloadMoreTxt: {
+            type: String,
+            default: "哎呀,这里是底部了啦"
+        },
+        scrollChange:{
+            type:Function
         }
     },
     data() {
@@ -51,6 +62,12 @@ export default {
     },
 
     mounted: function () {
+        const parentElement = this.getParentElement(this.$el);
+        let scrollEl = window;
+        if (this.useWindow === false) {
+            scrollEl = parentElement;
+        }
+        this.scrollEl = scrollEl;
         this.scrollListener();
     },
 
@@ -69,10 +86,12 @@ export default {
             this.diffX = endX - this.startX;
             this.diffY = endY - this.startY;
         },
-
+         getParentElement(el) {
+            return el && el.parentNode;
+        },
         scrollListener() {
-            window.addEventListener('scroll', this.handleScroll, false);
-            window.addEventListener('resize', this.handleScroll, false);
+            this.scrollEl.addEventListener('scroll', this.handleScroll, this.useCapture);
+            window.addEventListener('resize', this.handleScroll, this.useCapture);
         },
 
         requestAniFrame() {
@@ -88,7 +107,7 @@ export default {
 
         handleScroll() {
             this.requestAniFrame()(() => {
-                if (!this.hasMore || !this.isScrollAtBottom() || this.isLoading || !this.isShowMod) {
+                if (!this.isScrollAtBottom() || !this.hasMore || this.isLoading || !this.isShowMod) {
                     return false;
                 } else {
                     this.$emit('loadmore');
@@ -113,7 +132,10 @@ export default {
         isScrollAtBottom() {
             let offsetDistance;
             
+            let resScrollTop = 0;
+
             const windowScrollTop = this.getWindowScrollTop();
+
             if (this.useWindow) {
                 offsetDistance =
                     this.calculateTopPosition(this.$refs.scroller) +
@@ -124,10 +146,12 @@ export default {
                     scrollHeight,
                     clientHeight,
                     scrollTop
-                } = this.$refs.scroller;
+                } = this.scrollEl;
+
                 offsetDistance = scrollHeight - clientHeight - scrollTop;
+                resScrollTop = scrollTop;
             }
-            
+            this.$emit('scrollChange',this.useWindow?windowScrollTop :resScrollTop);
             // 保证是往下滑动的
             let beforeScrollTop = this.beforeScrollTop;
             this.beforeScrollTop = windowScrollTop;
@@ -145,13 +169,13 @@ export default {
 
     deactivated() {
         this.keepAlive = true;
-        window.removeEventListener('scroll', this.handleScroll, false);
-        window.removeEventListener('resize', this.handleScroll, false);
+        this.scrollEl.removeEventListener('scroll', this.handleScroll, this.useCapture);
+        window.removeEventListener('resize', this.handleScroll, this.useCapture);
     },
 
     destroyed() {
-        window.removeEventListener('scroll', this.handleScroll, false);
-        window.removeEventListener('resize', this.handleScroll, false);
+        this.scrollEl.removeEventListener('scroll', this.handleScroll, this.useCapture);
+        window.removeEventListener('resize', this.handleScroll, this.useCapture);
     }
 }
 </script>

+ 184 - 146
src/packages/textinput/demo.vue

@@ -1,174 +1,212 @@
 <template>
-  <div class="textinput-demo">
+    <div class="textinput-demo">
+        <h4>基本用法</h4>
+        <div>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput v-model="val" label="基本用法:" placeholder="请输入内容" />
+                </span>
+            </nut-cell>
+            <nut-cell>
+                <span slot="title">Value值: {{val}}</span>
+            </nut-cell>
+        </div>
+        <h4>配置</h4>
+        <div>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput
+                        :clearBtn="false"
+                        v-model="val2"
+                        label="无清空按钮:"
+                        placeholder="请输入内容"
+                    />
+                </span>
+            </nut-cell>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput :disabled="true" label="禁用状态:" placeholder="请输入内容" />
+                </span>
+            </nut-cell>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput placeholder="请输入密码" v-model="val3" label="密码框:" type="password" />
+                </span>
+            </nut-cell>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput
+                        placeholder="请输入内容"
+                        v-model="val4"
+                        label="无边框:"
+                        :hasBorder="false"
+                    />
+                </span>
+            </nut-cell>
+        </div>
+        <h4>使用input原生属性</h4>
+        <div>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput
+                        placeholder="maxlength=5"
+                        maxlength="5"
+                        label="限制文字数:"
+                        :outline="false"
+                        :hasBorder="false"
+                    />
+                </span>
+            </nut-cell>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput
+                        placeholder="请输入内容"
+                        v-model="val5"
+                        readonly
+                        label="只读:"
+                        :outline="false"
+                    />
+                </span>
+            </nut-cell>
+        </div>
 
-    <h4>基本用法</h4>
-    <div>
-      <nut-cell>
-        <span slot="title">
-          <nut-textinput v-model="val" label="基本用法:" placeholder="请输入内容" />
-        </span>
-      </nut-cell>
-      <nut-cell>
-        <span slot="title">Value值: {{val}}</span>
-      </nut-cell>
-    </div>
-    <h4>配置</h4>
-    <div>
-      <nut-cell>
-        <span slot="title">
-          <nut-textinput :clearBtn="false" v-model="val2" label="无清空按钮:" placeholder="请输入内容" />
-        </span>
-      </nut-cell>
-      <nut-cell>
-        <span slot="title">
-          <nut-textinput :disabled="true" label="禁用状态:" placeholder="请输入内容" />
-        </span>
-      </nut-cell>
-      <nut-cell>
-        <span slot="title">
-          <nut-textinput placeholder="请输入密码" v-model="val3" label="密码框:" type="password" />
-        </span>
-      </nut-cell>
-      <nut-cell>
-        <span slot="title">
-          <nut-textinput placeholder="请输入内容" v-model="val4" label="无边框:" :hasBorder="false" />
-        </span>
-      </nut-cell>
-    </div>
-    <h4>使用input原生属性</h4>
-    <div>
-      <nut-cell>
-        <span slot="title">
-          <nut-textinput
-            placeholder="maxlength=5"
-            maxlength="5"
-            label="限制文字数:"
-            :outline="false"
-            :hasBorder="false"
-          />
-        </span>
-      </nut-cell>
-      <nut-cell>
-        <span slot="title">
-          <nut-textinput placeholder="请输入内容" v-model="val5" readonly label="只读:" :outline="false" />
-        </span>
-      </nut-cell>
-    </div>
-    
-    <h4>使用input原生事件</h4>
-    <div>
-      <nut-cell>
-        <span slot="title">
-          <nut-textinput
-            placeholder="请输入内容"
-            label="focus/blur事件:"
-            @focus="onFocus"
-            @blur="onBlur"
-            v-model="val6"
-            :hasBorder="false"
-          />
-        </span>
-      </nut-cell>
-      <nut-cell>
-        <span slot="title">事件触发结果:{{result}}</span>
-      </nut-cell>
-    </div>
-    <h4>自定义Class</h4>
-    <div>
-      <nut-cell>
-        <span slot="title">
-          <nut-textinput class="my-input" v-model="val7" placeholder="请输入搜索内容" />
-        </span>
-      </nut-cell>
-    </div>
-    
-    <h4>自动聚焦</h4>
-    <div class="autoFucus">
-      <nut-textinput  class="my-input" type="search" v-model="val8"  placeholder="请输入搜索内容" ref="myInput" @keyup.enter="submit" />
+        <h4>使用input原生事件</h4>
+        <div>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput
+                        placeholder="请输入内容"
+                        label="focus/blur事件:"
+                        @focus="onFocus"
+                        @blur="onBlur"
+                        v-model="val6"
+                        :hasBorder="false"
+                    />
+                </span>
+            </nut-cell>
+            <nut-cell>
+                <span slot="title">事件触发结果:{{result}}</span>
+            </nut-cell>
+        </div>
+        <h4>自定义Class</h4>
+        <div>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput class="my-input" v-model="val7" placeholder="请输入搜索内容"></nut-textinput>
+                </span>
+            </nut-cell>
+        </div>
+        <h4>自定义关闭按钮样式</h4>
+        <div>
+            <nut-cell>
+                <span slot="title">
+                    <nut-textinput
+                        class="my-input"
+                        v-model="val9"
+                        placeholder="请输入搜索内容"
+                        :clearBtnPersonnal="true"
+                    >
+                        <template v-slot:clearBtn>
+                            <nut-icon type="cross"></nut-icon>
+                        </template>
+                    </nut-textinput>
+                </span>
+            </nut-cell>
+        </div>
+        <h4>自动聚焦</h4>
+        <div class="autoFucus">
+            <nut-textinput
+                class="my-input"
+                type="search"
+                v-model="val8"
+                placeholder="请输入搜索内容"
+                ref="myInput"
+                @keyup.enter="submit"
+            />
 
-      <div class="searchBtn" @click="submit">搜索</div>
+            <div class="searchBtn" @click="submit">搜索</div>
+        </div>
     </div>
-  </div>
 </template>
 
 <script>
 export default {
-  data() {
-    return {
-      val: "",
-      val2: "",
-      val3: "",
-      val4: "",
-      val5: "我使用了readonly原生属性",
-      val6: "",
-      val7: "",
-      val8: "",
-      result: "尚未触发"
-    };
-  },
-
-  mounted() {
-    const th = this
-			this.$nextTick(function() {
-				setTimeout(function() {
-					th.$refs.myInput.focus()
-				}, 2000)
-				
-			})
-  },
-  methods: {
-    onFocus() {
-      this.result = "focus事件触发!";
+    data() {
+        return {
+            val: "",
+            val2: "",
+            val3: "",
+            val4: "",
+            val5: "我使用了readonly原生属性",
+            val6: "",
+            val7: "",
+            val8: "",
+            val9: "",
+            result: "尚未触发"
+        };
     },
-    onBlur() {
-      this.result = "blur事件触发!";
+
+    mounted() {
+        const th = this;
+        this.$nextTick(function() {
+            setTimeout(function() {
+                th.$refs.myInput.focus();
+            }, 2000);
+        });
     },
+    methods: {
+        onFocus() {
+            this.result = "focus事件触发!";
+        },
+        onBlur() {
+            this.result = "blur事件触发!";
+        },
 
-    submit() {
-        this.$refs.myInput.blur()
+        submit() {
+            this.$refs.myInput.blur();
+        }
     }
-  }
 };
 </script>
 
 <style lang="scss">
 .textinput-demo {
-  padding-left: 0;
-  padding-right: 0;
+    padding-left: 0;
+    padding-right: 0;
 }
 .textinput-demo h4 {
-  padding: 0 10px;
+    padding: 0 10px;
 }
 
-.autoFucus{
-  background: #fff;
-  padding: 10px;
+.autoFucus {
+    background: #fff;
+    padding: 10px;
 
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
 
-  .my-input{
-    flex: 1;
-  }
-  .searchBtn{
-    margin-left: 10px;
-  }
+    .my-input {
+        flex: 1;
+    }
+    .searchBtn {
+        margin-left: 10px;
+    }
 }
 .nut-textinput {
-  &.my-input {
-    input {
-      height: 36px;
-      border-radius: 20px;
-      padding-left: 40px;
-      padding-right: 40px;
-      background: url("data:image/svg+xml, %3Csvg version='1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M15.8 14.3l-3.3-3.1c1-1.1 1.6-2.6 1.6-4.1 0-3.6-3.1-6.6-7-6.6s-7 3-7 6.6c0 3.6 3.1 6.6 7 6.6 1.7 0 3.2-.6 4.4-1.5l3.3 3.1c.1.1.3.2.5.2s.4-.1.5-.2c.3-.3.3-.7 0-1zM1.5 7.1c0-2.9 2.5-5.2 5.6-5.2 3.1 0 5.6 2.3 5.6 5.2 0 2.9-2.5 5.2-5.6 5.2-3.2 0-5.6-2.3-5.6-5.2z' fill-rule='evenodd' clip-rule='evenodd' fill='%23999999'/%3E%3C/svg%3E")
-        no-repeat 10px center;
-      background-size: 18px;
-    }
-    .nut-textinput-clear {
-      right: 15px;
+    &.my-input {
+        input {
+            height: 36px;
+            border-radius: 20px;
+            padding-left: 40px;
+            padding-right: 40px;
+            background: url("data:image/svg+xml, %3Csvg version='1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M15.8 14.3l-3.3-3.1c1-1.1 1.6-2.6 1.6-4.1 0-3.6-3.1-6.6-7-6.6s-7 3-7 6.6c0 3.6 3.1 6.6 7 6.6 1.7 0 3.2-.6 4.4-1.5l3.3 3.1c.1.1.3.2.5.2s.4-.1.5-.2c.3-.3.3-.7 0-1zM1.5 7.1c0-2.9 2.5-5.2 5.6-5.2 3.1 0 5.6 2.3 5.6 5.2 0 2.9-2.5 5.2-5.6 5.2-3.2 0-5.6-2.3-5.6-5.2z' fill-rule='evenodd' clip-rule='evenodd' fill='%23999999'/%3E%3C/svg%3E")
+                no-repeat 10px center;
+            background-size: 18px;
+        }
+        .nut-textinput-clear {
+            right: 15px;
+        }
     }
-  }
 }
 </style>

+ 24 - 9
src/packages/textinput/doc.md

@@ -63,6 +63,19 @@
 />
 ```
 
+自定义关闭按钮样式
+```html
+<nut-textinput
+    class="my-input"
+    v-model="val7"
+    placeholder="请输入搜索内容"
+    :clearBtnPersonnal="true"
+>
+    <template v-slot:clearBtn>
+        <nut-icon type="cross"></nut-icon>
+    </template>
+</nut-textinput>
+```
 自动聚焦
 
 注:由于移动设备的不同,第一次自动获取焦点并不一定能吊起键盘,需要手动吊起来一次,当再次进入时则正常吊起键盘
@@ -106,15 +119,17 @@ export default {
 
 ## Prop
 
-| 字段 | 说明 | 类型 | 默认值
-|----- | ----- | ----- | ----- 
-| value | 当前input值,可使用 v-model 双向绑定数据 | String | ''
-| type | input输入框的类型 | String | 'text'
-| placeholder | 占位文本 | String | ''
-| label | 文本框前面的标签 | String | ''
-| disabled | 是否禁用 | Boolean | false
-| clear-btn | 是否需要清空按钮 | Boolean | true
-| has-border | 是否需要边框 | Boolean | true
+| 字段              | 说明                                                                                     | 类型    | 默认值 |
+| ----------------- | ---------------------------------------------------------------------------------------- | ------- | ------ |
+| value             | 当前input值,可使用 v-model 双向绑定数据                                                 | String  | ''     |
+| type              | input输入框的类型                                                                        | String  | 'text' |
+| placeholder       | 占位文本                                                                                 | String  | ''     |
+| label             | 文本框前面的标签                                                                         | String  | ''     |
+| disabled          | 是否禁用                                                                                 | Boolean | false  |
+| clear-btn         | 是否需要清空按钮                                                                         | Boolean | true   |
+| has-border        | 是否需要边框                                                                             | Boolean | true   |
+| clearBtnPersonnal | 是否需要定制化清除按钮,如果是true,需要配合slot:  clearBtn使用,如案例自定义关闭按钮样式 | Boolean | false  |
+
 
 ## 特殊说明 
 

+ 99 - 89
src/packages/textinput/textinput.vue

@@ -1,102 +1,112 @@
 <template>
-  <form action="javascript:return true" :class="['nut-textinput',{'nut-textinput-disabled':disabled}]">
-    
-      <span class="nut-textinput-label" v-if="label">{{label}}</span>
-      <input
-        :type="type"
-        :placeholder="placeholder"
-        :value="value"
-        :disabled="disabled"
-        ref='nutUiInput'
-        :style="{'borderWidth':hasBorder?'':0,'outline':outline?'':'none','padding-right':clearBtn?'':'10px'}"
-        v-bind="$attrs"
-        v-on="inputListeners"
-        
-      />
-      <span class="nut-textinput-clear" v-if="clearBtn" v-show="clearBtnShow" @click="clear">
-        <svg version="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
-          <path
-            d="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm2.8 9.7c.3.3.3.8 0 1.1s-.8.3-1.1 0L8 9.1l-1.7 1.7c-.3.3-.8.3-1.1 0-.3-.3-.3-.8 0-1.1L6.9 8 5.2 6.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0L8 6.9l1.7-1.7c.3-.3.8-.3 1.1 0 .3.3.3.8 0 1.1L9.1 8l1.7 1.7z"
-          ></path>
-        </svg>
-      </span>
-  </form>
+    <form
+        action="javascript:return true"
+        :class="['nut-textinput',{'nut-textinput-disabled':disabled}]"
+    >
+        <span class="nut-textinput-label" v-if="label">{{label}}</span>
+        <input
+            :type="type"
+            :placeholder="placeholder"
+            :value="value"
+            :disabled="disabled"
+            ref="nutUiInput"
+            :style="{'borderWidth':hasBorder?'':0,'outline':outline?'':'none','padding-right':clearBtn?'':'10px'}"
+            v-bind="$attrs"
+            v-on="inputListeners"
+        />
+        <span class="nut-textinput-clear" v-if="clearBtn" v-show="clearBtnShow" @click="clear">
+            <svg
+                version="1"
+                xmlns="http://www.w3.org/2000/svg"
+                viewBox="0 0 16 16"
+                v-if="!clearBtnPersonnal"
+            >
+                <path
+                    d="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm2.8 9.7c.3.3.3.8 0 1.1s-.8.3-1.1 0L8 9.1l-1.7 1.7c-.3.3-.8.3-1.1 0-.3-.3-.3-.8 0-1.1L6.9 8 5.2 6.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0L8 6.9l1.7-1.7c.3-.3.8-.3 1.1 0 .3.3.3.8 0 1.1L9.1 8l1.7 1.7z"
+                />
+            </svg>
+            <slot name="clearBtn" v-else></slot>
+        </span>
+    </form>
 </template>
 <script>
 export default {
-  name: "nut-textinput",
-  props: {
-    value: {
-      type: String,
-      default: ""
-    },
-    type: {
-      type: String,
-      default: "text"
-    },
-    label: {
-      type: String,
-      default: ""
-    },
-    placeholder:{
-      type: String,
-      default: ""
-    },
-    
-    disabled: {
-      type: Boolean,
-      default: false
-    },
-    hasBorder: {
-      type: Boolean,
-      default: true
+    name: "nut-textinput",
+    props: {
+        value: {
+            type: String,
+            default: ""
+        },
+        type: {
+            type: String,
+            default: "text"
+        },
+        label: {
+            type: String,
+            default: ""
+        },
+        placeholder: {
+            type: String,
+            default: ""
+        },
+
+        disabled: {
+            type: Boolean,
+            default: false
+        },
+        hasBorder: {
+            type: Boolean,
+            default: true
+        },
+        outline: {
+            type: Boolean,
+            default: false
+        },
+        clearBtn: {
+            type: Boolean,
+            default: true
+        },
+        clearBtnPersonnal: {
+            type: Boolean,
+            default: false
+        }
     },
-    outline: {
-      type: Boolean,
-      default: false
+    computed: {},
+    data() {
+        return {
+            clearBtnShow: false
+        };
     },
-    clearBtn: {
-      type: Boolean,
-      default: true
-    }
-  },
-  computed: {},
-  data() {
-    return {
-      clearBtnShow: false
-    };
-  },
-  computed: {
-    inputListeners() {
-      let vm = this;
-      return Object.assign({}, this.$listeners, {
-        input: function(event) {
-          vm.clearBtnShow = !!event.target.value;
-          vm.$emit("input", event.target.value);
+    computed: {
+        inputListeners() {
+            let vm = this;
+            return Object.assign({}, this.$listeners, {
+                input: function(event) {
+                    vm.clearBtnShow = !!event.target.value;
+                    vm.$emit("input", event.target.value);
+                }
+            });
         }
-      });
-    }
-  },
-
-  methods: {
-    clear() {
-      this.$emit("input", "");
-      this.clearBtnShow = false;
     },
 
-    focus() {
-      this.$nextTick(function() {
-        this.$refs.nutUiInput.focus()
-      })
-    },
+    methods: {
+        clear() {
+            this.$emit("input", "");
+            this.clearBtnShow = false;
+        },
 
-    blur() {
-      this.$refs.nutUiInput.blur()
-    }
-  },
-  mounted() {
-    this.clearBtnShow = !!this.value;
+        focus() {
+            this.$nextTick(function() {
+                this.$refs.nutUiInput.focus();
+            });
+        },
 
-  }
+        blur() {
+            this.$refs.nutUiInput.blur();
+        }
+    },
+    mounted() {
+        this.clearBtnShow = !!this.value;
+    }
 };
 </script>

+ 1 - 0
types/nutui.d.ts

@@ -72,6 +72,7 @@ export declare class Popup extends UIComponent {}
 export declare class LuckDraw extends UIComponent {}
 export declare class Video extends UIComponent {}
 export declare class Signature extends UIComponent {}
+export declare class CircleProgress extends UIComponent {}
 export declare class TimeLine extends UIComponent {}
 export declare class TimeLineItem extends UIComponent {}
 export declare class SideNavBar extends UIComponent {}