ソースを参照

feat: 新增TextInput组件

Frans 6 年 前
コミット
dfb9046682

+ 3 - 1
build/webpack.test.conf.js

@@ -1,4 +1,5 @@
 
 
+const path = require('path');
 const prodConf = require('./webpack.prod.conf.js');
 const prodConf = require('./webpack.prod.conf.js');
 const merge = require('webpack-merge');
 const merge = require('webpack-merge');
 
 
@@ -11,7 +12,8 @@ module.exports = merge(prodConf, {
                 use: {
                 use: {
                     loader: 'istanbul-instrumenter-loader',
                     loader: 'istanbul-instrumenter-loader',
                     options: { esModules: true }
                     options: { esModules: true }
-                }
+                },
+                include: path.resolve(__dirname, '../src/')
             },
             },
             {
             {
                 test: /\.css$/,
                 test: /\.css$/,

+ 10 - 0
src/config.json

@@ -442,6 +442,16 @@
       "sort": "5",
       "sort": "5",
       "showDemo": true,
       "showDemo": true,
       "author": "林如风"
       "author": "林如风"
+    },
+    {
+      "version": "1.0.0",
+      "name": "TextInput",
+      "chnName": "文本框",
+      "desc": "单行文本框",
+      "type": "component",
+      "sort": "1",
+      "showDemo": true,
+      "author": "Frans"
     }
     }
   ]
   ]
 }
 }

+ 4 - 1
src/nutui.js

@@ -85,6 +85,8 @@ import InfiniteLoading from './packages/infiniteloading/index.js';
 import './packages/infiniteloading/infiniteloading.scss';
 import './packages/infiniteloading/infiniteloading.scss';
 import Uploader from "./packages/uploader/index.js";
 import Uploader from "./packages/uploader/index.js";
 import "./packages/uploader/uploader.scss";
 import "./packages/uploader/uploader.scss";
+import TextInput from "./packages/textinput/index.js";
+import "./packages/textinput/textinput.scss";
 
 
 const packages = {
 const packages = {
   Cell,
   Cell,
@@ -128,7 +130,8 @@ const packages = {
   BackTop,
   BackTop,
   CountDown,
   CountDown,
   InfiniteLoading,
   InfiniteLoading,
-  Uploader
+  Uploader,
+  TextInput
 };
 };
 
 
 const components = {};
 const components = {};

+ 135 - 0
src/packages/textinput/demo.vue

@@ -0,0 +1,135 @@
+<template>
+  <div class="textinput-demo">
+    <h4>基本用法</h4>
+    <div>
+      <nut-cell>
+        <span slot="title">
+          <nut-textinput v-model="val" label="基本用法:" placeholder="请输入内容"></nut-textinput>
+        </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="请输入内容"></nut-textinput>
+        </span>
+      </nut-cell>
+      <nut-cell>
+        <span slot="title">
+          <nut-textinput :disabled="true" label="禁用状态:" placeholder="请输入内容"></nut-textinput>
+        </span>
+      </nut-cell>
+      <nut-cell>
+        <span slot="title">
+          <nut-textinput placeholder="请输入密码" v-model="val3" label="密码框:" type="password"></nut-textinput>
+        </span>
+      </nut-cell>
+      <nut-cell>
+        <span slot="title">
+          <nut-textinput placeholder="请输入内容" v-model="val4" label="无边框:" :hasBorder="false"></nut-textinput>
+        </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"
+          ></nut-textinput>
+        </span>
+      </nut-cell>
+      <nut-cell>
+        <span slot="title">
+          <nut-textinput placeholder="请输入内容" v-model="val5" readonly label="只读:" :outline="false"></nut-textinput>
+        </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"
+          ></nut-textinput>
+        </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>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      val: "",
+      val2: "",
+      val3: "",
+      val4: "",
+      val5: "我使用了readonly原生属性",
+      val6: "",
+      val7: "",
+      result: "尚未触发"
+    };
+  },
+  methods: {
+    onFocus() {
+      this.result = "focus事件触发!";
+    },
+    onBlur() {
+      this.result = "blur事件触发!";
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+.textinput-demo {
+  padding-left: 0;
+  padding-right: 0;
+}
+.textinput-demo h4 {
+  padding: 0 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;
+    }
+  }
+}
+</style>

+ 23 - 0
src/packages/textinput/doc.md

@@ -0,0 +1,23 @@
+# TextInput 文本框
+
+单行文本框。
+
+## 基本用法
+
+```html
+<nut-textinput 
+    v-model="val"
+    label="无清空按钮:"
+    placeholder="请输入内容"
+    :clearBtn="false"
+    :hasBorder="true"
+    >
+</nut-textinput>
+```
+
+
+
+## Prop
+
+| 字段 | 说明 | 类型 | 默认值
+|----- | ----- | ----- | ----- 

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

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

+ 47 - 0
src/packages/textinput/textinput.scss

@@ -0,0 +1,47 @@
+.nut-textinput {
+    display: flex;
+    align-items: center;
+    position: relative;
+
+    input {
+        flex: 1;
+        height: 40px;
+        appearance: none;
+        font-size: 14px;
+        box-sizing: border-box;
+        border-radius: 4px;
+        border: 1px solid #DDDFE6;
+        background-color: '#FFFFFF';
+        padding: 0 30px 0 10px;
+
+        &::-webkit-input-placeholder {
+            color: #C1C4CB;
+            font-style: normal;
+        }
+    }
+
+    .nut-textinput-clear {
+        position: absolute;
+        right: 5px;
+        top: 50%;
+        transform: translateY(-50%);
+        height: 20px;
+        width: 20px;
+
+        svg {
+            fill: #999999;
+        }
+    }
+}
+
+.nut-textinput-disabled {
+    input {
+        background-color: #F5F7FA;
+        border-color: #E5E7ED;
+        color: #999999;
+
+        &::-webkit-input-placeholder {
+            color: #D1D3D9;
+        }
+    }
+}

+ 81 - 0
src/packages/textinput/textinput.vue

@@ -0,0 +1,81 @@
+<template>
+  <label :class="['nut-textinput',{'nut-textinput-disabled':disabled}]">
+    <span class="nut-textinput-label" v-if="label">{{label}}</span>
+    <input
+      :type="type"
+      :value="value"
+      :disabled="disabled"
+      :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>
+  </label>
+</template>
+<script>
+export default {
+  name: "nut-textinput",
+  props: {
+    value: {
+      type: String,
+      default: ""
+    },
+    type: {
+      type: String,
+      default: "text"
+    },
+    label: {
+      type: String,
+      default: ""
+    },
+    disabled: {
+      type: Boolean,
+      default: false
+    },
+    hasBorder: {
+      type: Boolean,
+      default: true
+    },
+    outline: {
+      type: Boolean,
+      default: 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);
+        }
+      });
+    }
+  },
+  methods: {
+    clear() {
+      this.$emit("input", "");
+      this.clearBtnShow = false;
+    }
+  },
+  mounted() {
+    this.clearBtnShow = !!this.value;
+  }
+};
+</script>

+ 1 - 0
types/nutui.d.ts

@@ -59,3 +59,4 @@ export declare class BackTop extends UIComponent {}
 export declare class Scroller extends UIComponent {}
 export declare class Scroller extends UIComponent {}
 export declare class CountDown extends UIComponent {}
 export declare class CountDown extends UIComponent {}
 export declare class Uploader extends UIComponent {}
 export declare class Uploader extends UIComponent {}
+export declare class TextInput extends UIComponent {}