Browse Source

feat: 修复折叠面板手风琴模式;fix: 修复notify标签式展示报错问题及class类名问题;fix: 解决签名组件(Signature)生产环境下 getContext 报错问题;fix: 适配textarea小程序自适应高度功能 (#1464)

* fix: countup优化滚动逻辑

* fix: collapse 无法动态更新问题修复

* fix: 解决H5侧动态加载问题

* docs: 文档增加调试功能(Barrage、Signature、CountUp、TextArea、Collapse)

* feat: 折叠面板 collapse 单元测试

* feat: countUp 单元测试

* feat: barrage 单元测试

* fix: 签名组件单元测试

* feat: textarea 单元测试

* feat: collapse 标题多行展示,无内容不下拉,图标位置配置

* feat: textarea 自动撑开,collapse 组件能力

* fix: collapse 单元测试优化

* fix: textarea 单元测试优化

* fix: 修改input参数,maxNum 改为 maxLength,文档修改等

* fix: maxlength 值

* fix: textarea 自适应

* fix: textarea rows

* upd: notify 增加组件调用方式

* fix: demo 修改

* feat: 新增collapse组件自定义内容(不折叠)功能

* fix: notify 单元测试优化

* feat: searchbar 组件能力补充

* feat: collapse,layout 组件国际化

* upd: countup、barrage、signature、Skeleton组件国际化

* fix: demo及文档修改,组件优化

* feat: textarea 增加autofocus、disabled等属性,增加点击区域事件

* fix: 解决 flexwrap 问题

* fix: 文档修改

* fix: 优化

* fix: collaspe 数据更新支持外部调用

* fix: demo

* feat: 修复折叠面板手风琴模式

* fix: 修复notify标签式展示报错问题及class类名问题

* fix: 解决签名组件生产环境下 getContext 报错问题

* fix: 适配textarea小程序自适应高度功能

Co-authored-by: richard1015 <51844712@qq.com>
Ymm 3 years ago
parent
commit
bec0985f30

+ 6 - 29
project.config.json

@@ -1,7 +1,8 @@
 {
   "description": "项目配置文件",
   "packOptions": {
-    "ignore": []
+    "ignore": [],
+    "include": []
   },
   "setting": {
     "urlCheck": true,
@@ -45,33 +46,9 @@
   "libVersion": "2.24.4",
   "appid": "wx9ac45039b7813c7d",
   "projectname": "nutui",
-  "debugOptions": {
-    "hidedInDevtools": []
-  },
-  "scripts": {},
-  "staticServerOptions": {
-    "baseURL": "",
-    "servePath": ""
-  },
-  "isGameTourist": false,
-  "condition": {
-    "search": {
-      "list": []
-    },
-    "conversation": {
-      "list": []
-    },
-    "game": {
-      "list": []
-    },
-    "plugin": {
-      "list": []
-    },
-    "gamePlugin": {
-      "list": []
-    },
-    "miniprogram": {
-      "list": []
-    }
+  "condition": {},
+  "editorSetting": {
+    "tabIndent": "insertSpaces",
+    "tabSize": 2
   }
 }

+ 7 - 0
project.private.config.json

@@ -0,0 +1,7 @@
+{
+  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+  "projectname": "nutui",
+  "setting": {
+    "compileHotReLoad": true
+  }
+}

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

@@ -4,7 +4,7 @@
   </view>
 </template>
 <script lang="ts">
-import { provide, ref, watch } from 'vue';
+import { getCurrentInstance, onMounted, provide, ref, watch } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 const { create } = createComponent('collapse');
 export default create({
@@ -55,24 +55,20 @@ export default create({
   emits: ['update:active', 'change'],
   setup(props, { emit, slots }) {
     const collapseDom: any = ref(null);
+    const collapseChldren: any = ref([]);
     watch(
       () => props.active,
       (newval: any, oldval) => {
-        let domsProps: any = slots?.default?.();
-        let doms: any = collapseDom.value?.children;
-        Array.from(doms).forEach((dom: any, index: number) => {
-          const item = dom['__vueParentComponent']['ctx'];
+        let doms: any = collapseChldren.value;
+        Array.from(doms).forEach((item: any) => {
           if (typeof newval == 'number' || typeof newval == 'string') {
-            if (newval == domsProps[index].props.name) {
+            if (newval == item.name) {
               item.changeOpen(!item.openExpanded);
             } else {
               item.changeOpen(false);
             }
           } else if (Object.values(newval) instanceof Array) {
-            if (
-              newval.indexOf(Number(domsProps[index].props.name)) > -1 ||
-              newval.indexOf(String(domsProps[index].props.name)) > -1
-            ) {
+            if (newval.indexOf(Number(item.name)) > -1 || newval.indexOf(String(item.name)) > -1) {
               item.changeOpen(true);
             } else {
               item.changeOpen(false);
@@ -83,6 +79,10 @@ export default create({
       }
     );
 
+    onMounted(() => {
+      collapseChldren.value = (getCurrentInstance() as any).provides.collapseParent.children || [];
+    });
+
     const changeVal = (val: string | number | Array<string | number>) => {
       emit('update:active', val);
       emit('change', val);

+ 5 - 0
src/packages/__VUE/notify/index.scss

@@ -31,6 +31,7 @@
   opacity: 0;
 }
 .nut-notify {
+  display: block;
   width: 100%;
   box-sizing: border-box;
   padding: $notify-padding;
@@ -59,4 +60,8 @@
   &--warning {
     background: $notify-warning-background-color;
   }
+  view {
+    width: 100%;
+    text-align: center;
+  }
 }

+ 5 - 1
src/packages/__VUE/notify/index.taro.vue

@@ -1,7 +1,7 @@
 <template>
   <Transition name="nut-fade" @after-leave="onAfterLeave">
     <view
-      :class="['popup-top', 'nut-notify', `nut-notify--${type}`, { className }]"
+      :class="[`popup-${position}`, 'nut-notify', `nut-notify--${type}`, className]"
       :style="{ color: color, background: background }"
       v-show="visible"
       @click="onClick"
@@ -40,6 +40,10 @@ export default create({
     visible: {
       type: Boolean,
       default: false
+    },
+    position: {
+      type: String,
+      default: 'top'
     }
   },
   emits: ['update:visible', 'closed', 'click'],

+ 7 - 7
src/packages/__VUE/notify/index.ts

@@ -2,18 +2,18 @@ import { createVNode, render, h, onMounted } from 'vue';
 import Notify from './index.vue';
 const defaultOptions = {
   type: 'base',
-  showPopup: true,
+  // showPopup: true,
   visible: true,
   msg: '',
   color: undefined,
   background: undefined,
   duration: 3000,
-  className: '',
-  onClosed: null,
-  onClick: null,
-  onOpened: null,
-  textTimer: null,
-  unmount: null
+  className: ''
+  // onClosed: null,
+  // onClick: null,
+  // onOpened: null,
+  // textTimer: null,
+  // unmount: null
 };
 
 let idsMap: string[] = [];

+ 7 - 7
src/packages/__VUE/notify/index.vue

@@ -36,14 +36,14 @@ export default create({
       type: String,
       default: 'danger'
     },
-    showPopup: {
-      type: Boolean,
-      default: false
-    },
-    // visible: {
+    // showPopup: {
     //   type: Boolean,
     //   default: false
     // },
+    modelVisible: {
+      type: Boolean,
+      default: false
+    },
     position: {
       type: String,
       default: 'top'
@@ -66,7 +66,7 @@ export default create({
       // state.mounted = true;
     });
 
-    const visible = ref(false);
+    const showPopup = ref(props.modelVisible);
 
     const clickCover = () => {
       props.onClick && props.onClick();
@@ -113,7 +113,7 @@ export default create({
       props.unmount && props.unmount(props.id);
       props.onClose && props.onClose();
     };
-    return { state, hide, onAfterLeave, clickCover, visible };
+    return { state, hide, onAfterLeave, clickCover, showPopup };
   }
 });
 </script>

+ 0 - 20
src/packages/__VUE/signature/doc.md

@@ -50,26 +50,6 @@ export default {
     }
 }
 </script>
-<script>
-import { reactive } from 'vue';
-export default {
-  props: {},
-  setup() {
-    const confirm = (canvas, data) => {
-        let img = document.createElement('img');
-        img.src = data;
-        document.querySelector('.demo').appendChild(img);
-    };
-    const clear = () => {
-        let img = document.querySelector('.demo img'); 
-        if (img) {
-            img.remove();
-        }
-    }
-    return { confirm, clear };
-  }
-};
-</script>
 ```
 :::
 ### 修改颜色和签字粗细

+ 4 - 4
src/packages/__VUE/signature/index.taro.vue

@@ -19,7 +19,7 @@
   </div>
 </template>
 <script lang="ts">
-import Taro from '@tarojs/taro';
+import Taro, { eventCenter, getCurrentInstance as getCurrentInstanceTaro } from '@tarojs/taro';
 import { ref, reactive, onMounted, computed } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 const { componentName, create, translate } = createComponent('signature');
@@ -58,7 +58,7 @@ export default create({
         [`${props.customClass}`]: props.customClass
       };
     });
-    const state = reactive({
+    const state: any = reactive({
       canvas: null,
       canvasHeight: 0,
       canvasWidth: 0,
@@ -124,7 +124,7 @@ export default create({
     };
 
     onMounted(() => {
-      setTimeout(() => {
+      eventCenter.once((getCurrentInstanceTaro() as any).router.onReady, () => {
         Taro.createSelectorQuery()
           .select('#spcanvas')
           .fields(
@@ -142,7 +142,7 @@ export default create({
             }
           )
           .exec();
-      }, 500);
+      });
     });
     return {
       confirm,

+ 2 - 2
src/packages/__VUE/signature/index.vue

@@ -1,8 +1,8 @@
 <template>
   <div :class="classes">
     <div class="nut-signature-inner" ref="wrap">
-      <canvas ref="canvas" :height="canvasHeight" :width="canvasWidth" v-if="() => isCanvasSupported()"></canvas>
-      <p class="nut-signature-unsopport" v-else>{{ unSupportTpl || translate('unSupportTpl') }}</p>
+      <canvas ref="canvas" :height="canvasHeight" :width="canvasWidth" v-show="isCanvasSupported()"></canvas>
+      <p class="nut-signature-unsopport" v-if="!isCanvasSupported()">{{ unSupportTpl || translate('unSupportTpl') }}</p>
     </div>
 
     <nut-button class="nut-signature-btn" type="default" @click="clear()">{{ translate('reSign') }}</nut-button>

+ 6 - 0
src/packages/__VUE/textarea/index.scss

@@ -44,5 +44,11 @@
     background-color: transparent;
     border: 0;
     resize: none;
+    line-height: 20px;
+  }
+  .cpoyText {
+    position: absolute;
+    top: -999999px;
+    left: -999999px;
   }
 }

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

@@ -20,6 +20,7 @@
       :auto-focus="autofocus"
     />
     <view class="nut-textarea__limit" v-if="limitShow"> {{ modelValue ? modelValue.length : 0 }}/{{ maxLength }}</view>
+    <view class="cpoyText" :style="copyTxtStyle" v-if="autosize">{{ modelValue }}</view>
   </view>
 </template>
 <script lang="ts">
@@ -91,6 +92,11 @@ export default create({
       };
     });
 
+    const copyTxtStyle: any = ref({
+      'word-break': 'break-all',
+      width: '0'
+    });
+
     const emitChange = (value: string, event: Event) => {
       if (props.maxLength && value.length > Number(props.maxLength)) {
         value = value.substring(0, Number(props.maxLength));
@@ -148,11 +154,28 @@ export default create({
       () => props.modelValue,
       () => {
         if (props.autosize) {
-          nextTick(getContentHeight);
+          copyHeight();
         }
       }
     );
 
+    const copyHeight = () => {
+      const query = Taro.createSelectorQuery();
+      query.select('.cpoyText').boundingClientRect();
+      query.exec((res) => {
+        if (res[0]) {
+          if (props.modelValue == '') {
+            textareaHeight.value = 20;
+          } else {
+            textareaHeight.value = res[0]['height'] || 20;
+          }
+          setTimeout(() => {
+            getContentHeight();
+          }, 400);
+        }
+      });
+    };
+
     const getRefHeight = () => {
       const query = Taro.createSelectorQuery();
       // const query = Taro.createSelectorQuery();
@@ -161,7 +184,9 @@ export default create({
       query.exec((res) => {
         if (res[0] && textareaRef.value) {
           let _item: any = Array.from(res[0]).filter((item: any) => item.id == uid);
-          textareaHeight.value = _item[0]['height'] || 30;
+          textareaHeight.value = _item[0]['height'] || 20;
+          copyTxtStyle.value.width = _item[0]['width'] + 'px';
+          nextTick(getContentHeight);
         }
       });
     };
@@ -170,10 +195,10 @@ export default create({
       if (props.autosize) {
         eventCenter.once((getCurrentInstanceTaro() as any).router.onReady, () => {
           getRefHeight();
+          // setTimeout(() => {
+          //   nextTick(getContentHeight);
+          // }, 300);
         });
-        setTimeout(() => {
-          nextTick(getContentHeight);
-        }, 300);
       }
     });
 
@@ -184,7 +209,8 @@ export default create({
       change,
       focus,
       blur,
-      translate
+      translate,
+      copyTxtStyle
     };
   }
 });

+ 1 - 2
src/sites/mobile-taro/vue/project.config.json

@@ -39,8 +39,7 @@
     "minifyWXML": true,
     "showES6CompileOption": false,
     "useCompilerPlugins": false,
-    "ignoreUploadUnusedFiles": true,
-    "useStaticServer": true
+    "ignoreUploadUnusedFiles": true
   },
   "compileType": "miniprogram",
   "simulatorType": "wechat",

+ 5 - 4
src/sites/mobile-taro/vue/project.private.config.json

@@ -7,9 +7,10 @@
     "miniprogram": {
       "list": [
         {
-          "name": "business/pages/address/index",
-          "pathName": "business/pages/address/index",
+          "name": "feedback/pages/notify/index",
+          "pathName": "feedback/pages/notify/index",
           "query": "",
+          "launchMode": "default",
           "scene": null
         },
         {
@@ -31,8 +32,8 @@
           "scene": null
         },
         {
-          "name": "exhibition/pages/ellipsis/index",
-          "pathName": "exhibition/pages/ellipsis/index",
+          "name": "business/pages/signature/index",
+          "pathName": "business/pages/signature/index",
           "query": "",
           "launchMode": "default",
           "scene": null

+ 24 - 35
src/sites/mobile-taro/vue/src/feedback/pages/notify/index.vue

@@ -1,9 +1,7 @@
 <template>
   <div class="demo">
     <nut-cell-group :title="baseState.state.desc">
-      <nut-cell is-Link @click="baseState.methods.cellClick">{{
-        baseState.state.desc
-      }}</nut-cell>
+      <nut-cell is-Link @click="baseState.methods.cellClick">{{ baseState.state.desc }}</nut-cell>
       <nut-notify
         @click="onClick"
         @closed="onClosed"
@@ -20,26 +18,10 @@
         v-model:visible="notifyState.state.show"
         :msg="notifyState.state.desc"
       />
-      <nut-cell
-        is-Link
-        @click="notifyState.methods.cellClick('primary', '主要通知')"
-        >主要通知</nut-cell
-      >
-      <nut-cell
-        is-Link
-        @click="notifyState.methods.cellClick('success', '成功通知')"
-        >成功通知</nut-cell
-      >
-      <nut-cell
-        is-Link
-        @click="notifyState.methods.cellClick('danger', '危险通知')"
-        >危险通知</nut-cell
-      >
-      <nut-cell
-        is-Link
-        @click="notifyState.methods.cellClick('warning', '警告通知')"
-        >警告通知</nut-cell
-      >
+      <nut-cell is-Link @click="notifyState.methods.cellClick('primary', '主要通知')">主要通知</nut-cell>
+      <nut-cell is-Link @click="notifyState.methods.cellClick('success', '成功通知')">成功通知</nut-cell>
+      <nut-cell is-Link @click="notifyState.methods.cellClick('danger', '危险通知')">危险通知</nut-cell>
+      <nut-cell is-Link @click="notifyState.methods.cellClick('warning', '警告通知')">警告通知</nut-cell>
     </nut-cell-group>
     <nut-cell-group title="自定义样式">
       <nut-notify
@@ -52,26 +34,24 @@
         :msg="customState.state.desc"
         :duration="customState.state.duration"
       />
-      <nut-cell
-        is-Link
-        @click="
-          customState.methods.cellClick('primary', '自定义背景色和字体颜色')
-        "
-      >
+      <nut-cell is-Link @click="customState.methods.cellClick('primary', '自定义背景色和字体颜色')">
         自定义背景色和字体颜色
       </nut-cell>
-      <nut-cell
-        is-Link
-        @click="customState.methods.cellClick('primary', '自定义时长5s', 5000)"
-      >
+      <nut-cell is-Link @click="customState.methods.cellClick('primary', '自定义时长5s', 5000)">
         自定义时长5s
       </nut-cell>
     </nut-cell-group>
+    <nut-cell-group title="组件调用">
+      <nut-cell is-Link @click="showNotify">组件调用</nut-cell>
+      <nut-notify v-model:visible="show">
+        <span>Content</span>
+      </nut-notify>
+    </nut-cell-group>
   </div>
 </template>
 
 <script lang="ts">
-import { reactive } from 'vue';
+import { reactive, ref } from 'vue';
 export default {
   setup() {
     const onClosed = () => console.log('closed');
@@ -119,12 +99,21 @@ export default {
         }
       }
     };
+    const show = ref(false);
+    const showNotify = () => {
+      show.value = true;
+      setTimeout(() => {
+        show.value = false;
+      }, 2000);
+    };
     return {
       baseState,
       notifyState,
       customState,
       onClosed,
-      onClick
+      onClick,
+      show,
+      showNotify
     };
   }
 };