Skip to content

Commit bf9e55a

Browse files
authored
feat: add backtop (#314)
* feat: add backtop * chore: rename index.vue -> Index.vue * chore: delete file
1 parent 83fa0b0 commit bf9e55a

File tree

10 files changed

+222
-1
lines changed

10 files changed

+222
-1
lines changed

docs/.vitepress/config.mts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ export default defineConfig({
247247
}, {
248248
link: "/component/sidebar",
249249
text: "Sidebar 侧边栏"
250+
}, {
251+
link: "/component/backtop",
252+
text: "Backtop 回到顶部"
250253
}]
251254
}, {
252255

@@ -427,4 +430,4 @@ export default defineConfig({
427430

428431
},
429432

430-
})
433+
})

docs/component/backtop.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<frame/>
2+
3+
# Backtop 回到顶部 `$LOWEST_VERSION$`
4+
5+
## 基本用法
6+
7+
由于返回顶部需要实时监听滚动条位置,但是在uniapp的组件中不能获取页面的滚动信息,
8+
所以只能在页面的`onPageScroll`生命周期中获取滚动条位置,再通过`Props`传递给组件。
9+
10+
```html
11+
<wd-backtop :scrollTop="scrollTop"></wd-backtop>
12+
```
13+
14+
```typescript
15+
const scrollTop = ref<number>(0)
16+
onPageScroll((e) => {
17+
scrollTop.value = e.scrollTop
18+
})
19+
```
20+
21+
## 自定义图标
22+
23+
```html
24+
<wd-backtop :scrollTop="scrollTop">
25+
<text>TOP<text>
26+
</wd-backtop>
27+
```
28+
29+
## 自定义样式
30+
31+
```html
32+
<wd-backtop :scrollTop="scrollTop" customStyle="background: #007aff;color:white;"></wd-backtop>
33+
```
34+
35+
## Attributes
36+
37+
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
38+
| --------- | -------------------------------- | ------ | ------ | ------ | -------- |
39+
| scrollTop | 页面滚动距离 | number | - | - | - |
40+
| top | 距离顶部多少距离时显示,单位`px` | number | - | 300 | - |
41+
| duration | 返回顶部滚动时间,单位`ms` | number | - | 100 | - |
42+
| zIndex | 组件z-index属性 | number | - | 10 | - |
43+
| iconStyle | 自定义`icon`样式 | string | - | - | - |
44+
| shape | 按钮形状 | string | square | circle | - |
45+
| bottom | 距离屏幕顶部的距离,单位`px` | number | - | 100 | - |
46+
| right | 距离屏幕右边距离,单位`px` | number | - | 20 | - |
47+
48+
## 外部样式类
49+
50+
| 类名 | 说明 | 最低版本 |
51+
| ------------ | ---------- | -------- |
52+
| custom-class | 根节点样式 | - |
53+
| custom-style | 根节点样式 | - |

src/pages.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,16 @@
761761
},
762762
"navigationBarTitleText": "PasswordInput 密码输入框"
763763
}
764+
},
765+
{
766+
"path": "pages/backtop/Index",
767+
"name": "backtop",
768+
"style": {
769+
"mp-alipay": {
770+
"allowsBounceVertical": "NO"
771+
},
772+
"navigationBarTitleText": "Backtop 回到顶部"
773+
}
764774
}
765775
],
766776
// "tabBar": {

src/pages/backtop/Index.vue

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<template>
2+
<page-wraper>
3+
<demo-block>
4+
<wd-checkbox shape="square" size="large" v-model="isSquare">显示方形</wd-checkbox>
5+
<wd-checkbox shape="square" size="large" v-model="isCustomIcon">自定义图标</wd-checkbox>
6+
<wd-checkbox shape="square" size="large" v-model="isTop">自定义距离</wd-checkbox>
7+
<wd-checkbox shape="square" size="large" v-model="isStyle">自定义样式</wd-checkbox>
8+
<wd-checkbox shape="square" size="large" v-model="isDuration">自定义返回顶部滚动时间</wd-checkbox>
9+
</demo-block>
10+
<wd-backtop
11+
v-if="isCustomIcon"
12+
:scrollTop="scrollTop"
13+
:shape="isSquare ? 'square' : undefined"
14+
:top="isTop ? 600 : undefined"
15+
:customStyle="isStyle ? 'background: #007aff;color:white;' : undefined"
16+
:duration="isDuration ? 1000 : undefined"
17+
>
18+
<text :style="`color: ${isStyle ? 'white' : '#333'};`">TOP</text>
19+
</wd-backtop>
20+
<wd-backtop
21+
v-else
22+
:scrollTop="scrollTop"
23+
:shape="isSquare ? 'square' : undefined"
24+
:top="isTop ? 600 : undefined"
25+
:customStyle="isStyle ? 'background: #007aff;color:white;' : undefined"
26+
:duration="isDuration ? 1000 : undefined"
27+
></wd-backtop>
28+
<view style="height: 2000px; color: red"></view>
29+
</page-wraper>
30+
</template>
31+
<script lang="ts" setup>
32+
import { onPageScroll } from '@dcloudio/uni-app'
33+
import { ref } from 'vue'
34+
35+
const scrollTop = ref(0)
36+
onPageScroll((e) => {
37+
scrollTop.value = e.scrollTop
38+
})
39+
40+
const isSquare = ref(false)
41+
const isCustomIcon = ref(false)
42+
const isTop = ref(false)
43+
const isStyle = ref(false)
44+
const isDuration = ref(false)
45+
</script>
46+
<style lang="scss" scoped></style>

src/pages/index/Index.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ const list = ref([
117117
{
118118
id: 'sidebar',
119119
name: 'Sidebar 侧边栏'
120+
},
121+
{
122+
id: 'backtop',
123+
name: 'Backtop 回到顶部'
120124
}
121125
]
122126
},

src/uni_modules/wot-design-uni/components/common/abstracts/variable.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,3 +869,6 @@ $-password-input-cursor-duration: var(--wd-password-input-cursor-duration, 1s);
869869
$-form-item-error-message-color: var(--wot-form-item-error-message-color, $-color-danger) !default;
870870
$-form-item-error-message-font-size: var(--wot-form-item-error-message-font-size, $-fs-secondary) !default;
871871
$-form-item-error-message-line-height: var(--wot-form-item-error-message-line-height, 24px) !default;
872+
873+
/* backtop */
874+
$-backtop-bg: var(--wot-backtop-bg, #e1e1e1) !default;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
@import '../common/abstracts/variable';
2+
@import '../common/abstracts/mixin';
3+
4+
@include b(backtop) {
5+
position: fixed;
6+
background-color: $-backtop-bg;
7+
width: 40px;
8+
height: 40px;
9+
display: flex;
10+
justify-content: center;
11+
align-items: center;
12+
color: $-color-gray-8;
13+
14+
@include when(circle) {
15+
border-radius: 50%;
16+
}
17+
18+
@include when(square) {
19+
border-radius: 4px;
20+
}
21+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { baseProps, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
2+
3+
export const backtopProps = {
4+
...baseProps,
5+
/**
6+
* 页面滚动距离
7+
*/
8+
scrollTop: makeRequiredProp(Number),
9+
/**
10+
* 距离顶部多少距离时显示
11+
*/
12+
top: makeNumberProp(300),
13+
/**
14+
* 返回顶部滚动时间
15+
*/
16+
duration: makeNumberProp(100),
17+
/**
18+
* 层级
19+
*/
20+
zIndex: makeNumberProp(10),
21+
/**
22+
* icon样式
23+
*/
24+
iconStyle: makeStringProp(''),
25+
/**
26+
* 形状
27+
*/
28+
shape: makeStringProp('circle'),
29+
/**
30+
* 距离屏幕底部距离
31+
*/
32+
bottom: makeNumberProp(100),
33+
/**
34+
* 距离屏幕右边距离
35+
*/
36+
right: makeNumberProp(20)
37+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<template>
2+
<wd-transition :show="show" name="fade">
3+
<view
4+
:class="`wd-backtop ${customClass} is-${shape}`"
5+
:style="`z-index: ${zIndex}; bottom: ${bottom}px; right: ${right}px; ${customStyle}`"
6+
@click="handleBacktop"
7+
>
8+
<slot v-if="$slots.default"></slot>
9+
<wd-icon v-else name="backtop" size="20px" :custom-style="iconStyle" />
10+
</view>
11+
</wd-transition>
12+
</template>
13+
14+
<script lang="ts">
15+
export default {
16+
name: 'wd-backtop',
17+
options: {
18+
addGlobalClass: true,
19+
virtualHost: true,
20+
styleIsolation: 'shared'
21+
}
22+
}
23+
</script>
24+
25+
<script lang="ts" setup>
26+
import { computed } from 'vue'
27+
import { backtopProps } from './types'
28+
29+
const props = defineProps(backtopProps)
30+
31+
const show = computed(() => props.scrollTop > props.top)
32+
33+
function handleBacktop() {
34+
uni.pageScrollTo({
35+
scrollTop: 0,
36+
duration: props.duration
37+
})
38+
}
39+
</script>
40+
41+
<style lang="scss" scoped>
42+
@import './index.scss';
43+
</style>

src/uni_modules/wot-design-uni/global.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ declare module '@vue/runtime-core' {
9595
WdPasswordInput: typeof import('./components/wd-password-input/wd-password-input.vue')['default']
9696
WdForm: typeof import('./components/wd-form/wd-form.vue')['default']
9797
WdTextarea: typeof import('./components/wd-textarea/wd-textarea.vue')['default']
98+
WdBacktop: typeof import('./components/wd-backtop/wd-backtop.vue')['default']
9899
}
99100
}
100101

0 commit comments

Comments
 (0)