Skip to content

Commit

Permalink
refactor(backtop): move to script setup (jd-opensource#2970)
Browse files Browse the repository at this point in the history
  • Loading branch information
subordon authored Mar 17, 2024
1 parent 2c01041 commit 35e4636
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 253 deletions.
3 changes: 2 additions & 1 deletion src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@
"version": "3.0.0",
"name": "Backtop",
"cName": "返回顶部",
"setup": true,
"desc": "较长页面快捷返回顶部",
"author": "liqiong43"
},
Expand Down Expand Up @@ -904,4 +905,4 @@
]
}
]
}
}
2 changes: 1 addition & 1 deletion src/packages/__VUE/backtop/__tests__/backtop.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { mount, config } from '@vue/test-utils';
import Backtop from '../index.vue';
import Backtop from '../backtop.vue';
import { mockScrollTop } from './../../../utils/unit';
import { nextTick } from 'vue';
import { Top } from '@nutui/icons-vue';
Expand Down
74 changes: 74 additions & 0 deletions src/packages/__VUE/backtop/backtop.taro.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<template>
<view>
<nut-scroll-view
:scroll-y="true"
:style="{ height }"
:scroll-top="scrollTop"
scroll-with-animation="true"
@scroll="scroll"
>
<slot name="content"></slot>
</nut-scroll-view>
<view :class="classes" :style="style" @click.stop="handleClick">
<slot name="icon">
<Top width="19px" height="19px" class="nut-backtop-main"></Top>
</slot>
</view>
</view>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import NutScrollView from '../scroll-view/index.taro.vue';
import { Top } from '@nutui/icons-vue-taro';
defineOptions({
name: 'NutBacktop'
});
export type BacktopProps = Partial<{
height: string;
bottom: number;
right: number;
distance: number;
zIndex: number;
}>;
const props = withDefaults(defineProps<BacktopProps>(), {
height: '100vh',
bottom: 20,
right: 10,
distance: 200,
zIndex: 10
});
const emit = defineEmits(['click']);
const backTop = ref(false);
const scrollTop = ref(1);
const scroll = (e: any) => {
scrollTop.value = 2;
backTop.value = e.detail.scrollTop >= props.distance;
};
const classes = computed(() => {
const prefixCls = 'nut-backtop';
return {
[prefixCls]: true,
show: backTop.value
};
});
const style = computed(() => {
return {
right: `${props.right}px`,
bottom: `${props.bottom}px`,
zIndex: props.zIndex
};
});
const handleClick = (e: MouseEvent) => {
scrollTop.value = 1;
emit('click', e);
};
</script>
137 changes: 137 additions & 0 deletions src/packages/__VUE/backtop/backtop.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<template>
<div :class="classes" :style="style" @click.stop="handleClick">
<slot>
<Top width="19px" height="19px" class="nut-backtop-main"></Top>
</slot>
</div>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, onActivated, onDeactivated, ref } from 'vue';
import requestAniFrame, { cancelRaf } from '@/packages/utils/raf';
import { Top } from '@nutui/icons-vue';
defineOptions({
name: 'NutBacktop'
});
export type BacktopProps = Partial<{
bottom: number;
right: number;
elId: string;
distance: number;
zIndex: number;
isAnimation: boolean;
duration: number;
}>;
const props = withDefaults(defineProps<BacktopProps>(), {
bottom: 20,
right: 10,
elId: 'body',
distance: 200,
zIndex: 10,
isAnimation: true,
duration: 1000
});
const emit = defineEmits(['click']);
const backTop = ref(false);
const scrollTop = ref(0);
const scrollEl = ref(window as HTMLElement | Window);
const startTime = ref(0);
const keepAlive = ref(false);
const classes = computed(() => {
const prefixCls = 'nut-backtop';
return {
[prefixCls]: true,
show: backTop.value
};
});
const style = computed(() => {
return {
right: `${props.right}px`,
bottom: `${props.bottom}px`,
zIndex: props.zIndex
};
});
function scrollListener() {
if (scrollEl.value instanceof Window) {
scrollTop.value = scrollEl.value.scrollY;
} else {
scrollTop.value = scrollEl.value.scrollTop;
}
backTop.value = scrollTop.value >= props.distance;
}
function scroll(y = 0) {
if (scrollEl.value instanceof Window) {
window.scrollTo(0, y);
} else {
scrollEl.value.scrollTop = y;
}
}
function scrollAnimation() {
let cid = requestAniFrame(function fn() {
var t = props.duration - Math.max(0, startTime.value - +new Date() + props.duration);
var y = (t * -scrollTop.value) / props.duration + scrollTop.value;
scroll(y);
cid = requestAniFrame(fn);
if (t == props.duration || y == 0) {
cancelRaf(cid);
}
});
}
function addEventListener() {
scrollEl.value.addEventListener('scroll', scrollListener, false);
scrollEl.value.addEventListener('resize', scrollListener, false);
}
function removeEventListener() {
scrollEl.value.removeEventListener('scroll', scrollListener, false);
scrollEl.value.removeEventListener('resize', scrollListener, false);
}
function handleClick(e: MouseEvent) {
startTime.value = +new Date();
props.isAnimation && props.duration > 0 ? scrollAnimation() : scroll();
emit('click', e);
}
function init() {
if (props.elId && document.getElementById(props.elId)) {
scrollEl.value = document.getElementById(props.elId) as HTMLElement | Window;
}
addEventListener();
}
onMounted(() => {
if (props.distance == 0) {
backTop.value = true;
}
init();
});
onUnmounted(() => {
removeEventListener();
});
onActivated(() => {
if (keepAlive.value) {
keepAlive.value = false;
init();
}
});
onDeactivated(() => {
keepAlive.value = true;
removeEventListener();
});
</script>
8 changes: 8 additions & 0 deletions src/packages/__VUE/backtop/doc.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ app.use(Backtop);
| --- | --- |
| default | The default slot is used to customize the content |

### Types version

The component exports the following type definitions:

```ts
import type { BacktopProps, BacktopInstance } from '@nutui/nutui';
```

## Theming

### CSS Variables
Expand Down
8 changes: 8 additions & 0 deletions src/packages/__VUE/backtop/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ app.use(Backtop);
| --- | --- |
| default | 默认 `slot`,用以自定义内容 |

### 类型定义 version

组件导出以下类型定义:

```ts
import type { BacktopProps, BacktopInstance } from '@nutui/nutui';
```

## 主题定制

### 样式变量
Expand Down
8 changes: 8 additions & 0 deletions src/packages/__VUE/backtop/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ app.use(Backtop);
| content | 滚动容器中包含的内容 |
| icon | 返回到顶部,按钮内容 |

### 类型定义 version

组件导出以下类型定义:

```ts
import type { BacktopProps, BacktopInstance } from '@nutui/nutui';
```

## 主题定制

### 样式变量
Expand Down
11 changes: 11 additions & 0 deletions src/packages/__VUE/backtop/index.taro.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Backtop from './backtop.taro.vue';
import type { ComponentPublicInstance } from 'vue';
import { withInstall } from '@/packages/utils';

withInstall(Backtop);

export type { BacktopProps } from './backtop.taro.vue';

export type BacktopInstance = ComponentPublicInstance & InstanceType<typeof Backtop>;

export { Backtop, Backtop as default };
93 changes: 0 additions & 93 deletions src/packages/__VUE/backtop/index.taro.vue

This file was deleted.

11 changes: 11 additions & 0 deletions src/packages/__VUE/backtop/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Backtop from './backtop.vue';
import type { ComponentPublicInstance } from 'vue';
import { withInstall } from '@/packages/utils';

withInstall(Backtop);

export type { BacktopProps } from './backtop.vue';

export type BacktopInstance = ComponentPublicInstance & InstanceType<typeof Backtop>;

export { Backtop, Backtop as default };
Loading

0 comments on commit 35e4636

Please sign in to comment.