Browse Source

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

Drjnigfubo 3 years ago
parent
commit
5f0f635120

+ 6 - 22
src/packages/__VUE/collapse/index.taro.vue

@@ -116,34 +116,18 @@ export default create({
             if (typeof newval == 'number' || typeof newval == 'string') {
               if (domsProps[index]) {
                 if (domsProps[index].props) {
-                  if (newval == domsProps[index].props.name) {
-                    item.changeOpen(true);
-                  } else {
-                    item.changeOpen(false);
-                  }
+                  item.changeOpen(newval == domsProps[index].props.name ? true : false);
                 } else {
-                  if (newval == item.name) {
-                    item.changeOpen(true);
-                  } else {
-                    item.changeOpen(false);
-                  }
+                  item.changeOpen(newval == item.name ? true : false);
                 }
               } else {
-                if (newval == item.name) {
-                  item.changeOpen(true);
-                } else {
-                  item.changeOpen(false);
-                }
+                item.changeOpen(newval == item.name ? true : false);
               }
             } else if (Object.values(newval) instanceof Array) {
-              if (
+              const isOpen =
                 newval.indexOf(Number(domsProps[index].props.name)) > -1 ||
-                newval.indexOf(String(domsProps[index].props.name)) > -1
-              ) {
-                item.changeOpen(true);
-              } else {
-                item.changeOpen(false);
-              }
+                newval.indexOf(String(domsProps[index].props.name)) > -1;
+              item.changeOpen(isOpen);
             }
             item.animation();
           });

+ 3 - 10
src/packages/__VUE/collapse/index.vue

@@ -62,17 +62,10 @@ export default create({
         let doms: any = collapseChldren.value;
         Array.from(doms).forEach((item: any) => {
           if (typeof newval == 'number' || typeof newval == 'string') {
-            if (newval == item.name) {
-              item.changeOpen(true);
-            } else {
-              item.changeOpen(false);
-            }
+            item.changeOpen(newval == item.name ? true : false);
           } else if (Object.values(newval) instanceof Array) {
-            if (newval.indexOf(Number(item.name)) > -1 || newval.indexOf(String(item.name)) > -1) {
-              item.changeOpen(true);
-            } else {
-              item.changeOpen(false);
-            }
+            const isOpen = newval.indexOf(Number(item.name)) > -1 || newval.indexOf(String(item.name)) > -1;
+            item.changeOpen(isOpen);
           }
           item.animation();
         });

+ 8 - 4
src/packages/__VUE/collapseitem/index.vue

@@ -257,10 +257,14 @@ export default create({
       var observer = new MutationObserver(() => {
         animation();
       });
-      observer.observe(document.getElementsByClassName('collapse-wrapper')[0], {
-        childList: true,
-        subtree: true
-      });
+      const ele = document.getElementsByClassName('collapse-wrapper')[0];
+      if (ele) {
+        observer.observe(ele, {
+          childList: true,
+          subtree: true
+        });
+      }
+
       init();
       // proxyData.classDirection = parent.props.expandIconPosition;
       // if (parent.props.icon && parent.props.icon != 'none') {

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

@@ -137,8 +137,9 @@
       @clear="clear"
       @click="click"
       @click-input="clickInput"
+      @click-left-icon="clickLeftIcon"
+      @click-right-icon="clickRightIcon"
     />
-    <nut-icon @click="click1" name="dongdong"></nut-icon>
   </div>
 </template>
 
@@ -261,32 +262,29 @@ export default createDemo({
     setTimeout(function () {
       // state.val1 = '异步数据';
     }, 2000);
-    const change = (value: string | number) => {
+    const change = (value: string) => {
       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, '');
 
@@ -301,8 +299,7 @@ export default createDemo({
       clickLeftIcon,
       clickRightIcon,
       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({
         event: ''
       });
-      const change = (value: string | number) => {
+      const change = (value: string) => {
         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 {
@@ -539,13 +539,13 @@ Use `label-align` prop to align the label, `input-align` prop to align the input
 | Event   | Description      | Arguments    |
 |--------|----------------|-------------|
 | 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
 

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

@@ -458,29 +458,29 @@ app.use(Icon);
       const state = reactive({
         event: ''
       });
-      const change = (value: string | number) => {
+      const change = (value: string) => {
         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 {
@@ -542,13 +542,13 @@ app.use(Icon);
 | 名称   | 说明           | 回调参数    |
 |--------|----------------|-------------|
 | 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
 | 名称  | 说明     | 

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

@@ -1,20 +1,23 @@
 <template>
   <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>
+    <template v-if="$slots.input">
       <view class="nut-input-value">
         <view class="nut-input-inner" @click="onClickInput">
           <slot name="input"></slot>
@@ -22,66 +25,27 @@
       </view>
     </template>
     <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-inner">
           <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"
               ref="inputRef"
               :style="styles"
-              :type="inputType(type)"
               :maxlength="maxLength"
               :placeholder="placeholder"
-              placeholder-class="nut-placeholder"
               :disabled="disabled"
               :readonly="readonly"
               :value="modelValue"
               :formatTrigger="formatTrigger"
-              :confirm-type="confirmType"
-              :adjust-position="adjustPosition"
-              :always-system="alwaysSystem"
+              :autofocus="autofocus"
+              :enterkeyhint="confirmType"
               @input="onInput"
               @focus="onFocus"
               @blur="onBlur"
               @click="onClickInput"
-            />
+            ></component>
             <view v-if="readonly" class="nut-input-disabled-mask" @click="onClickInput"></view>
           </view>
           <view class="nut-input-clear-box">
@@ -120,12 +84,22 @@
   </view>
 </template>
 <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 { formatNumber } from './util';
 
 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({
   props: {
     ref: {
@@ -133,11 +107,11 @@ export default create({
       default: ''
     },
     type: {
-      type: String as PropType<import('./type').InputType>,
+      type: String as PropType<InputType>,
       default: 'text'
     },
     modelValue: {
-      type: [String, Number],
+      type: String,
       default: ''
     },
     placeholder: {
@@ -157,7 +131,7 @@ export default create({
       default: '80'
     },
     labelAlign: {
-      type: String as PropType<import('./type').InputAlignType>,
+      type: String as PropType<InputAlignType>,
       default: 'left'
     },
     colon: {
@@ -225,7 +199,7 @@ export default create({
       default: true
     },
     formatTrigger: {
-      type: String as PropType<import('./type').InputFormatTrigger>,
+      type: String as PropType<InputFormatTrigger>,
       default: 'onChange'
     },
     formatter: {
@@ -233,7 +207,7 @@ export default create({
       default: null
     },
     rules: {
-      type: Array as PropType<import('./type').InputRule>,
+      type: Array as PropType<InputRule>,
       default: []
     },
     errorMessage: {
@@ -241,7 +215,7 @@ export default create({
       default: ''
     },
     errorMessageAlign: {
-      type: String as PropType<import('./type').InputAlignType>,
+      type: String as PropType<InputAlignType>,
       default: ''
     },
     rows: {
@@ -257,7 +231,7 @@ export default create({
       default: false
     },
     confirmType: {
-      type: String as PropType<import('./type').ConfirmTextType>,
+      type: String as PropType<ConfirmTextType>,
       default: 'done'
     },
     adjustPosition: {
@@ -285,9 +259,14 @@ export default create({
   setup(props, { emit, slots }) {
     const active = ref(false);
 
-    const inputRef: any = ref(null);
+    const inputRef = ref();
     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({
       focused: false,
@@ -307,19 +286,19 @@ export default create({
       };
     });
 
-    const styles: any = computed(() => {
+    const styles: ComputedRef = computed(() => {
       return {
         textAlign: props.inputAlign
       };
     });
-    const stylesTextarea: any = computed(() => {
+    const stylesTextarea: ComputedRef = computed(() => {
       return {
         textAlign: props.inputAlign,
         height: Number(props.rows) * 24 + 'px'
       };
     });
 
-    const inputType = (type: string) => {
+    const inputType = (type: InputType) => {
       if (type === 'number') {
         return 'text';
       } else if (type === 'digit') {
@@ -338,12 +317,11 @@ export default create({
       updateValue(value);
     };
 
-    const updateValue = (value: string, trigger: import('./type').InputFormatTrigger = 'onChange') => {
+    const updateValue = (value: string, trigger: InputFormatTrigger = 'onChange') => {
       if (props.type === 'digit') {
         value = formatNumber(value, false, false);
       }
       if (props.type === 'number') {
-        // console.log('value', value)
         value = formatNumber(value, true, true);
       }
 
@@ -351,7 +329,7 @@ export default create({
         value = props.formatter(value);
       }
 
-      if (inputRef && inputRef.value && inputRef.value !== value) {
+      if (inputRef?.value !== value) {
         inputRef.value = value;
       }
 
@@ -368,7 +346,8 @@ export default create({
       const input = event.target as HTMLInputElement;
       let value = input.value;
       active.value = true;
-      emit('focus', value, event);
+      emit('focus', event);
+      emit('update:modelValue', value);
     };
 
     const onBlur = (event: Event) => {
@@ -385,13 +364,13 @@ export default create({
         value = value.slice(0, Number(props.maxLength));
       }
       updateValue(getModelValue(), 'onBlur');
-      emit('blur', value, event);
+      emit('blur', event);
+      emit('update:modelValue', value);
     };
 
     const clear = (event: Event) => {
+      event.stopPropagation();
       if (props.disabled) return;
-      emit('update:modelValue', '', event);
-      emit('change', '', event);
       emit('clear', '', event);
     };
 
@@ -410,6 +389,7 @@ export default create({
     };
 
     const onClickLeftIcon = (event: MouseEvent) => {
+      event.stopPropagation();
       if (props.disabled) {
         return;
       }
@@ -417,6 +397,7 @@ export default create({
     };
 
     const onClickRightIcon = (event: MouseEvent) => {
+      event.stopPropagation();
       if (props.disabled) {
         return;
       }
@@ -443,6 +424,7 @@ export default create({
     });
 
     return {
+      renderInput,
       inputRef,
       active,
       classes,

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

@@ -1,20 +1,23 @@
 <template>
   <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>
+    <template v-if="$slots.input">
       <view class="nut-input-value">
         <view class="nut-input-inner" @click="onClickInput">
           <slot name="input"></slot>
@@ -22,50 +25,14 @@
       </view>
     </template>
     <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-inner">
           <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"
               ref="inputRef"
               :style="styles"
-              :type="inputType(type)"
               :maxlength="maxLength"
               :placeholder="placeholder"
               :disabled="disabled"
@@ -78,7 +45,7 @@
               @focus="onFocus"
               @blur="onBlur"
               @click="onClickInput"
-            />
+            ></component>
           </view>
           <view class="nut-input-clear-box">
             <nut-icon
@@ -116,12 +83,22 @@
   </view>
 </template>
 <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 { formatNumber } from './util';
 
 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({
   props: {
     ref: {
@@ -129,11 +106,11 @@ export default create({
       default: ''
     },
     type: {
-      type: String as PropType<import('./type').InputType>,
+      type: String as PropType<InputType>,
       default: 'text'
     },
     modelValue: {
-      type: [String, Number],
+      type: String,
       default: ''
     },
     placeholder: {
@@ -153,7 +130,7 @@ export default create({
       default: '80'
     },
     labelAlign: {
-      type: String as PropType<import('./type').InputAlignType>,
+      type: String as PropType<InputAlignType>,
       default: 'left'
     },
     colon: {
@@ -221,7 +198,7 @@ export default create({
       default: true
     },
     formatTrigger: {
-      type: String as PropType<import('./type').InputFormatTrigger>,
+      type: String as PropType<InputFormatTrigger>,
       default: 'onChange'
     },
     formatter: {
@@ -229,7 +206,7 @@ export default create({
       default: null
     },
     rules: {
-      type: Array as PropType<import('./type').InputRule>,
+      type: Array as PropType<InputRule>,
       default: []
     },
     errorMessage: {
@@ -237,7 +214,7 @@ export default create({
       default: ''
     },
     errorMessageAlign: {
-      type: String as PropType<import('./type').InputAlignType>,
+      type: String as PropType<InputAlignType>,
       default: ''
     },
     rows: {
@@ -272,11 +249,14 @@ export default create({
 
   setup(props, { emit, slots }) {
     const active = ref(false);
-
-    const inputRef = ref<HTMLInputElement>();
-    const customValue = ref<() => unknown>();
+    const inputRef = ref();
     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({
       focused: false,
@@ -296,19 +276,19 @@ export default create({
       };
     });
 
-    const styles: any = computed(() => {
+    const styles: ComputedRef = computed(() => {
       return {
         textAlign: props.inputAlign
       };
     });
-    const stylesTextarea: any = computed(() => {
+    const stylesTextarea: ComputedRef = computed(() => {
       return {
         textAlign: props.inputAlign,
         height: Number(props.rows) * 24 + 'px'
       };
     });
 
-    const inputType = (type: string) => {
+    const inputType = (type: InputType) => {
       if (type === 'number') {
         return 'text';
       } else if (type === 'digit') {
@@ -327,12 +307,11 @@ export default create({
       updateValue(value);
     };
 
-    const updateValue = (value: string, trigger: import('./type').InputFormatTrigger = 'onChange') => {
+    const updateValue = (value: string, trigger: InputFormatTrigger = 'onChange') => {
       if (props.type === 'digit') {
         value = formatNumber(value, false, false);
       }
       if (props.type === 'number') {
-        // console.log('value', value)
         value = formatNumber(value, true, true);
       }
 
@@ -357,10 +336,8 @@ export default create({
       const input = event.target as HTMLInputElement;
       let value = input.value;
       active.value = true;
-      emit('focus', value, event);
-      // if (getProp('readonly')) {
-      //   blur();
-      // }
+      emit('focus', event);
+      emit('update:modelValue', value);
     };
 
     const onBlur = (event: Event) => {
@@ -377,13 +354,13 @@ export default create({
         value = value.slice(0, Number(props.maxLength));
       }
       updateValue(getModelValue(), 'onBlur');
-      emit('blur', value, event);
+      emit('blur', event);
+      emit('update:modelValue', value);
     };
 
     const clear = (event: Event) => {
+      event.stopPropagation();
       if (props.disabled) return;
-      emit('update:modelValue', '', event);
-      emit('change', '', event);
       emit('clear', '', event);
     };
 
@@ -402,6 +379,7 @@ export default create({
     };
 
     const onClickLeftIcon = (event: MouseEvent) => {
+      event.stopPropagation();
       if (props.disabled) {
         return;
       }
@@ -409,6 +387,7 @@ export default create({
     };
 
     const onClickRightIcon = (event: MouseEvent) => {
+      event.stopPropagation();
       if (props.disabled) {
         return;
       }
@@ -432,6 +411,7 @@ export default create({
     });
 
     return {
+      renderInput,
       inputRef,
       active,
       classes,

+ 0 - 1
src/packages/__VUE/menuitem/index.scss

@@ -39,7 +39,6 @@
 .nut-menu__pop {
   transition: all 0 ease 0;
   transform: none;
-  overflow: hidden;
 }
 
 .placeholder-element {

+ 5 - 2
src/packages/__VUE/menuitem/index.taro.vue

@@ -1,5 +1,5 @@
 <template>
-  <view :class="classes" v-show="state.showWrapper" style="position: fixed" :style="{ zIndex: state.zIndex }">
+  <view :class="classes" v-show="state.showWrapper" :style="{ zIndex: state.zIndex }">
     <div
       v-show="state.isShowPlaceholderElement"
       @click="handleClickOutside"
@@ -13,13 +13,16 @@
         parent.props.direction === 'down' ? { top: parent.offset.value + 'px' } : { bottom: parent.offset.value + 'px' }
       "
       :overlay-style="
-        parent.props.direction === 'down' ? { top: parent.offset.value + 'px' } : { bottom: parent.offset.value + 'px' }
+        parent.props.direction === 'down'
+          ? { top: parent.offset.value + 'px' }
+          : { bottom: parent.offset.value + 'px', top: 'auto' }
       "
       v-bind="$attrs"
       v-model:visible="state.showPopup"
       :position="parent.props.direction === 'down' ? 'top' : 'bottom'"
       :duration="parent.props.duration"
       pop-class="nut-menu__pop"
+      :destroy-on-close="false"
       :overlay="parent.props.overlay"
       :lockScroll="parent.props.lockScroll"
       @closed="handleClose"

+ 4 - 2
src/packages/__VUE/menuitem/index.vue

@@ -13,14 +13,16 @@
         parent.props.direction === 'down' ? { top: parent.offset.value + 'px' } : { bottom: parent.offset.value + 'px' }
       "
       :overlayStyle="
-        parent.props.direction === 'down' ? { top: parent.offset.value + 'px' } : { bottom: parent.offset.value + 'px' }
+        parent.props.direction === 'down'
+          ? { top: parent.offset.value + 'px' }
+          : { bottom: parent.offset.value + 'px', top: 'auto' }
       "
       v-bind="$attrs"
       v-model:visible="state.showPopup"
       :position="parent.props.direction === 'down' ? 'top' : 'bottom'"
       :duration="parent.props.duration"
       pop-class="nut-menu__pop"
-      overlayClass="nut-menu__overlay"
+      :destroy-on-close="false"
       :overlay="parent.props.overlay"
       @closed="handleClose"
       :lockScroll="parent.props.lockScroll"

+ 8 - 6
src/packages/__VUE/textarea/index.taro.vue

@@ -201,12 +201,14 @@ export default create({
     onMounted(() => {
       if (props.autosize) {
         Taro.nextTick(() => {
-          if (Taro.getEnv() === 'ALIPAY') {
-            getRefWidth();
-            copyHeight();
-          } else {
-            getRefHeight();
-          }
+          setTimeout(() => {
+            if (Taro.getEnv() === 'ALIPAY') {
+              getRefWidth();
+              copyHeight();
+            } else {
+              getRefHeight();
+            }
+          }, 300);
         });
       }
     });