feat: add new RollingText component (#11911)

This commit is contained in:
cunzaizhuyi 2023-06-15 10:03:12 +08:00 committed by GitHub
parent 9cdbbbdc99
commit a0112e3079
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1550 additions and 0 deletions

View File

@ -0,0 +1,192 @@
# RollingText
### Introduction
Rolling text animation, which can roll numbers and other types of text.
### Install
Register component globally via `app.use`, refer to [Component Registration](#/en-US/advanced-usage#zu-jian-zhu-ce) for more registration ways.
```js
import { createApp } from 'vue';
import { RollingText } from 'vant';
const app = createApp();
app.use(RollingText);
```
## Usage
### Basic Usage
```html
<van-rolling-text
:start-num="0"
:target-num="123"
:duration="2"
:auto-start="false"
direction="down"
/>
```
### Set Rolling Direction
You can set the rolling direction of the number by using the `direction` property. `up` represents rolling up.
```html
<van-rolling-text
:start-num="0"
:target-num="432"
:duration="2"
:auto-start="false"
direction="up"
/>
```
### Set Stop Order
You can set the order of stopping the animation of each digit through the `stop-order` prop. By default, it stops from the higher digits. Setting `rtl` can stop from the ones digit.
```html
<van-rolling-text
:start-num="0"
:target-num="54321"
:duration="2"
:auto-start="false"
stop-order="rtl"
direction="up"
/>
```
### Rolling Non-numeric Text
You can set non-numeric content flip using the `text-array` props.
```html
<van-rolling-text
:text-array="textArray"
:duration="1"
:auto-start="false"
stop-order="rtl"
direction="up"
/>
```
```js
import { ref } from 'vue';
export default {
setup() {
const textArray = ref([
'aaaaa',
'bbbbb',
'ccccc',
'ddddd',
'eeeee',
'fffff',
'ggggg',
]);
return { textArray };
},
};
```
### Custom Style
```html
<van-rolling-text
class="my-roll-number"
:start-num="12345"
:target-num="54321"
:duration="2"
stop-order="rtl"
direction="up"
/>
```
```css
.my-rolling-text {
gap: 6px;
.van-roll-single {
color: white;
background: deepskyblue;
border-radius: 5px;
width: 25px;
font-size: 20px;
}
}
```
### Manual Control
After getting the component instance through `ref`, you can call the `start` and `reset` methods.
```html
<van-rolling-text
ref="rollTextEl"
:start-num="0"
:target-num="54321"
:duration="2"
:auto-start="false"
stop-order="rtl"
direction="up"
/>
<van-grid clickable :column-num="3">
<van-grid-item icon="play-circle-o" :text="start" @click="start" />
<van-grid-item icon="replay" :text="reset" @click="reset" />
</van-grid>
```
```js
import { ref } from 'vue';
export default {
setup() {
const rollTextEl = ref(null);
const start = () => {
rollTextEl.value.start();
};
const reset = () => {
rollTextEl.value.reset();
};
return { rollTextEl, start, reset };
},
};
```
## API
### Props
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
| start-num | Start number | _number_ | 0 |
| target-num | Target number | _number_ | - |
| text-array | Text array | _Array_ | [] |
| duration | Duration of the animation, in seconds | _number_ | 2 |
| direction | Rolling direction of the number, with `down` and `up` as the values | _string_ | `down` |
| auto-start | Whether to start the animation | _boolean_ | true |
| stop-order | Order of stopping the animation of each digit, with `ltr` and `rtl` as the values | _string_ | `ltr` |
### Type Definition
The component exports the following type definitions:
```ts
import type { RollingTextProps } from 'vant';
```
## Theming
### CSS Variables
The component provides the following CSS variables, which can be used to customize styles. Please refer to [ConfigProvider component](#/en-US/config-provider).
| Name | Default Value | Description |
| --- | --- | --- |
| --van-rolling-text-bg-color | _inherit_ | Background color of a single digit |
| --van-rolling-text-color | _white_ | Color of the number |
| --van-rolling-text-gap | _0px_ | Spacing between digits |
| --van-rolling-text-single-width | _15px_ | Width of a single digit |
| --van-rolling-text-single-border-r | _0px_ | Border radius of a single digit |

View File

@ -0,0 +1,192 @@
# RollingText 翻滚文本动效
### 介绍
文本翻滚动效,可以翻滚数字和其他类型文本。
### 引入
通过以下方式来全局注册组件,更多注册方式请参考[组件注册](#/zh-CN/advanced-usage#zu-jian-zhu-ce)。
```js
import { createApp } from 'vue';
import { RollingText } from 'vant';
const app = createApp();
app.use(RollingText);
```
## 代码演示
### 基础用法
```html
<van-rolling-text
:start-num="0"
:target-num="123"
:duration="2"
:auto-start="false"
direction="down"
/>
```
### 设置翻滚方向
可以通过 `direction` 属性设置数字的翻滚方向。`up` 表示向上翻滚。
```html
<van-rolling-text
:start-num="0"
:target-num="432"
:duration="2"
:auto-start="false"
direction="up"
/>
```
### 设置各数位停止顺序
可以通过 `stop-order` 属性设置动画各个数位的停止先后顺序。默认先停止高位。设置 `rtl` 可以先从个位停止。
```html
<van-rolling-text
:start-num="0"
:target-num="54321"
:duration="2"
:auto-start="false"
stop-order="rtl"
direction="up"
/>
```
### 翻转非数字内容
可以通过 `text-array` 属性设置非数字内容的翻转。
```html
<van-rolling-text
:text-array="textArray"
:duration="1"
:auto-start="false"
stop-order="rtl"
direction="up"
/>
```
```js
import { ref } from 'vue';
export default {
setup() {
const textArray = ref([
'aaaaa',
'bbbbb',
'ccccc',
'ddddd',
'eeeee',
'fffff',
'ggggg',
]);
return { textArray };
},
};
```
### 自定义样式
```html
<van-rolling-text
class="my-roll-number"
:start-num="12345"
:target-num="54321"
:duration="2"
stop-order="rtl"
direction="up"
/>
```
```css
.my-rolling-text {
gap: 6px;
.van-roll-single {
color: white;
background: deepskyblue;
border-radius: 5px;
width: 25px;
font-size: 20px;
}
}
```
### 手动控制
通过 ref 获取到组件实例后,可以调用 `start``reset` 方法。
```html
<van-rolling-text
ref="rollTextEl"
:start-num="0"
:target-num="54321"
:duration="2"
:auto-start="false"
stop-order="rtl"
direction="up"
/>
<van-grid clickable :column-num="3">
<van-grid-item icon="play-circle-o" :text="start" @click="start" />
<van-grid-item icon="replay" :text="reset" @click="reset" />
</van-grid>
```
```js
import { ref } from 'vue';
export default {
setup() {
const rollTextEl = ref(null);
const start = () => {
rollTextEl.value.start();
};
const reset = () => {
rollTextEl.value.reset();
};
return { rollTextEl, start, reset };
},
};
```
## API
### Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| start-num | 开始数值 | _number_ | 0 |
| target-num | 目标数值 | _number_ | - |
| text-array | 内容数组,翻转非数字内容,需要传此参数 | _Array_ | [] |
| duration | 动画时长,单位为秒 | _number_ | 2 |
| direction | 数值翻滚方向,值为 `down``up` | _string_ | `down` |
| auto-start | 是否自动开始动画 | _boolean_ | true |
| stop-order | 各个数位动画停止先后顺序,值为 `ltr``rtl` | _string_ | `ltr` |
### 类型定义
组件导出以下类型定义:
```ts
import type { RollingTextProps } from 'vant';
```
## 主题定制
### 样式变量
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 [ConfigProvider 组件](#/zh-CN/config-provider)。
| 名称 | 默认值 | 描述 |
| ---------------------------------- | --------- | ---------------- |
| --van-rolling-text-bg-color | _inherit_ | 单个数位背景色 |
| --van-rolling-text-color | _white_ | 数字颜色 |
| --van-rolling-text-gap | _0px_ | 数位之间的间隔 |
| --van-rolling-text-single-width | _15px_ | 单个数位宽度 |
| --van-rolling-text-single-border-r | _0px_ | 单个数位边框圆角 |

View File

@ -0,0 +1,121 @@
import { ref, defineComponent, computed, type ExtractPropTypes } from 'vue';
import RollingTextItem from './RollingTextItem';
// Utils
import {
createNamespace,
makeArrayProp,
makeNumberProp,
makeStringProp,
truthProp,
} from '../utils';
import { useExpose } from '../composables/use-expose';
const [name, bem] = createNamespace('rolling-text');
export type RollingTextDirection = 'up' | 'down';
export type RollingTextStopOrder = 'ltr' | 'rtl';
export const rollingTextProps = {
startNum: makeNumberProp(0),
targetNum: Number,
textArray: makeArrayProp<string>(),
duration: makeNumberProp(2),
autoStart: truthProp,
direction: makeStringProp<RollingTextDirection>('down'),
stopOrder: makeStringProp<RollingTextStopOrder>('ltr'),
};
const CIRCLE_NUM = 2;
export type RollingTextProps = ExtractPropTypes<typeof rollingTextProps>;
export default defineComponent({
name,
props: rollingTextProps,
setup(props) {
const isCustomType = computed(
() => Array.isArray(props.textArray) && props.textArray.length
);
const getTextArrByIdx = (idx: number) => {
if (!isCustomType.value) return [];
const result = [];
for (let i = 0; i < props.textArray.length; i++) {
result.push(props.textArray[i][idx]);
}
return result;
};
const targetNumArr = computed(() => {
if (isCustomType.value)
return props.textArray[props.textArray.length - 1].split('');
return `${props.targetNum}`.split('');
});
const startNumArr = () => {
const arr = `${props.startNum}`.split('');
while (arr.length < targetNumArr.value.length) {
arr.unshift('0');
}
return arr;
};
const getTwoFigure = (i: number) => [
startNumArr()[i],
targetNumArr.value[i],
];
const getFigureArr = (i: number) => {
const [start, target] = getTwoFigure(i);
const result = [];
for (let i = +start; i <= 9; i++) {
result.push(i);
}
for (let i = 0; i <= CIRCLE_NUM; i++) {
for (let j = 0; j <= 9; j++) {
result.push(j);
}
}
for (let i = 0; i <= +target; i++) {
result.push(i);
}
return result;
};
const getDelay = (i: number, len: number) => {
if (props.stopOrder === 'ltr') return 0.2 * i;
return 0.2 * (len - 1 - i);
};
const isStart = ref(false);
const start = () => {
isStart.value = true;
};
const reset = () => {
isStart.value = false;
};
useExpose({
start,
reset,
});
return () => (
<div class={bem()}>
{targetNumArr.value.map((figure, i) => (
<RollingTextItem
figureArr={
isCustomType.value ? getTextArrByIdx(i) : getFigureArr(i)
}
duration={props.duration}
direction={props.direction}
isStart={props.autoStart || isStart.value}
delay={getDelay(i, targetNumArr.value.length)}
/>
))}
</div>
);
},
});

View File

@ -0,0 +1,72 @@
import { defineComponent, computed } from 'vue';
// Utils
import {
createNamespace,
makeNumberProp,
makeArrayProp,
addUnit,
} from '../utils';
export const props = {
figureArr: makeArrayProp(),
delay: Number,
duration: makeNumberProp(2),
isStart: Boolean,
direction: String,
};
const HEIGHT = 40;
export default defineComponent({
name: 'RollSingle',
props,
setup(props) {
const downConfig = {
classNameSpace: 'roll-single-down',
aniClass: 'van-roll-single-down__ani',
dataHandle: () => props.figureArr.slice().reverse(),
};
const upConfig = {
classNameSpace: 'roll-single-up',
aniClass: 'van-roll-single-up__ani',
dataHandle: () => props.figureArr,
};
const directionConfig = props.direction === 'down' ? downConfig : upConfig;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, bem] = createNamespace(directionConfig.classNameSpace);
const newFigureArr = computed(directionConfig.dataHandle);
const totalHeight = computed(
() => HEIGHT * props.figureArr.length - HEIGHT
);
const translateValPx = computed(() => `-${totalHeight.value}px`);
const itemStyleObj = {
lineHeight: addUnit(HEIGHT),
};
const getStyle = () => ({
height: addUnit(HEIGHT),
'--van-translate': translateValPx.value,
'--van-duration': props.duration + 's',
'--van-delay': props.delay + 's',
});
return () => (
<div style={getStyle()} class={[bem(), 'van-roll-single']}>
<div
class={[bem('box'), { [directionConfig.aniClass]: props.isStart }]}
>
{Array.isArray(newFigureArr.value) &&
newFigureArr.value.map((figure) => (
<div class={bem('item')} style={itemStyleObj}>
{figure}
</div>
))}
</div>
</div>
);
},
});

View File

@ -0,0 +1,186 @@
<script setup lang="ts">
import VanRollingText from '..';
import Button from '../../button';
import { ref } from 'vue';
import { useTranslate } from '../../../docs/site';
import VanGrid from '../../grid';
import VanGridItem from '../../grid-item';
const t = useTranslate({
'zh-CN': {
direction: '设置翻滚方向',
stopOrder: '设置各数位停止顺序',
rollDown: '向下翻滚',
rollUp: '向上翻滚',
stopFrom: '从个位停止',
manualControl: '手动控制',
customStyle: '自定义样式',
noNumberType: '翻转非数字内容',
start: '开始',
reset: '重置',
},
'en-US': {
direction: 'Set Roll Direction',
stopOrder: 'Set StopOrder',
rollDown: 'rollDown',
rollUp: 'rollUp',
stopFrom: 'right-side stop first',
manualControl: 'Manual Control',
customStyle: 'Custom Style',
noNumberType: 'Roll non-number type text',
start: 'Start',
rest: 'Reset',
},
});
const isStart = ref(false);
const isStart2 = ref(false);
const isStart3 = ref(false);
const isStart4 = ref(false);
const isStartNoNumberType = ref(false);
const textArray = ref([
'aaaaa',
'bbbbb',
'ccccc',
'ddddd',
'eeeee',
'fffff',
'ggggg',
]);
const rollingTextEl = ref(null);
const start = () => {
rollingTextEl.value.start();
};
const reset = () => {
rollingTextEl.value.reset();
};
</script>
<template>
<demo-block :title="t('basicUsage')">
<div style="">
<VanRollingText
:start-num="0"
:target-num="123"
:duration="2"
:auto-start="isStart"
direction="down"
/>
<div style="margin-top: 10px">
<Button @click="() => (isStart = true)" type="primary">{{
t('rollDown')
}}</Button>
</div>
</div>
</demo-block>
<demo-block :title="t('direction')">
<div>
<VanRollingText
:start-num="0"
:target-num="432"
:duration="2"
:auto-start="isStart2"
direction="up"
/>
<div style="margin-top: 10px">
<Button @click="() => (isStart2 = true)" type="primary">{{
t('rollUp')
}}</Button>
</div>
</div>
</demo-block>
<demo-block :title="t('stopOrder')">
<div>
<VanRollingText
:start-num="0"
:target-num="54321"
:duration="2"
:auto-start="isStart3"
stop-order="rtl"
direction="up"
/>
<div style="margin-top: 10px">
<Button @click="() => (isStart3 = true)" type="primary">{{
t('stopFrom')
}}</Button>
</div>
</div>
</demo-block>
<demo-block :title="t('noNumberType')">
<div>
<VanRollingText
:text-array="textArray"
:duration="1"
:auto-start="isStartNoNumberType"
stop-order="rtl"
direction="up"
/>
<div style="margin-top: 10px">
<Button @click="() => (isStartNoNumberType = true)" type="primary">{{
t('start')
}}</Button>
</div>
</div>
</demo-block>
<demo-block :title="t('customStyle')">
<div>
<VanRollingText
class="my-rolling-te11xt"
:start-num="12345"
:target-num="54321"
:duration="2"
:auto-start="isStart4"
stop-order="rtl"
direction="up"
/>
</div>
</demo-block>
<demo-block :title="t('manualControl')">
<div>
<VanRollingText
class="my-rolling-te11xt"
ref="rollingTextEl"
:start-num="0"
:target-num="54321"
:duration="2"
:auto-start="false"
stop-order="rtl"
direction="up"
/>
<van-grid clickable :column-num="3" style="margin-top: 10px">
<van-grid-item icon="play-circle-o" :text="t('start')" @click="start" />
<van-grid-item icon="replay" :text="t('reset')" @click="reset" />
</van-grid>
</div>
</demo-block>
</template>
<style lang="less">
.van-button {
margin-left: var(--van-padding-md);
}
.van-rolling-text {
margin-left: var(--van-padding-md);
}
.van-grid {
margin-left: var(--van-padding-md);
}
.my-rolling-te11xt {
gap: 6px;
.van-roll-single {
color: white;
background: deepskyblue;
border-radius: 5px;
width: 25px;
font-size: 20px;
}
}
</style>

View File

@ -0,0 +1,85 @@
:root {
--van-rolling-text-bg-color: inherit;
--van-rolling-text-color: black;
--van-rolling-text-gap: 0px;
--van-rolling-text-single-width: 15px;
--van-rolling-text-single-border-r: 0px;
}
.van-rolling-text {
display: inline-flex;
justify-content: center;
align-items: center;
gap: var(--van-rolling-text-gap);
}
.van-roll-single-down {
width: var(--van-rolling-text-single-width);
border-radius: var(--van-rolling-text-single-border-r);
background-color: var(--van-rolling-text-bg-color);
color: var(--van-rolling-text-color);
overflow: hidden;
// 如果向下滚动则起始是translate负值到0
@keyframes van-down {
0% {
transform: translateY(var(--van-translate));
}
100% {
transform: translateY(0);
}
}
&__box {
overflow: hidden;
transform: translateY(var(--van-translate));
}
&__ani {
animation: van-down var(--van-duration) ease-in-out var(--van-delay);
animation-name: van-down;
animation-timing-function: ease-in-out;
animation-iteration-count: 1;
animation-duration: var(--van-duration);
animation-fill-mode: both;
animation-delay: var(--van-delay);
}
&__item {
text-align: center;
}
}
.van-roll-single-up {
width: var(--van-rolling-text-single-width);
border-radius: var(--van-rolling-text-single-border-r);
background-color: var(--van-rolling-text-bg-color);
color: var(--van-rolling-text-color);
overflow: hidden;
// 如果是向上翻滚则起始是0到translate负值
@keyframes van-up {
0% {
transform: translateY(0);
}
100% {
transform: translateY(var(--van-translate));
}
}
&__box {
overflow: hidden;
}
&__ani {
animation: van-up var(--van-duration) ease-in-out var(--van-delay);
animation-iteration-count: 1;
animation-fill-mode: both;
//animation-name: van-up;
//animation-timing-function: ease-in-out;
//animation-duration: var(--van-duration);
//animation-delay: var(--van-delay);
}
&__item {
text-align: center;
}
}

View File

@ -0,0 +1,12 @@
import { withInstall } from '../utils';
import _RollingText from './RollingText';
export const RollingText = withInstall(_RollingText);
export default RollingText;
export type { RollingTextProps } from './RollingText';
declare module 'vue' {
export interface GlobalComponents {
Van_RollingText: typeof _RollingText;
}
}

View File

@ -0,0 +1,669 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render comp 1`] = `
<div class="van-rolling-text">
<div style="height: 40px; --van-translate: -1640px; --van-duration: 2s; --van-delay: 0s;"
class="van-roll-single-down van-roll-single"
>
<div class="van-roll-single-down__box van-roll-single-down__ani">
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
</div>
</div>
<div style="height: 40px; --van-translate: -1680px; --van-duration: 2s; --van-delay: 0.2s;"
class="van-roll-single-down van-roll-single"
>
<div class="van-roll-single-down__box van-roll-single-down__ani">
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
</div>
</div>
<div style="height: 40px; --van-translate: -1720px; --van-duration: 2s; --van-delay: 0.4s;"
class="van-roll-single-down van-roll-single"
>
<div class="van-roll-single-down__box van-roll-single-down__ani">
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
9
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
8
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
7
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
6
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
5
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
4
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
3
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
2
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
1
</div>
<div class="van-roll-single-down__item"
style="line-height: 40px;"
>
0
</div>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,13 @@
import { RollingText } from '..';
import { mount } from '../../../test';
test('should render comp', () => {
const wrapper = mount(RollingText, {
props: {
'start-num': 0,
'target-num': 123,
},
});
expect(wrapper.html()).toMatchSnapshot();
});

View File

View File

@ -332,6 +332,10 @@ location.href = location.href.replace('youzan.github.io', 'vant-ui.github.io');
path: 'progress',
title: 'Progress 进度条',
},
{
path: 'rolling-text',
title: 'RollingText 翻滚文本',
},
{
path: 'skeleton',
title: 'Skeleton 骨架屏',
@ -788,6 +792,10 @@ location.href = location.href.replace('youzan.github.io', 'vant-ui.github.io');
path: 'progress',
title: 'Progress',
},
{
path: 'rolling-text',
title: 'RollingText',
},
{
path: 'skeleton',
title: 'Skeleton',