浏览代码

input组件优化:合并template代码 (#1890)

ailululu 3 年之前
父节点
当前提交
79cfba063e

+ 18 - 21
src/packages/__VUE/input/demo.vue

@@ -137,8 +137,9 @@
       @clear="clear"
       @clear="clear"
       @click="click"
       @click="click"
       @click-input="clickInput"
       @click-input="clickInput"
+      @click-left-icon="clickLeftIcon"
+      @click-right-icon="clickRightIcon"
     />
     />
-    <nut-icon @click="click1" name="dongdong"></nut-icon>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -261,32 +262,29 @@ export default createDemo({
     setTimeout(function () {
     setTimeout(function () {
       // state.val1 = '异步数据';
       // state.val1 = '异步数据';
     }, 2000);
     }, 2000);
-    const change = (value: string | number) => {
+    const change = (value: string) => {
       console.log('change: ', value);
       console.log('change: ', value);
     };
     };
-    const focus = (value: string | number, event: Event) => {
-      console.log('focus:', value, event);
+    const focus = (event: Event) => {
+      console.log('focus:', event);
     };
     };
-    const blur = (value: string | number, event: Event) => {
-      console.log('blur:', value, event);
+    const blur = (event: Event) => {
+      console.log('blur:', event);
     };
     };
-    const clear = (value: string | number, event: Event) => {
-      console.log('clear:', value, event);
+    const clear = (event: Event) => {
+      console.log('clear:', event);
     };
     };
-    const click = (value: string | number) => {
-      console.log('click1:', value);
+    const click = (event: Event) => {
+      console.log('click:', event);
     };
     };
-    const click1 = (value: string | number) => {
-      console.log('click1111:', value);
+    const clickInput = (event: Event) => {
+      console.log('clickInput:', event);
     };
     };
-    const clickInput = (value: string | number) => {
-      console.log('clickInput:', value);
+    const clickLeftIcon = (event: Event) => {
+      console.log('clickLeftIcon:', event);
     };
     };
-    const clickLeftIcon = (value: string | number) => {
-      console.log('clickLeftIcon:', value);
-    };
-    const clickRightIcon = (value: string | number) => {
-      console.log('clickRightIcon:', value);
+    const clickRightIcon = (event: Event) => {
+      console.log('clickRightIcon:', event);
     };
     };
     const formatter = (value: string) => value.replace(/\d/g, '');
     const formatter = (value: string) => value.replace(/\d/g, '');
 
 
@@ -301,8 +299,7 @@ export default createDemo({
       clickLeftIcon,
       clickLeftIcon,
       clickRightIcon,
       clickRightIcon,
       formatter,
       formatter,
-      translate,
-      click1
+      translate
     };
     };
   }
   }
 });
 });

+ 22 - 22
src/packages/__VUE/input/doc.en-US.md

@@ -455,29 +455,29 @@ Use `label-align` prop to align the label, `input-align` prop to align the input
       const state = reactive({
       const state = reactive({
         event: ''
         event: ''
       });
       });
-      const change = (value: string | number) => {
+      const change = (value: string) => {
         console.log('change: ', value);
         console.log('change: ', value);
       };
       };
-      const focus = (value: string | number, event: Event) => {
-        console.log('focus:', value, event);
+      const focus = (event: Event) => {
+        console.log('focus:', event);
       };
       };
-      const blur = (value: string | number, event: Event) => {
-        console.log('blur:', value, event);
+      const blur = (event: Event) => {
+        console.log('blur:', event);
       };
       };
-      const clear = (value: string | number, event: Event) => {
-        console.log('clear:', value, event);
+      const clear = (event: Event) => {
+        console.log('clear:', event);
       };
       };
-      const click = (value: string | number) => {
-        console.log('click:', value);
+      const click = (event: Event) => {
+        console.log('click:', event);
       };
       };
-      const clickInput = (value: string | number) => {
-        console.log('clickInput:', value);
+      const clickInput = (event: Event) => {
+        console.log('clickInput:', event);
       };
       };
-      const clickLeftIcon = (value: string | number) => {
-        console.log('clickLeftIcon:', value);
+      const clickLeftIcon = (event: Event) => {
+        console.log('clickLeftIcon:', event);
       };
       };
-      const clickRightIcon = (value: string | number) => {
-        console.log('clickRightIcon:', value);
+      const clickRightIcon = (event: Event) => {
+        console.log('clickRightIcon:', event);
       };
       };
 
 
       return {
       return {
@@ -539,13 +539,13 @@ Use `label-align` prop to align the label, `input-align` prop to align the input
 | Event   | Description      | Arguments    |
 | Event   | Description      | Arguments    |
 |--------|----------------|-------------|
 |--------|----------------|-------------|
 | update:model-value | Emitted when input value changed | val  |
 | update:model-value | Emitted when input value changed | val  |
-| focus  | Emitted when input is focused     | val  ,event |
-| blur   | Emitted when input is blurred     | val ,event  |
-| clear  | Emitted when the clear icon is clicked   | val ,event  |
-| click  | Emitted when component is clicked	      | val ,event  |
-| click-input      | Emitted when the input is clicked      | val ,event  |
-| click-left-icon  | Emitted when the left icon is clicked      | val ,event  |
-| click-right-icon | Emitted when the right icon is clicked      | val ,event  |
+| focus  | Emitted when input is focused     | event |
+| blur   | Emitted when input is blurred     | event  |
+| clear  | Emitted when the clear icon is clicked   | event  |
+| click  | Emitted when component is clicked	      | event  |
+| click-input      | Emitted when the input is clicked      | event  |
+| click-left-icon  | Emitted when the left icon is clicked      | event  |
+| click-right-icon | Emitted when the right icon is clicked      | event  |
 
 
 ### Slots
 ### Slots
 
 

+ 22 - 22
src/packages/__VUE/input/doc.md

@@ -458,29 +458,29 @@ app.use(Icon);
       const state = reactive({
       const state = reactive({
         event: ''
         event: ''
       });
       });
-      const change = (value: string | number) => {
+      const change = (value: string) => {
         console.log('change: ', value);
         console.log('change: ', value);
       };
       };
-      const focus = (value: string | number, event: Event) => {
-        console.log('focus:', value, event);
+      const focus = (event: Event) => {
+        console.log('focus:', event);
       };
       };
-      const blur = (value: string | number, event: Event) => {
-        console.log('blur:', value, event);
+      const blur = (event: Event) => {
+        console.log('blur:', event);
       };
       };
-      const clear = (value: string | number, event: Event) => {
-        console.log('clear:', value, event);
+      const clear = (event: Event) => {
+        console.log('clear:', event);
       };
       };
-      const click = (value: string | number) => {
-        console.log('click:', value);
+      const click = (event: Event) => {
+        console.log('click:', event);
       };
       };
-      const clickInput = (value: string | number) => {
-        console.log('clickInput:', value);
+      const clickInput = (event: Event) => {
+        console.log('clickInput:', event);
       };
       };
-      const clickLeftIcon = (value: string | number) => {
-        console.log('clickLeftIcon:', value);
+      const clickLeftIcon = (event: Event) => {
+        console.log('clickLeftIcon:', event);
       };
       };
-      const clickRightIcon = (value: string | number) => {
-        console.log('clickRightIcon:', value);
+      const clickRightIcon = (event: Event) => {
+        console.log('clickRightIcon:', event);
       };
       };
 
 
       return {
       return {
@@ -542,13 +542,13 @@ app.use(Icon);
 | 名称   | 说明           | 回调参数    |
 | 名称   | 说明           | 回调参数    |
 |--------|----------------|-------------|
 |--------|----------------|-------------|
 | update:model-value | 输入框内容变化时触发 | val  |
 | update:model-value | 输入框内容变化时触发 | val  |
-| focus  | 输入框聚焦时触发     | val  ,event |
-| blur   | 输入框失焦时触发     | val ,event  |
-| clear  | 点击清除按钮时触发   | val ,event  |
-| click  | 点击组件时触发      | val ,event  |
-| click-input      | 点击输入区域时触发      | val ,event  |
-| click-left-icon  | 点击左侧图标时触发      | val ,event  |
-| click-right-icon | 点击右侧图标时触发      | val ,event  |
+| focus  | 输入框聚焦时触发     | event |
+| blur   | 输入框失焦时触发     | event  |
+| clear  | 点击清除按钮时触发   | event  |
+| click  | 点击组件时触发      | event  |
+| click-input      | 点击输入区域时触发      | event  |
+| click-left-icon  | 点击左侧图标时触发      | event  |
+| click-right-icon | 点击右侧图标时触发      | event  |
 
 
 ### Slots
 ### Slots
 | 名称  | 说明     | 
 | 名称  | 说明     | 

+ 60 - 78
src/packages/__VUE/input/index.taro.vue

@@ -1,20 +1,23 @@
 <template>
 <template>
   <view :class="classes">
   <view :class="classes">
-    <template v-if="$slots.input">
-      <view
-        v-if="label"
-        class="nut-input-label"
-        :class="labelClass"
-        :style="{
-          width: `${labelWidth}px`,
-          textAlign: labelAlign
-        }"
-      >
-        <view class="label-string">
-          {{ label }}
-          {{ colon ? ':' : '' }}
-        </view>
+    <view v-if="leftIcon && leftIcon.length > 0" class="nut-input-left-icon" @click="onClickLeftIcon">
+      <nut-icon :name="leftIcon" v-bind="$attrs" :size="leftIconSize"></nut-icon>
+    </view>
+    <view
+      v-if="label"
+      class="nut-input-label"
+      :class="labelClass"
+      :style="{
+        width: `${labelWidth}px`,
+        textAlign: labelAlign
+      }"
+    >
+      <view class="label-string">
+        {{ label }}
+        {{ colon ? ':' : '' }}
       </view>
       </view>
+    </view>
+    <template v-if="$slots.input">
       <view class="nut-input-value">
       <view class="nut-input-value">
         <view class="nut-input-inner" @click="onClickInput">
         <view class="nut-input-inner" @click="onClickInput">
           <slot name="input"></slot>
           <slot name="input"></slot>
@@ -22,66 +25,27 @@
       </view>
       </view>
     </template>
     </template>
     <template v-else>
     <template v-else>
-      <view v-if="leftIcon && leftIcon.length > 0" class="nut-input-left-icon" @click="onClickLeftIcon">
-        <nut-icon :name="leftIcon" v-bind="$attrs" :size="leftIconSize"></nut-icon>
-      </view>
-      <view
-        v-if="label"
-        class="nut-input-label"
-        :class="labelClass"
-        :style="{
-          width: `${labelWidth}px`,
-          textAlign: labelAlign
-        }"
-      >
-        <view class="label-string">
-          {{ label }}
-          {{ colon ? ':' : '' }}
-        </view>
-      </view>
       <view class="nut-input-value">
       <view class="nut-input-value">
         <view class="nut-input-inner">
         <view class="nut-input-inner">
           <view class="nut-input-box">
           <view class="nut-input-box">
-            <textarea
-              v-if="type == 'textarea'"
-              class="input-text"
-              ref="inputRef"
-              :style="stylesTextarea"
-              :maxlength="maxLength"
-              :placeholder="placeholder"
-              placeholder-class="nut-placeholder"
-              :disabled="disabled"
-              :readonly="readonly"
-              :value="modelValue"
-              :formatTrigger="formatTrigger"
-              :adjust-position="adjustPosition"
-              :always-system="alwaysSystem"
-              @input="onInput"
-              @focus="onFocus"
-              @blur="onBlur"
-              @click="onClickInput"
-            />
-            <input
-              v-else
+            <component
+              :is="renderInput(type)"
               class="input-text"
               class="input-text"
               ref="inputRef"
               ref="inputRef"
               :style="styles"
               :style="styles"
-              :type="inputType(type)"
               :maxlength="maxLength"
               :maxlength="maxLength"
               :placeholder="placeholder"
               :placeholder="placeholder"
-              placeholder-class="nut-placeholder"
               :disabled="disabled"
               :disabled="disabled"
               :readonly="readonly"
               :readonly="readonly"
               :value="modelValue"
               :value="modelValue"
               :formatTrigger="formatTrigger"
               :formatTrigger="formatTrigger"
-              :confirm-type="confirmType"
-              :adjust-position="adjustPosition"
-              :always-system="alwaysSystem"
+              :autofocus="autofocus"
+              :enterkeyhint="confirmType"
               @input="onInput"
               @input="onInput"
               @focus="onFocus"
               @focus="onFocus"
               @blur="onBlur"
               @blur="onBlur"
               @click="onClickInput"
               @click="onClickInput"
-            />
+            ></component>
             <view v-if="readonly" class="nut-input-disabled-mask" @click="onClickInput"></view>
             <view v-if="readonly" class="nut-input-disabled-mask" @click="onClickInput"></view>
           </view>
           </view>
           <view class="nut-input-clear-box">
           <view class="nut-input-clear-box">
@@ -120,12 +84,22 @@
   </view>
   </view>
 </template>
 </template>
 <script lang="ts">
 <script lang="ts">
-import { PropType, ref, reactive, computed, onMounted, watch, nextTick, inject } from 'vue';
+import { PropType, ref, reactive, computed, onMounted, watch, ComputedRef, InputHTMLAttributes, h } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 import { createComponent } from '@/packages/utils/create';
 import { formatNumber } from './util';
 import { formatNumber } from './util';
 
 
 const { componentName, create } = createComponent('input');
 const { componentName, create } = createComponent('input');
 
 
+export type InputType = InputHTMLAttributes['type'];
+export type InputAlignType = 'left' | 'center' | 'right'; // text-align
+export type InputFormatTrigger = 'onChange' | 'onBlur'; // onChange: 在输入时执行格式化 ; onBlur: 在失焦时执行格式化
+export type InputRule = {
+  pattern?: RegExp;
+  message?: string;
+  required?: boolean;
+};
+export type ConfirmTextType = 'send' | 'search' | 'next' | 'go' | 'done';
+
 export default create({
 export default create({
   props: {
   props: {
     ref: {
     ref: {
@@ -133,11 +107,11 @@ export default create({
       default: ''
       default: ''
     },
     },
     type: {
     type: {
-      type: String as PropType<import('./type').InputType>,
+      type: String as PropType<InputType>,
       default: 'text'
       default: 'text'
     },
     },
     modelValue: {
     modelValue: {
-      type: [String, Number],
+      type: String,
       default: ''
       default: ''
     },
     },
     placeholder: {
     placeholder: {
@@ -157,7 +131,7 @@ export default create({
       default: '80'
       default: '80'
     },
     },
     labelAlign: {
     labelAlign: {
-      type: String as PropType<import('./type').InputAlignType>,
+      type: String as PropType<InputAlignType>,
       default: 'left'
       default: 'left'
     },
     },
     colon: {
     colon: {
@@ -225,7 +199,7 @@ export default create({
       default: true
       default: true
     },
     },
     formatTrigger: {
     formatTrigger: {
-      type: String as PropType<import('./type').InputFormatTrigger>,
+      type: String as PropType<InputFormatTrigger>,
       default: 'onChange'
       default: 'onChange'
     },
     },
     formatter: {
     formatter: {
@@ -233,7 +207,7 @@ export default create({
       default: null
       default: null
     },
     },
     rules: {
     rules: {
-      type: Array as PropType<import('./type').InputRule>,
+      type: Array as PropType<InputRule>,
       default: []
       default: []
     },
     },
     errorMessage: {
     errorMessage: {
@@ -241,7 +215,7 @@ export default create({
       default: ''
       default: ''
     },
     },
     errorMessageAlign: {
     errorMessageAlign: {
-      type: String as PropType<import('./type').InputAlignType>,
+      type: String as PropType<InputAlignType>,
       default: ''
       default: ''
     },
     },
     rows: {
     rows: {
@@ -257,7 +231,7 @@ export default create({
       default: false
       default: false
     },
     },
     confirmType: {
     confirmType: {
-      type: String as PropType<import('./type').ConfirmTextType>,
+      type: String as PropType<ConfirmTextType>,
       default: 'done'
       default: 'done'
     },
     },
     adjustPosition: {
     adjustPosition: {
@@ -285,9 +259,14 @@ export default create({
   setup(props, { emit, slots }) {
   setup(props, { emit, slots }) {
     const active = ref(false);
     const active = ref(false);
 
 
-    const inputRef: any = ref(null);
+    const inputRef = ref();
     const getModelValue = () => String(props.modelValue ?? '');
     const getModelValue = () => String(props.modelValue ?? '');
-    // const form = inject('form');
+
+    const renderInput = (type: InputType) => {
+      return h(type == 'textarea' ? 'textarea' : 'input', {
+        style: type == 'textarea' ? stylesTextarea : styles
+      });
+    };
 
 
     const state = reactive({
     const state = reactive({
       focused: false,
       focused: false,
@@ -307,19 +286,19 @@ export default create({
       };
       };
     });
     });
 
 
-    const styles: any = computed(() => {
+    const styles: ComputedRef = computed(() => {
       return {
       return {
         textAlign: props.inputAlign
         textAlign: props.inputAlign
       };
       };
     });
     });
-    const stylesTextarea: any = computed(() => {
+    const stylesTextarea: ComputedRef = computed(() => {
       return {
       return {
         textAlign: props.inputAlign,
         textAlign: props.inputAlign,
         height: Number(props.rows) * 24 + 'px'
         height: Number(props.rows) * 24 + 'px'
       };
       };
     });
     });
 
 
-    const inputType = (type: string) => {
+    const inputType = (type: InputType) => {
       if (type === 'number') {
       if (type === 'number') {
         return 'text';
         return 'text';
       } else if (type === 'digit') {
       } else if (type === 'digit') {
@@ -338,12 +317,11 @@ export default create({
       updateValue(value);
       updateValue(value);
     };
     };
 
 
-    const updateValue = (value: string, trigger: import('./type').InputFormatTrigger = 'onChange') => {
+    const updateValue = (value: string, trigger: InputFormatTrigger = 'onChange') => {
       if (props.type === 'digit') {
       if (props.type === 'digit') {
         value = formatNumber(value, false, false);
         value = formatNumber(value, false, false);
       }
       }
       if (props.type === 'number') {
       if (props.type === 'number') {
-        // console.log('value', value)
         value = formatNumber(value, true, true);
         value = formatNumber(value, true, true);
       }
       }
 
 
@@ -351,7 +329,7 @@ export default create({
         value = props.formatter(value);
         value = props.formatter(value);
       }
       }
 
 
-      if (inputRef && inputRef.value && inputRef.value !== value) {
+      if (inputRef?.value !== value) {
         inputRef.value = value;
         inputRef.value = value;
       }
       }
 
 
@@ -368,7 +346,8 @@ export default create({
       const input = event.target as HTMLInputElement;
       const input = event.target as HTMLInputElement;
       let value = input.value;
       let value = input.value;
       active.value = true;
       active.value = true;
-      emit('focus', value, event);
+      emit('focus', event);
+      emit('update:modelValue', value);
     };
     };
 
 
     const onBlur = (event: Event) => {
     const onBlur = (event: Event) => {
@@ -385,13 +364,13 @@ export default create({
         value = value.slice(0, Number(props.maxLength));
         value = value.slice(0, Number(props.maxLength));
       }
       }
       updateValue(getModelValue(), 'onBlur');
       updateValue(getModelValue(), 'onBlur');
-      emit('blur', value, event);
+      emit('blur', event);
+      emit('update:modelValue', value);
     };
     };
 
 
     const clear = (event: Event) => {
     const clear = (event: Event) => {
+      event.stopPropagation();
       if (props.disabled) return;
       if (props.disabled) return;
-      emit('update:modelValue', '', event);
-      emit('change', '', event);
       emit('clear', '', event);
       emit('clear', '', event);
     };
     };
 
 
@@ -410,6 +389,7 @@ export default create({
     };
     };
 
 
     const onClickLeftIcon = (event: MouseEvent) => {
     const onClickLeftIcon = (event: MouseEvent) => {
+      event.stopPropagation();
       if (props.disabled) {
       if (props.disabled) {
         return;
         return;
       }
       }
@@ -417,6 +397,7 @@ export default create({
     };
     };
 
 
     const onClickRightIcon = (event: MouseEvent) => {
     const onClickRightIcon = (event: MouseEvent) => {
+      event.stopPropagation();
       if (props.disabled) {
       if (props.disabled) {
         return;
         return;
       }
       }
@@ -443,6 +424,7 @@ export default create({
     });
     });
 
 
     return {
     return {
+      renderInput,
       inputRef,
       inputRef,
       active,
       active,
       classes,
       classes,

+ 56 - 76
src/packages/__VUE/input/index.vue

@@ -1,20 +1,23 @@
 <template>
 <template>
   <view :class="classes">
   <view :class="classes">
-    <template v-if="$slots.input">
-      <view
-        v-if="label"
-        class="nut-input-label"
-        :class="labelClass"
-        :style="{
-          width: `${labelWidth}px`,
-          textAlign: labelAlign
-        }"
-      >
-        <view class="label-string">
-          {{ label }}
-          {{ colon ? ':' : '' }}
-        </view>
+    <view v-if="leftIcon && leftIcon.length > 0" class="nut-input-left-icon" @click="onClickLeftIcon">
+      <nut-icon :name="leftIcon" v-bind="$attrs" :size="leftIconSize"></nut-icon>
+    </view>
+    <view
+      v-if="label"
+      class="nut-input-label"
+      :class="labelClass"
+      :style="{
+        width: `${labelWidth}px`,
+        textAlign: labelAlign
+      }"
+    >
+      <view class="label-string">
+        {{ label }}
+        {{ colon ? ':' : '' }}
       </view>
       </view>
+    </view>
+    <template v-if="$slots.input">
       <view class="nut-input-value">
       <view class="nut-input-value">
         <view class="nut-input-inner" @click="onClickInput">
         <view class="nut-input-inner" @click="onClickInput">
           <slot name="input"></slot>
           <slot name="input"></slot>
@@ -22,50 +25,14 @@
       </view>
       </view>
     </template>
     </template>
     <template v-else>
     <template v-else>
-      <view v-if="leftIcon && leftIcon.length > 0" class="nut-input-left-icon" @click="onClickLeftIcon">
-        <nut-icon :name="leftIcon" v-bind="$attrs" :size="leftIconSize"></nut-icon>
-      </view>
-      <view
-        v-if="label"
-        class="nut-input-label"
-        :class="labelClass"
-        :style="{
-          width: `${labelWidth}px`,
-          textAlign: labelAlign
-        }"
-      >
-        <view class="label-string">
-          {{ label }}
-          {{ colon ? ':' : '' }}
-        </view>
-      </view>
       <view class="nut-input-value">
       <view class="nut-input-value">
         <view class="nut-input-inner">
         <view class="nut-input-inner">
           <view class="nut-input-box">
           <view class="nut-input-box">
-            <textarea
-              v-if="type == 'textarea'"
-              class="input-text"
-              ref="inputRef"
-              :style="stylesTextarea"
-              :maxlength="maxLength"
-              :placeholder="placeholder"
-              :disabled="disabled"
-              :readonly="readonly"
-              :value="modelValue"
-              :formatTrigger="formatTrigger"
-              :autofocus="autofocus"
-              :enterkeyhint="confirmType"
-              @input="onInput"
-              @focus="onFocus"
-              @blur="onBlur"
-              @click="onClickInput"
-            />
-            <input
-              v-else
+            <component
+              :is="renderInput(type)"
               class="input-text"
               class="input-text"
               ref="inputRef"
               ref="inputRef"
               :style="styles"
               :style="styles"
-              :type="inputType(type)"
               :maxlength="maxLength"
               :maxlength="maxLength"
               :placeholder="placeholder"
               :placeholder="placeholder"
               :disabled="disabled"
               :disabled="disabled"
@@ -78,7 +45,7 @@
               @focus="onFocus"
               @focus="onFocus"
               @blur="onBlur"
               @blur="onBlur"
               @click="onClickInput"
               @click="onClickInput"
-            />
+            ></component>
           </view>
           </view>
           <view class="nut-input-clear-box">
           <view class="nut-input-clear-box">
             <nut-icon
             <nut-icon
@@ -116,12 +83,22 @@
   </view>
   </view>
 </template>
 </template>
 <script lang="ts">
 <script lang="ts">
-import { PropType, ref, reactive, computed, onMounted, watch, nextTick, inject } from 'vue';
+import { PropType, ref, reactive, computed, onMounted, watch, ComputedRef, InputHTMLAttributes, h } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 import { createComponent } from '@/packages/utils/create';
 import { formatNumber } from './util';
 import { formatNumber } from './util';
 
 
 const { componentName, create } = createComponent('input');
 const { componentName, create } = createComponent('input');
 
 
+export type InputType = InputHTMLAttributes['type'];
+export type InputAlignType = 'left' | 'center' | 'right'; // text-align
+export type InputFormatTrigger = 'onChange' | 'onBlur'; // onChange: 在输入时执行格式化 ; onBlur: 在失焦时执行格式化
+export type InputRule = {
+  pattern?: RegExp;
+  message?: string;
+  required?: boolean;
+};
+export type ConfirmTextType = 'send' | 'search' | 'next' | 'go' | 'done';
+
 export default create({
 export default create({
   props: {
   props: {
     ref: {
     ref: {
@@ -129,11 +106,11 @@ export default create({
       default: ''
       default: ''
     },
     },
     type: {
     type: {
-      type: String as PropType<import('./type').InputType>,
+      type: String as PropType<InputType>,
       default: 'text'
       default: 'text'
     },
     },
     modelValue: {
     modelValue: {
-      type: [String, Number],
+      type: String,
       default: ''
       default: ''
     },
     },
     placeholder: {
     placeholder: {
@@ -153,7 +130,7 @@ export default create({
       default: '80'
       default: '80'
     },
     },
     labelAlign: {
     labelAlign: {
-      type: String as PropType<import('./type').InputAlignType>,
+      type: String as PropType<InputAlignType>,
       default: 'left'
       default: 'left'
     },
     },
     colon: {
     colon: {
@@ -221,7 +198,7 @@ export default create({
       default: true
       default: true
     },
     },
     formatTrigger: {
     formatTrigger: {
-      type: String as PropType<import('./type').InputFormatTrigger>,
+      type: String as PropType<InputFormatTrigger>,
       default: 'onChange'
       default: 'onChange'
     },
     },
     formatter: {
     formatter: {
@@ -229,7 +206,7 @@ export default create({
       default: null
       default: null
     },
     },
     rules: {
     rules: {
-      type: Array as PropType<import('./type').InputRule>,
+      type: Array as PropType<InputRule>,
       default: []
       default: []
     },
     },
     errorMessage: {
     errorMessage: {
@@ -237,7 +214,7 @@ export default create({
       default: ''
       default: ''
     },
     },
     errorMessageAlign: {
     errorMessageAlign: {
-      type: String as PropType<import('./type').InputAlignType>,
+      type: String as PropType<InputAlignType>,
       default: ''
       default: ''
     },
     },
     rows: {
     rows: {
@@ -272,11 +249,14 @@ export default create({
 
 
   setup(props, { emit, slots }) {
   setup(props, { emit, slots }) {
     const active = ref(false);
     const active = ref(false);
-
-    const inputRef = ref<HTMLInputElement>();
-    const customValue = ref<() => unknown>();
+    const inputRef = ref();
     const getModelValue = () => String(props.modelValue ?? '');
     const getModelValue = () => String(props.modelValue ?? '');
-    // const form = inject('form');
+
+    const renderInput = (type: InputType) => {
+      return h(type == 'textarea' ? 'textarea' : 'input', {
+        style: type == 'textarea' ? stylesTextarea : styles
+      });
+    };
 
 
     const state = reactive({
     const state = reactive({
       focused: false,
       focused: false,
@@ -296,19 +276,19 @@ export default create({
       };
       };
     });
     });
 
 
-    const styles: any = computed(() => {
+    const styles: ComputedRef = computed(() => {
       return {
       return {
         textAlign: props.inputAlign
         textAlign: props.inputAlign
       };
       };
     });
     });
-    const stylesTextarea: any = computed(() => {
+    const stylesTextarea: ComputedRef = computed(() => {
       return {
       return {
         textAlign: props.inputAlign,
         textAlign: props.inputAlign,
         height: Number(props.rows) * 24 + 'px'
         height: Number(props.rows) * 24 + 'px'
       };
       };
     });
     });
 
 
-    const inputType = (type: string) => {
+    const inputType = (type: InputType) => {
       if (type === 'number') {
       if (type === 'number') {
         return 'text';
         return 'text';
       } else if (type === 'digit') {
       } else if (type === 'digit') {
@@ -327,12 +307,11 @@ export default create({
       updateValue(value);
       updateValue(value);
     };
     };
 
 
-    const updateValue = (value: string, trigger: import('./type').InputFormatTrigger = 'onChange') => {
+    const updateValue = (value: string, trigger: InputFormatTrigger = 'onChange') => {
       if (props.type === 'digit') {
       if (props.type === 'digit') {
         value = formatNumber(value, false, false);
         value = formatNumber(value, false, false);
       }
       }
       if (props.type === 'number') {
       if (props.type === 'number') {
-        // console.log('value', value)
         value = formatNumber(value, true, true);
         value = formatNumber(value, true, true);
       }
       }
 
 
@@ -357,10 +336,8 @@ export default create({
       const input = event.target as HTMLInputElement;
       const input = event.target as HTMLInputElement;
       let value = input.value;
       let value = input.value;
       active.value = true;
       active.value = true;
-      emit('focus', value, event);
-      // if (getProp('readonly')) {
-      //   blur();
-      // }
+      emit('focus', event);
+      emit('update:modelValue', value);
     };
     };
 
 
     const onBlur = (event: Event) => {
     const onBlur = (event: Event) => {
@@ -377,13 +354,13 @@ export default create({
         value = value.slice(0, Number(props.maxLength));
         value = value.slice(0, Number(props.maxLength));
       }
       }
       updateValue(getModelValue(), 'onBlur');
       updateValue(getModelValue(), 'onBlur');
-      emit('blur', value, event);
+      emit('blur', event);
+      emit('update:modelValue', value);
     };
     };
 
 
     const clear = (event: Event) => {
     const clear = (event: Event) => {
+      event.stopPropagation();
       if (props.disabled) return;
       if (props.disabled) return;
-      emit('update:modelValue', '', event);
-      emit('change', '', event);
       emit('clear', '', event);
       emit('clear', '', event);
     };
     };
 
 
@@ -402,6 +379,7 @@ export default create({
     };
     };
 
 
     const onClickLeftIcon = (event: MouseEvent) => {
     const onClickLeftIcon = (event: MouseEvent) => {
+      event.stopPropagation();
       if (props.disabled) {
       if (props.disabled) {
         return;
         return;
       }
       }
@@ -409,6 +387,7 @@ export default create({
     };
     };
 
 
     const onClickRightIcon = (event: MouseEvent) => {
     const onClickRightIcon = (event: MouseEvent) => {
+      event.stopPropagation();
       if (props.disabled) {
       if (props.disabled) {
         return;
         return;
       }
       }
@@ -432,6 +411,7 @@ export default create({
     });
     });
 
 
     return {
     return {
+      renderInput,
       inputRef,
       inputRef,
       active,
       active,
       classes,
       classes,