Browse Source

fix(barrage): barrage 样式报错,H5环境 slot 插槽适配 (#1771)

* 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小程序自适应高度功能

* fix: 折叠面板优化

* feat: 组件支持暗黑模式

* feat(signature): signature 组件增加签名开始,结束,进行中回调函数

* docs: 文档修改

* fix: textarea 适配支付宝小程序

* feat: searchbar 新增自定义清除图标功能

* feat: 新增聚焦自定义样式

* fix: ts 问题修正,demo 同步。单元测试排错

* feat: barrage 增加slot模式,demo及文档完善

* fix: 弹幕兼容

* fix: barrage 优化

* feat: searchbar 新增自定义清除图标功能

* fix: barrage 样式报错,H5环境 slot 插槽适配

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

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

@@ -6,7 +6,7 @@
     </nut-cell>
     <h2>{{ translate('slotTitle') }}</h2>
     <nut-cell>
-      <nut-barrage ref="danmu">
+      <nut-barrage>
         <span>aaa</span>
         <span>bbb</span>
         <span>ccc</span>

+ 2 - 0
src/packages/__VUE/barrage/doc.en-US.md

@@ -58,6 +58,8 @@ export default {
 
 ### slot usage
 
+> Using the slot requires putting the scrolling content inside the html tag, the applet environment is not currently supported
+
 :::demo
 
 ```html

+ 2 - 0
src/packages/__VUE/barrage/doc.md

@@ -58,6 +58,8 @@ export default {
 
 ### slot 用法
 
+> 使用插槽需要将滚动内容放在html标签内,小程序环境暂不支持
+
 :::demo
 
 ```html

+ 0 - 8
src/packages/__VUE/barrage/index.scss

@@ -1,11 +1,3 @@
-.slotContainer {
-  > * {
-    opacity: 0;
-  }
-  > .dmitem {
-    opacity: 1;
-  }
-}
 .nut-barrage {
   position: absolute;
   left: 0;

+ 46 - 29
src/packages/__VUE/barrage/index.taro.vue

@@ -1,6 +1,19 @@
 <template>
   <view class="dmBody" :class="classes">
-    <div ref="dmContainer" class="dmContainer slotContainer" v-if="$slots.default">
+    <div ref="dmContainer" :class="['dmContainer', $slots.default && 'slotContainer']">
+      <div :class="['slotBody', 'slotBody' + classTime]">
+        <!-- <slot></slot> -->
+        <view
+          v-for="(item, index) of danmuList"
+          :key="'danmu' + index"
+          :class="['dmitem', 'dmitem' + index, 'move']"
+          :style="styleList[index]"
+        >
+          {{ item.length > 8 ? item.substr(0, 8) + '...' : item }}
+        </view>
+      </div>
+    </div>
+    <!-- <div ref="dmContainer" class="dmContainer slotContainer" v-if="$slots.default">
       <slot></slot>
       <view
         v-for="(item, index) of danmuListSlots"
@@ -10,8 +23,8 @@
       >
         {{ item.length > 8 ? item.substr(0, 8) + '...' : item }}
       </view>
-    </div>
-    <view class="dmContainer" id="dmContainer" v-else>
+    </div> -->
+    <!-- <view class="dmContainer" id="dmContainer">
       <view
         v-for="(item, index) of danmuList"
         :key="'danmu' + index"
@@ -20,7 +33,7 @@
       >
         {{ item.length > 8 ? item.substr(0, 8) + '...' : item }}
       </view>
-    </view>
+    </view> -->
   </view>
 </template>
 <script lang="ts">
@@ -59,6 +72,8 @@ export default create({
   emits: ['click'],
 
   setup(props, { slots }) {
+    const classTime = new Date().getTime();
+
     const slotDefault = !!useSlots().default;
 
     const timeId = ref(new Date().getTime());
@@ -78,11 +93,13 @@ export default create({
 
     onMounted(() => {
       if (slotDefault) {
-        danmuList.value = slots?.default?.();
-        runStep();
-      } else {
-        runStep();
+        const list = document.getElementsByClassName('slotBody' + classTime)[0].getElementsByClassName('dmitem');
+        console.log(list);
+
+        let childrens = list?.[0]?.children || [];
+        danmuList.value = childrens;
       }
+      runStep();
     });
 
     onUnmounted(() => {
@@ -123,27 +140,27 @@ export default create({
     };
 
     const runStep = () => {
-      danmuList.value.forEach((item, index: number) => {
-        let el = danmuList.value[index]?.el;
-        if (!el) {
-          danmuListSlots.value.push(item);
-          let l = slotDefault ? String(danmuList.value.length) : '';
-          let s = l + danmuListSlots.value.indexOf(item);
-          getNode(Number(s));
+      danmuList.value.forEach((item: any, index: number) => {
+        // let el = danmuList.value[index];
+        if (typeof danmuList.value[index] == 'object') {
+          // danmuListSlots.value.push(item);
+          // let l = slotDefault ? String(danmuList.value.length) : '';
+          // let s = l + danmuListSlots.value.indexOf(item);
+          getNode(index);
         } else {
-          if (el?.classList.contains('dmitem')) {
-            el.classList.remove('dmitem');
-          }
-          if (el?.classList.contains('dmitem' + index)) {
-            el.classList.remove('dmitem' + index);
-          }
-          if (slotDefault && el) {
-            if (el?.classList.contains('move')) {
-              el.classList.remove('move');
-            }
-            el.classList.add('.move');
-          }
-          el.classList.add('.dmitem .dmitem' + index);
+          // if (el?.classList.contains('dmitem')) {
+          //   el.classList.remove('dmitem');
+          // }
+          // if (el?.classList.contains('dmitem' + index)) {
+          //   el.classList.remove('dmitem' + index);
+          // }
+          // if (slotDefault && el) {
+          //   if (el?.classList.contains('move')) {
+          //     el.classList.remove('move');
+          //   }
+          //   el.classList.add('.move');
+          // }
+          // el.classList.add('.dmitem .dmitem' + index);
           getNode(index);
         }
       });
@@ -173,7 +190,7 @@ export default create({
       }
     };
 
-    return { classes, danmuList, add, styleList, distance, danmuListSlots };
+    return { classTime, classes, danmuList, add, styleList, distance, danmuListSlots };
   }
 });
 </script>

+ 32 - 15
src/packages/__VUE/barrage/index.vue

@@ -1,9 +1,10 @@
 <template>
   <div ref="dmBody" :class="classes">
-    <div ref="dmContainer" class="dmContainer slotContainer" v-if="$slots.default">
-      <slot></slot>
+    <div ref="dmContainer" :class="['dmContainer', $slots.default && 'slotContainer']">
+      <div :class="['slotBody', 'slotBody' + classTime]" v-if="$slots.default">
+        <slot></slot>
+      </div>
     </div>
-    <div ref="dmContainer" class="dmContainer" v-else></div>
   </div>
 </template>
 <script lang="ts">
@@ -12,6 +13,7 @@ import { createComponent } from '@/packages/utils/create';
 const { componentName, create } = createComponent('barrage');
 
 export default create({
+  name: 'barrage',
   props: {
     danmu: {
       type: Array,
@@ -41,6 +43,7 @@ export default create({
   emits: ['click'],
 
   setup(props, { slots }) {
+    const classTime = new Date().getTime();
     const slotDefault = !!useSlots().default;
 
     const classes = computed(() => {
@@ -64,19 +67,30 @@ export default create({
     onMounted(() => {
       danmuCWidth.value = dmBody.value.offsetWidth;
       if (slotDefault) {
-        danmuList.value = slots?.default?.();
-        run();
-      } else {
-        run();
+        const list = document.getElementsByClassName('slotBody' + classTime);
+        let childrens = list?.[0]?.children || [];
+        const dmList: any[] = [];
+        if (childrens) {
+          Array.from(childrens).forEach((item: any) => {
+            item.style.opacity = '0';
+            dmList.push(item);
+          });
+        }
+        danmuList.value = dmList;
       }
+      setTimeout(() => {
+        run();
+      }, 300);
     });
 
     onUnmounted(() => {
+      danmuList.value = [];
       clearInterval(timer);
       timer = 0;
     });
 
     onDeactivated(() => {
+      danmuList.value = [];
       clearInterval(timer);
       timer = 0;
     });
@@ -113,30 +127,33 @@ export default create({
         return;
       }
       const _index = props.loop ? index.value % danmuList.value.length : index.value;
-      let el = document.createElement(`div`);
-      if (slotDefault && danmuList.value[_index]?.el) {
-        el = danmuList.value[_index]?.el;
-        if (el?.classList.contains('dmitem')) {
+      let el = document.createElement(`view`);
+
+      if (slotDefault && typeof danmuList.value[_index] == 'object') {
+        el = danmuList.value[_index];
+        if (el?.classList?.contains('dmitem')) {
           el.classList.remove('dmitem');
         }
-        if (el?.classList.contains('move')) {
+        if (el?.classList?.contains('move')) {
           el.classList.remove('move');
         }
-        el?.classList.add('dmitem');
+        el?.classList?.add('dmitem');
       } else {
         el.innerHTML = danmuList.value[_index] as string;
         el.classList.add('dmitem');
         dmContainer.value.appendChild(el);
       }
+
       // let el = document.createElement(`div`);
       // el.innerHTML = danmuList.value[_index] as string;
       // el.classList.add('dmitem');
       // dmContainer.value.appendChild(el);
       nextTick(() => {
         const height = el.offsetHeight;
-        el.classList.add('move');
+        el?.classList?.add('move');
         el.style.animationDuration = `${speeds}ms`;
         el.style.top = (_index % rows.value) * (height + top.value) + 20 + 'px';
+        el.style.opacity = '1';
         if (!slotDefault) {
           const width = el.offsetWidth;
           el.style.width = width + 20 + 'px';
@@ -155,7 +172,7 @@ export default create({
         }
       });
     };
-    return { classes, danmuList, dmBody, dmContainer, add, distance };
+    return { classTime, classes, danmuList, dmBody, dmContainer, add, distance };
   }
 });
 </script>

+ 1 - 1
src/packages/__VUE/searchbar/__tests__/searchbar.spec.ts

@@ -167,7 +167,7 @@ test('slot test', () => {
   expect(wrapper.html()).toMatchSnapshot();
 });
 
-test('custom clear icon', async () => {
+test('custom clear icon', () => {
   const wrapper = mount(SearchBar, {
     props: {
       clearIcon: 'close',

+ 4 - 6
src/packages/__VUE/searchbar/demo.vue

@@ -28,7 +28,7 @@
     </nut-searchbar>
 
     <h2>{{ translate('basic7') }}</h2>
-    <nut-searchbar v-model="searchValue6" :clear-icon="icon2"> </nut-searchbar>
+    <nut-searchbar v-model="searchValue6" :clear-icon="icon"> </nut-searchbar>
 
     <h2>{{ translate('basic6') }}</h2>
     <nut-searchbar v-model="searchValue5" @click-right-icon="clickRightIcon">
@@ -63,7 +63,7 @@ const initTranslate = () =>
       basic4: '右侧添加搜索文字',
       basic5: '更改输入框内部及外部的背景样式',
       basic6: '显示全部 icon',
-      basic7: '自定义清除按钮 icon',
+      basic7: '自定义清除图标 icon',
       word1: '标签',
       word2: '搜索',
       title3: '标题3'
@@ -75,7 +75,7 @@ const initTranslate = () =>
       basic4: 'Add search text to the right',
       basic5: 'Change the background style inside and outside the input box',
       basic6: 'Show all icons',
-      basic7: 'custom clear button icons',
+      basic7: 'custom clear button icon',
       word1: 'label',
       word2: 'search'
     }
@@ -83,8 +83,7 @@ const initTranslate = () =>
 export default createDemo({
   props: {},
   setup() {
-    const icon = 'close';
-    const icon2 =
+    const icon =
       'https://img10.360buyimg.com/imagetools/jfs/t1/170133/30/22902/10546/61833626E32d7ccde/a7c373ba30de9a89.png';
     initTranslate();
     const state = reactive({
@@ -113,7 +112,6 @@ export default createDemo({
 
     return {
       icon,
-      icon2,
       clickLeft,
       clickLeftIcon,
       clickRightIcon,

+ 3 - 3
src/packages/__VUE/searchbar/doc.md

@@ -160,11 +160,11 @@ app.use(Icon);
   import { toRefs, reactive } from 'vue';
   export default {
     setup() {
+      const icon = 
+      'https://img10.360buyimg.com/imagetools/jfs/t1/170133/30/22902/10546/61833626E32d7ccde/a7c373ba30de9a89.png';
       const state = reactive({
         searchValue: ""
       });
-      const icon =
-      'https://img10.360buyimg.com/imagetools/jfs/t1/170133/30/22902/10546/61833626E32d7ccde/a7c373ba30de9a89.png';
 
       return {
         ...toRefs(state),
@@ -225,7 +225,7 @@ app.use(Icon);
 | input-type    | 输入框类型   | String | 'text'      |
 | placeholder        | 输入框默认暗纹  | String | '请输入'   |
 | clearable          | 是否展示清除按钮 | Boolean | true     |
-| close-icon `v3.2.2`     | 自定义关闭图标 | String | 'circle-close'   |
+| clear-icon `v3.2.2`         | 自定义清除按钮图标 | String | "circle-close"     |
 | background      | 输入框外部背景 | String |   '#fff'   |
 | input-background   | 输入框内部背景 | String |   '#f7f7f7'   |
 | confirm-type   | 键盘右下角按钮的文字(`仅支持小程序`),仅在`type='text'`时生效,可选值 `send`:发送、`search`:搜索、`next`:下一个、`go`:前往、`done`:完成 | String |   `done`   |

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

@@ -14,9 +14,10 @@
           "scene": null
         },
         {
-          "name": "pages/index/index",
-          "pathName": "pages/index/index",
+          "name": "business/pages/barrage/index",
+          "pathName": "business/pages/barrage/index",
           "query": "",
+          "launchMode": "default",
           "scene": null
         },
         {

+ 3 - 3
src/sites/mobile-taro/vue/src/business/pages/barrage/index.vue

@@ -4,15 +4,15 @@
     <nut-cell>
       <nut-barrage ref="danmu" :danmu="list"></nut-barrage>
     </nut-cell>
-    <h2>slot 用法</h2>
+    <!-- <h2>slot 用法</h2>
     <nut-cell>
-      <nut-barrage ref="danmu">
+      <nut-barrage>
         <span>aaa</span>
         <span>bbb</span>
         <span>ccc</span>
         <span>ddd</span>
       </nut-barrage>
-    </nut-cell>
+    </nut-cell> -->
     <div class="test">
       <button @click="addDanmu" class="add nut-button--primary">随机添加</button>
     </div>