Browse Source

feat: 新增collapse组件自定义内容(不折叠)功能;fix: notify 单元测试优化 (#1235)

* fix: notify 单元测试优化
Ymm 3 years ago
parent
commit
75d22c3677

+ 16 - 1
src/packages/__VUE/collapse/demo.vue

@@ -29,7 +29,6 @@
       </nut-collapse-item>
     </nut-collapse>
     <h2>自定义折叠图标</h2>
-
     <nut-collapse v-model:active="active3" :accordion="true" icon="arrow-right2" rotate="90">
       <nut-collapse-item :title="title1" :name="1">
         <template v-slot:sTitle> 文本测试 </template>
@@ -54,6 +53,16 @@
         使用 Teleport 新特性重构挂载类组件
       </nut-collapse-item>
     </nut-collapse>
+    <h2>设置固定内容(不折叠)</h2>
+    <nut-collapse v-model:active="active6" icon="down-arrow" :accordion="true">
+      <nut-collapse-item :title="title1" :name="1">
+        <template v-slot:extraRender>固定内容</template>
+        NutUI是一套拥有京东风格的轻量级的 Vue 组件库
+      </nut-collapse-item>
+      <nut-collapse-item :title="title2" :name="2">
+        在产品的功能、体验、易用性和灵活性等各个方面做了全面的升级!
+      </nut-collapse-item>
+    </nut-collapse>
   </div>
 </template>
 <script lang="ts">
@@ -68,6 +77,7 @@ export default createDemo({
       active3: 1,
       active4: 1,
       active5: 1,
+      active6: 1,
       title1: '标题1',
       title2: '标题2',
       title3: '标题3',
@@ -83,3 +93,8 @@ export default createDemo({
   }
 });
 </script>
+<style lang="scss">
+.nut-collapse-item .collapse-extraWrapper .collapse-extraRender {
+  color: red;
+}
+</style>

+ 36 - 0
src/packages/__VUE/collapse/doc.md

@@ -221,6 +221,41 @@ export default {
 </script>
 ```
 :::
+### 设置固定内容(不折叠)
+
+通过 slot:extraRender 设置内容
+:::demo
+
+```html
+<template>
+  <nut-collapse v-model:active="activeName" icon="down-arrow" :accordion="true">
+    <nut-collapse-item :title="title1" :name="1">
+      <template v-slot:extraRender>固定内容</template>
+      NutUI是一套拥有京东风格的轻量级的 Vue 组件库
+    </nut-collapse-item>
+    <nut-collapse-item :title="title2" :name="2">
+      在产品的功能、体验、易用性和灵活性等各个方面做了全面的升级!
+    </nut-collapse-item>
+  </nut-collapse>
+</template>
+<script>
+import { reactive, ref, toRefs } from 'vue';
+export default {
+  setup() {
+    const activeName = ref(1);
+    const title = reactive({
+      title1: '标题1',
+      title2: '标题2',
+    })
+    return {
+      activeName,
+      ...toRefs(title)
+    };
+  }
+}
+</script>
+```
+:::
 ## Collapse Prop
 
 | 字段 | 说明 | 类型 | 默认值
@@ -244,6 +279,7 @@ export default {
 | title | 标题栏左侧内容,支持插槽传入(props传入的优先级更高) | string | - |
 | sub-title | 标题栏副标题,支持插槽传入(props传入的优先级更高) | string | - |
 | disabled | 标题栏是否禁用 | boolean | false |
+| slot:extraRender | 设置标题下固定内容(不折叠) | - | ’‘ |
 
 
 ### Events

+ 12 - 2
src/packages/__VUE/collapseitem/index.scss

@@ -68,13 +68,15 @@
   // .extraRender {
   //   display: block;
   // }
-  .collapse-wrapper {
+  .collapse-wrapper,
+  .collapse-extraWrapper {
     display: block;
     position: relative;
     height: 0;
     overflow: hidden;
     transition: height 0.3s ease-in-out;
-    .collapse-content {
+    .collapse-content,
+    .collapse-extraRender {
       display: block;
       padding: $collapse-wrapper-content-padding;
       color: $collapse-wrapper-content-color;
@@ -86,6 +88,14 @@
       padding: $collapse-wrapper-empty-content-padding;
     }
   }
+  .collapse-extraWrapper {
+    height: auto;
+    .collapse-extraRender {
+      word-wrap: break-word;
+      word-break: break-all;
+      overflow: hidden;
+    }
+  }
   .open-style {
     will-change: height;
     height: auto;

+ 5 - 0
src/packages/__VUE/collapseitem/index.taro.vue

@@ -36,6 +36,11 @@
         :style="iconStyle"
       ></nut-icon>
     </view>
+    <view v-if="$slots.extraRender" class="collapse-extraWrapper">
+      <div class="collapse-extraRender">
+        <slot name="extraRender"></slot>
+      </div>
+    </view>
     <view
       :class="['collapse-wrapper', openExpanded ? 'open-style' : 'close-style']"
       ref="wrapperRef"

+ 5 - 0
src/packages/__VUE/collapseitem/index.vue

@@ -34,6 +34,11 @@
         :style="iconStyle"
       ></nut-icon>
     </view>
+    <view v-if="$slots.extraRender" class="collapse-extraWrapper">
+      <div class="collapse-extraRender">
+        <slot name="extraRender"></slot>
+      </div>
+    </view>
     <view class="collapse-wrapper" ref="wrapperRef">
       <view :class="['collapse-content', emptyContent]" ref="contentRef">
         <slot></slot>

+ 5 - 5
src/packages/__VUE/notify/__test__/function.spec.ts

@@ -13,7 +13,7 @@ describe('function notify', () => {
       color: '#ad0000',
       background: '#ffe1e1'
     });
-    let textNotify = document.querySelector('.nut-notify') as HTMLElement;
+    const textNotify = document.querySelector('.nut-notify') as HTMLElement;
     expect(textNotify.innerHTML).toContain('基础用法');
     expect(textNotify.style.color).toEqual('rgb(173, 0, 0)');
     expect(textNotify.style.background).toEqual('rgb(255, 225, 225)');
@@ -24,7 +24,7 @@ describe('function notify', () => {
     NotifyFunction.primary('主要通知', {
       duration: 500
     });
-    let textNotify1 = document.querySelector('.nut-notify--primary') as HTMLElement;
+    const textNotify1 = document.querySelector('.nut-notify--primary') as HTMLElement;
     expect(textNotify1.innerHTML).toContain('主要通知');
     await sleep(500);
     expect(textNotify1.style.display).toEqual('');
@@ -33,7 +33,7 @@ describe('function notify', () => {
     NotifyFunction.success('成功通知', {
       duration: 500
     });
-    let textNotify1 = document.querySelector('.nut-notify--success') as HTMLElement;
+    const textNotify1 = document.querySelector('.nut-notify--success') as HTMLElement;
     expect(textNotify1.innerHTML).toContain('成功通知');
     await sleep(500);
     expect(textNotify1.style.display).toEqual('');
@@ -42,7 +42,7 @@ describe('function notify', () => {
     NotifyFunction.danger('危险通知', {
       duration: 500
     });
-    let textNotify1 = document.querySelector('.nut-notify--danger') as HTMLElement;
+    const textNotify1 = document.querySelector('.nut-notify--danger') as HTMLElement;
     expect(textNotify1.innerHTML).toContain('危险通知');
     await sleep(500);
     expect(textNotify1.style.display).toEqual('');
@@ -51,7 +51,7 @@ describe('function notify', () => {
     NotifyFunction.warn('警告通知', {
       duration: 500
     });
-    let textNotify1 = document.querySelector('.nut-notify--warning') as HTMLElement;
+    const textNotify1 = document.querySelector('.nut-notify--warning') as HTMLElement;
     expect(textNotify1.innerHTML).toContain('警告通知');
     await sleep(500);
     expect(textNotify1.style.display).toEqual('');

+ 11 - 4
src/packages/__VUE/notify/__test__/notify.spec.ts

@@ -3,13 +3,18 @@ import Notify from '../index.vue';
 
 describe('Notify', () => {
   test('base notify', () => {
-    const wrapper = mount(Notify);
-    const rate = wrapper.find('.nut-notify');
+    const wrapper = mount(Notify, {
+      props: {
+        isWrapTeleport: false
+      }
+    });
+    const rate = wrapper.find('.nut-popup').find('.nut-notify');
     expect(rate.exists()).toBe(true);
   });
   test('base notify message', async () => {
     const wrapper = mount(Notify, {
       props: {
+        isWrapTeleport: false,
         message: '测试文案'
       }
     });
@@ -18,6 +23,7 @@ describe('Notify', () => {
   test('should be displayed after setting the type', async () => {
     const wrapper = mount(Notify, {
       props: {
+        isWrapTeleport: false,
         type: 'warning'
       }
     });
@@ -28,17 +34,18 @@ describe('Notify', () => {
   test('should be displayed after setting the color and background', async () => {
     const wrapper = mount(Notify, {
       props: {
+        isWrapTeleport: false,
         color: 'rgb(173, 0, 0)',
         background: 'rgb(255, 225, 225)'
       }
     });
-    const notify = wrapper.find('.nut-notify');
+    const notify = wrapper.find('.nut-notify').find('.nut-notify');
     expect((notify.element as HTMLElement).style.color).toBe('rgb(173, 0, 0)');
     expect((notify.element as HTMLElement).style.background).toBe('rgb(255, 225, 225)');
   });
 
   test('should be displayed after setting the color and class-name', () => {
-    const wrapper = mount(Notify, { props: { 'class-name': 'xxx' } });
+    const wrapper = mount(Notify, { props: { isWrapTeleport: false, 'class-name': 'xxx' } });
     const rate = wrapper.findAll('.xxx');
     expect(rate.length).toBe(1);
   });

+ 28 - 12
src/packages/__VUE/notify/__test__/notify.ts

@@ -1,4 +1,4 @@
-import { createVNode, defineComponent, render, App } from 'vue';
+import { createVNode, defineComponent, render, h, onMounted } from 'vue';
 import Notify from '../index.vue';
 const defaultOptions = {
   type: 'base',
@@ -11,7 +11,7 @@ const defaultOptions = {
   onClosed: null,
   onClick: null,
   onOpened: null,
-  textTimer: null,
+  // textTimer: null,
   unmount: null
 };
 
@@ -67,15 +67,30 @@ const mountNotify = (opts: any) => {
   opts.id = _id;
   idsMap.push(opts.id);
   optsMap.push(opts);
-  const container = document.createElement('view');
-  container.id = opts.id;
-  const instance: any = createVNode(Notify, opts);
-  render(instance, container);
-  document.body.appendChild(container);
-  setTimeout(() => {
-    instance.showPopup = true;
-  }, 0);
-  return instance.component.ctx;
+  const root = document.createElement('view');
+  root.id = 'notify-' + opts.id;
+  const Wrapper = {
+    setup() {
+      // opts.onUpdate = (val: boolean) => {
+      //   console.log(val);
+      //   if (val == false) {
+      //     document.body.removeChild(root);
+      //   }
+      // };
+      opts.teleport = `#notify-${opts.id}`;
+      onMounted(() => {
+        setTimeout(() => {
+          document.body.removeChild(root);
+        }, opts.duration);
+      });
+      return () => {
+        return h(Notify, opts);
+      };
+    }
+  };
+  const instance: any = createVNode(Wrapper);
+  document.body.appendChild(root);
+  render(instance, root);
 };
 
 const errorMsg = (msg: string) => {
@@ -109,7 +124,8 @@ export const NotifyFunction = {
   hide() {
     clearNotify();
   },
-  install(app: App): void {
+  install(app: any): void {
+    app.use(Notify);
     app.config.globalProperties.$notify = NotifyFunction;
   }
 };

+ 1 - 1
src/packages/__VUE/notify/demo.vue

@@ -43,7 +43,7 @@ export default createDemo({
       });
     };
     const primaryNotify = (msg: string) => {
-      Notify.primary(msg, { duration: 10000 });
+      Notify.primary(msg, { duration: 1000 });
     };
     const successNotify = (msg: string) => {
       Notify.success(msg);

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

@@ -1,5 +1,5 @@
 <template>
-  <nut-popup v-model:visible="showPopup" :position="position" :overlay="false">
+  <nut-popup v-model:visible="showPopup" :position="position" :overlay="false" :isWrapTeleport="isWrapTeleport">
     <div
       :class="['nut-notify', `nut-notify--${type}`, className]"
       :style="{ color: color, background: background }"
@@ -48,6 +48,10 @@ export default create({
       type: String,
       default: 'top'
     },
+    isWrapTeleport: {
+      type: Boolean,
+      default: true
+    },
     onClose: Function,
     onClick: Function,
     unmount: Function

+ 11 - 0
src/sites/mobile-taro/vue/src/exhibition/pages/collapse/index.vue

@@ -46,6 +46,16 @@
         快看漫画与全球潮玩集合店X11达成战略合作
       </nut-collapse-item>
     </nut-collapse>
+    <h2>设置固定内容(不折叠部分)</h2>
+    <nut-collapse v-model:active="active6" icon="down-arrow" :accordion="true">
+      <nut-collapse-item :title="title1" :name="1">
+        <template v-slot:extraRender>固定内容</template>
+        NutUI是一套拥有京东风格的轻量级的 Vue 组件库
+      </nut-collapse-item>
+      <nut-collapse-item :title="title2" :name="2">
+        在产品的功能、体验、易用性和灵活性等各个方面做了全面的升级!
+      </nut-collapse-item>
+    </nut-collapse>
   </div>
 </template>
 <script lang="ts">
@@ -58,6 +68,7 @@ export default {
       active3: 1,
       active4: 1,
       active5: 1,
+      active6: 1,
       title1: '标题1',
       title2: '标题2',
       title3: '标题3',