Skip to content

Commit eaeb935

Browse files
fix: 🐛 修复NoticeBar通知栏在小程序端垂直滚动无效的问题
1 parent 6566892 commit eaeb935

File tree

4 files changed

+110
-131
lines changed

4 files changed

+110
-131
lines changed

docs/component/notice-bar.md

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -109,18 +109,10 @@ const onNext = (index: number) => {
109109

110110
1. `direction`传递`vertical`即可开启垂直滚动,目前仅支持一个方向的垂直滚动
111111
2. `text`为数组时才会进行滚动
112-
3. 垂直滚动时会提供`vertical`的插槽,该插槽传递`{item: any, index: number}`
113-
4. <u>**插槽内容不应该改变高度,例如设置 height、padding 等可能改变高度的样式,否则会导致滚动不准确**</u>
114112

115113
```html
116114
<wd-notice-bar prefix="warn-bold" direction="vertical" :text="textArray" :speed="0.5" :delay="3" custom-class="space" />
117115
<wd-notice-bar prefix="warn-bold" direction="vertical" text="只有一条消息不会滚动" :speed="0.5" :delay="3" custom-class="space" />
118-
<wd-notice-bar prefix="warn-bold" direction="vertical" :text="textArray" :speed="0.5" :delay="3">
119-
<template #vertical="{ item, index }">
120-
<!-- 插槽内容不应该改变高度,例如设置height、padding等可能改变高度的样式,否则会导致滚动不准确 -->
121-
<view style="font-weight: 700; text-decoration: underline">{{ index }}: {{ item }}</view>
122-
</template>
123-
</wd-notice-bar>
124116
```
125117

126118
## Attributes
@@ -148,11 +140,11 @@ const onNext = (index: number) => {
148140

149141
## Slot
150142

151-
| name | 说明 | 类型 | 最低版本 |
152-
| -------- | -------------------- | ---------------------------- | -------- |
153-
| prefix | 前置图标 | - | - |
154-
| suffix | 后置插槽 | - | - |
155-
| vertical | 垂直滚动时提供的插槽 | `{item: any, index: number}` | - |
143+
| name | 说明 | 类型 | 最低版本 |
144+
| ------- | ------------ | ---- | -------- |
145+
| prefix | 前置图标 | - | - |
146+
| suffix | 后置插槽 | - | - |
147+
| default | 通知文本内容 | - | - |
156148

157149
## 外部样式类
158150

src/components/page-wraper/page-wraper.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<slot />
1212
</view>
1313
<wd-notify />
14+
<wd-gap height="0" safe-area-bottom></wd-gap>
1415
</wd-config-provider>
1516
</template>
1617
<script lang="ts">

src/pages/noticeBar/Index.vue

Lines changed: 59 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,79 @@
11
<!--
22
* @Author: weisheng
33
* @Date: 2023-06-13 11:47:12
4-
* @LastEditTime: 2023-08-07 20:24:04
4+
* @LastEditTime: 2024-04-09 21:48:26
55
* @LastEditors: weisheng
66
* @Description:
7-
* @FilePath: \wot-design-uni\src\pages\noticeBar\Index.vue
7+
* @FilePath: /wot-design-uni/src/pages/noticeBar/Index.vue
88
* 记得注释
99
-->
1010
<template>
1111
<page-wraper>
12-
<demo-block title="基本用法">
13-
<wd-notice-bar text="这是一条消息提示信息这是一条消息提示信息这是一条消息提示信息" prefix="warn-bold" />
14-
</demo-block>
12+
<view>
13+
<demo-block title="基本用法">
14+
<wd-notice-bar text="这是一条消息提示信息这是一条消息提示信息这是一条消息提示信息" prefix="warn-bold" />
15+
</demo-block>
1516

16-
<demo-block title="类型修改">
17-
<wd-notice-bar
18-
type="danger"
19-
text="当前网络不可用,请检查你的网络设置。当前网络不可用,请检查你的网络设置。"
20-
prefix="wifi-error"
21-
custom-class="space"
22-
/>
23-
<wd-notice-bar
24-
type="info"
25-
text="pc-win沃特已登录,可在“设备管理”中查看详情。pc-win沃特已登录,可在“设备管理”中查看详情。"
26-
prefix="check-outline"
27-
/>
28-
</demo-block>
17+
<demo-block title="类型修改">
18+
<wd-notice-bar
19+
type="danger"
20+
text="当前网络不可用,请检查你的网络设置。当前网络不可用,请检查你的网络设置。"
21+
prefix="wifi-error"
22+
custom-class="space"
23+
/>
24+
<wd-notice-bar
25+
type="info"
26+
text="pc-win沃特已登录,可在“设备管理”中查看详情。pc-win沃特已登录,可在“设备管理”中查看详情。"
27+
prefix="check-outline"
28+
/>
29+
</demo-block>
2930

30-
<demo-block title="禁止滚动">
31-
<wd-notice-bar :scrollable="false" text="通知被禁或时段内消息屏蔽可能造成消…" prefix="warn-bold"></wd-notice-bar>
32-
</demo-block>
31+
<demo-block title="禁止滚动">
32+
<wd-notice-bar :scrollable="false" text="通知被禁或时段内消息屏蔽可能造成消…" prefix="warn-bold"></wd-notice-bar>
33+
</demo-block>
3334

34-
<demo-block title="插槽">
35-
<wd-notice-bar :scrollable="false">
36-
<template #prefix>
37-
<wd-icon custom-class="prefix" name="warn-bold">占位符</wd-icon>
38-
</template>
39-
通知被禁或时段内消息屏蔽可能造成消…
40-
<template #suffix>
41-
<div style="color: #4d80f0">查看</div>
42-
</template>
43-
</wd-notice-bar>
44-
</demo-block>
35+
<demo-block title="插槽">
36+
<wd-notice-bar :scrollable="false">
37+
<template #prefix>
38+
<wd-icon custom-class="prefix" name="warn-bold">占位符</wd-icon>
39+
</template>
40+
通知被禁或时段内消息屏蔽可能造成消…
41+
<template #suffix>
42+
<div style="color: #4d80f0">查看</div>
43+
</template>
44+
</wd-notice-bar>
45+
</demo-block>
4546

46-
<demo-block title="可关闭的">
47-
<wd-notice-bar text="挂起后,电脑与手机均不会有新客户接入。挂起后,电脑与手机均不会有新客户接入。" closable prefix="warn-bold" />
48-
</demo-block>
47+
<demo-block title="可关闭的">
48+
<wd-notice-bar text="挂起后,电脑与手机均不会有新客户接入。挂起后,电脑与手机均不会有新客户接入。" closable prefix="warn-bold" />
49+
</demo-block>
4950

50-
<demo-block title="多行展示">
51-
<wd-notice-bar
52-
text="这是一条消息提示信息,这是一条消息提示信息,这是一条消息提示信息这是一条消息提示信息,这是一条消息提示信息,这是一条消息提示信息"
53-
wrapable
54-
:scrollable="false"
55-
/>
56-
</demo-block>
51+
<demo-block title="多行展示">
52+
<wd-notice-bar
53+
text="这是一条消息提示信息,这是一条消息提示信息,这是一条消息提示信息这是一条消息提示信息,这是一条消息提示信息,这是一条消息提示信息"
54+
wrapable
55+
:scrollable="false"
56+
/>
57+
</demo-block>
5758

58-
<demo-block title="自定义颜色">
59-
<wd-notice-bar
60-
text="这是一条消息提示信息,这是一条消息提示信息,这是一条消息提示信息"
61-
prefix="check-outline"
62-
color="#34D19D"
63-
background-color="#f0f9eb"
64-
></wd-notice-bar>
65-
</demo-block>
59+
<demo-block title="自定义颜色">
60+
<wd-notice-bar
61+
text="这是一条消息提示信息,这是一条消息提示信息,这是一条消息提示信息"
62+
prefix="check-outline"
63+
color="#34D19D"
64+
background-color="#f0f9eb"
65+
></wd-notice-bar>
66+
</demo-block>
6667

67-
<demo-block title="多文本轮播">
68-
<wd-notice-bar :text="textArray" prefix="check-outline" @next="onNext" />
69-
</demo-block>
68+
<demo-block title="多文本轮播">
69+
<wd-notice-bar :text="textArray" prefix="check-outline" @next="onNext" />
70+
</demo-block>
7071

71-
<demo-block title="垂直滚动">
72-
<wd-notice-bar prefix="warn-bold" direction="vertical" :text="textArray" :speed="0.5" :delay="3" custom-class="space" />
73-
<wd-notice-bar prefix="warn-bold" direction="vertical" text="只有一条消息不会滚动" :speed="0.5" :delay="3" custom-class="space" />
74-
<wd-notice-bar prefix="warn-bold" direction="vertical" :text="textArray" :speed="0.5" :delay="3">
75-
<template #vertical="{ item, index }">
76-
<!-- 插槽内容不应该改变高度,例如设置height、padding等可能改变高度的样式,否则会导致滚动不准确 -->
77-
<view style="font-weight: 700; text-decoration: underline">{{ index }}: {{ item }}</view>
78-
</template>
79-
</wd-notice-bar>
80-
</demo-block>
72+
<demo-block title="垂直滚动">
73+
<wd-notice-bar prefix="warn-bold" direction="vertical" :text="textArray" :delay="3" custom-class="space" />
74+
<wd-notice-bar prefix="warn-bold" direction="vertical" text="只有一条消息不会滚动" :delay="3" custom-class="space" />
75+
</demo-block>
76+
</view>
8177
</page-wraper>
8278
</template>
8379
<script lang="ts" setup>

src/uni_modules/wot-design-uni/components/wd-notice-bar/wd-notice-bar.vue

Lines changed: 45 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
<template>
2-
<view
3-
v-if="show"
4-
:class="`wd-notice-bar ${customClass} ${noticeBarClass}`"
5-
:style="`color: ${color}; background: ${backgroundColor};${customStyle}`"
6-
>
2+
<view v-if="show" :class="`wd-notice-bar ${customClass} ${noticeBarClass}`" :style="rootStyle">
73
<wd-icon v-if="prefix" custom-class="wd-notice-bar__prefix" size="18px" :name="prefix"></wd-icon>
84
<slot v-else name="prefix"></slot>
95
<view class="wd-notice-bar__wrap">
10-
<view class="wd-notice-bar__content" :animation="animation" @transitionend="animationEnd">
6+
<view class="wd-notice-bar__content" :style="animation" @transitionend="animationEnd">
117
<template v-if="isVertical">
12-
<slot v-for="(item, i) in textArray" :key="item" name="vertical" :item="item" :index="i">
13-
<view>{{ item }}</view>
14-
</slot>
15-
<slot v-if="textArray.length > 1" name="vertical" :item="textArray[0]" :index="0">
16-
<view>{{ textArray[0] }}</view>
17-
</slot>
8+
<view v-for="item in textArray" :key="item">{{ item }}</view>
9+
<view v-if="textArray.length > 1">{{ textArray[0] }}</view>
1810
</template>
1911
<slot v-else>{{ currentText }}</slot>
2012
</view>
@@ -35,12 +27,9 @@ export default {
3527
</script>
3628

3729
<script lang="ts" setup>
38-
import { onBeforeMount, ref, watch } from 'vue'
39-
import { getRect } from '../common/util'
40-
import { getCurrentInstance } from 'vue'
41-
import { nextTick } from 'vue'
30+
import { ref, watch, nextTick, computed, getCurrentInstance, type CSSProperties } from 'vue'
31+
import { getRect, isDef, objToStyle } from '../common/util'
4232
import { noticeBarProps } from './types'
43-
import { computed } from 'vue'
4433
4534
const $wrap = '.wd-notice-bar__wrap'
4635
const $content = '.wd-notice-bar__content'
@@ -51,37 +40,27 @@ const emit = defineEmits(['close', 'next'])
5140
const wrapWidth = ref<number>(0)
5241
const show = ref<boolean>(true)
5342
const animation = ref<string>('')
54-
const noticeBarClass = ref<string>('')
5543
const currentIndex = ref(0)
5644
const textArray = computed(() => (Array.isArray(props.text) ? props.text : [props.text]))
5745
const currentText = computed(() => textArray.value[currentIndex.value])
5846
const verticalIndex = ref(0)
5947
const isHorizontal = computed(() => props.direction === 'horizontal')
6048
const isVertical = computed(() => props.direction === 'vertical')
6149
62-
const { proxy } = getCurrentInstance() as any
63-
watch(
64-
[() => props.type, () => props.scrollable, () => props.wrapable],
65-
() => {
66-
computedClass()
67-
},
68-
{ deep: true, immediate: true }
69-
)
50+
const rootStyle = computed(() => {
51+
const style: CSSProperties = {}
52+
if (isDef(props.color)) {
53+
style.color = props.color
54+
}
7055
71-
watch(
72-
[() => props.text],
73-
() => {
74-
nextTick(() => scroll())
75-
},
76-
{ deep: true, immediate: true }
77-
)
56+
if (isDef(props.backgroundColor)) {
57+
style.background = props.backgroundColor
58+
}
7859
79-
onBeforeMount(() => {
80-
computedClass()
60+
return `${objToStyle(style)};${props.customStyle}`
8161
})
82-
83-
function computedClass() {
84-
const { type, wrapable, scrollable, direction } = props
62+
const noticeBarClass = computed(() => {
63+
const { type, wrapable, scrollable } = props
8564
8665
let noticeBarClasses: string[] = []
8766
type && noticeBarClasses.push(`is-${type}`)
@@ -93,22 +72,34 @@ function computedClass() {
9372
}
9473
9574
wrapable && !scrollable && noticeBarClasses.push('wd-notice-bar--wrap')
96-
noticeBarClass.value = noticeBarClasses.join(' ')
97-
}
75+
return noticeBarClasses.join(' ')
76+
})
77+
78+
const { proxy } = getCurrentInstance() as any
79+
80+
watch(
81+
[() => props.text],
82+
() => {
83+
nextTick(() => scroll())
84+
},
85+
{ deep: true, immediate: true }
86+
)
87+
9888
function handleClose() {
9989
show.value = false
10090
emit('close')
10191
}
10292
10393
function initAnimation({ duration, delay, translate }: { duration: number; delay: number; translate: number }) {
104-
const ani = uni
105-
.createAnimation({
106-
duration,
107-
delay
108-
})
109-
[isHorizontal.value ? 'translateX' : 'translateY'](translate)
110-
ani.step()
111-
return ani.export()
94+
const style: CSSProperties = {
95+
transitionProperty: 'all',
96+
transitionDelay: `${delay}s`,
97+
transitionDuration: `${duration}s`,
98+
transform: `${props.direction === 'vertical' ? 'translateY' : 'translateX'}(${translate}px)`,
99+
transitionTimingFunction: 'linear'
100+
}
101+
102+
return objToStyle(style)
112103
}
113104
114105
function queryRect() {
@@ -117,10 +108,9 @@ function queryRect() {
117108
118109
async function verticalAnimate(height: number) {
119110
const translate = -(height / (textArray.value.length + 1)) * (currentIndex.value + 1)
120-
121111
animation.value = initAnimation({
122-
duration: props.speed * 1000,
123-
delay: props.delay * 1000,
112+
duration: height / (textArray.value.length + 1) / props.speed,
113+
delay: props.delay,
124114
translate
125115
})
126116
}
@@ -134,8 +124,8 @@ async function scroll() {
134124
if (isHorizontal.value) {
135125
if (props.scrollable) {
136126
animation.value = initAnimation({
137-
duration: (contentRect.width / props.speed) * 1000,
138-
delay: props.delay * 1000,
127+
duration: contentRect.width / props.speed,
128+
delay: props.delay,
139129
translate: -contentRect.width
140130
})
141131
}
@@ -183,8 +173,8 @@ function animationEnd() {
183173
184174
if (isHorizontal.value) {
185175
animation.value = initAnimation({
186-
duration: ((wrapWidth.value + contentRect.width) / props.speed) * 1000,
187-
delay: props.delay * 1000,
176+
duration: (wrapWidth.value + contentRect.width) / props.speed,
177+
delay: props.delay,
188178
translate: -contentRect.width
189179
})
190180
} else {

0 commit comments

Comments
 (0)