[improvement] rename packages dir to src (#3659)

This commit is contained in:
neverland
2019-06-27 11:25:57 +08:00
committed by GitHub
parent 8489918dca
commit 75c79b7044
619 changed files with 21 additions and 21 deletions
+176
View File
@@ -0,0 +1,176 @@
<template>
<demo-section>
<demo-block :title="$t('basicUsage')">
<van-swipe
:autoplay="3000"
indicator-color="white"
>
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
</demo-block>
<demo-block :title="$t('title2')">
<van-swipe :autoplay="3000">
<van-swipe-item
v-for="(image, index) in images"
:key="index"
>
<img v-lazy="image">
</van-swipe-item>
</van-swipe>
</demo-block>
<demo-block :title="$t('title3')">
<van-swipe
indicator-color="white"
@change="onChange"
>
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
</demo-block>
<demo-block :title="$t('title4')">
<van-swipe
vertical
:autoplay="3000"
indicator-color="white"
class="demo-swipe--vertical"
>
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
</demo-block>
<demo-block :title="$t('title5')">
<van-swipe
:autoplay="3000"
:width="300"
:loop="false"
indicator-color="white"
>
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
</demo-block>
<demo-block :title="$t('title6')">
<van-swipe @change="onChange">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
<template #indicator>
<div class="custom-indicator">{{ current + 1 }}/4</div>
</template>
</van-swipe>
</demo-block>
</demo-section>
</template>
<script>
export default {
i18n: {
'zh-CN': {
title2: '图片懒加载',
title3: '监听 change 事件',
title4: '纵向滚动',
title5: '设置滑块大小',
title6: '自定义指示器',
message: '当前 Swipe 索引:'
},
'en-US': {
title2: 'Image Lazyload',
title3: 'Change Event',
title4: 'Vertical Scrolling',
title5: 'Set Swiper Item Size',
title6: 'Custom indicator',
message: 'Current Swipe index:'
}
},
data() {
return {
current: 0,
images: [
'https://img.yzcdn.cn/public_files/2017/09/05/3bd347e44233a868c99cf0fe560232be.jpg',
'https://img.yzcdn.cn/public_files/2017/09/05/c0dab461920687911536621b345a0bc9.jpg',
'https://img.yzcdn.cn/public_files/2017/09/05/4e3ea0898b1c2c416eec8c11c5360833.jpg',
'https://img.yzcdn.cn/public_files/2017/09/05/fd08f07665ed67d50e11b32a21ce0682.jpg'
]
};
},
methods: {
onChange(index) {
this.current = index;
this.$toast(this.$t('message') + index);
}
}
};
</script>
<style lang="less">
@import '../../style/var';
.demo-swipe {
padding-bottom: 30px;
.van-swipe {
cursor: pointer;
&-item {
color: @white;
font-size: 20px;
line-height: 150px;
text-align: center;
&:nth-child(even) {
background-color: #39a9ed;
}
&:nth-child(odd) {
background-color: #66c6f2;
}
}
img {
display: block;
box-sizing: border-box;
width: 100%;
height: 240px;
padding: 30px 60px;
background-color: @white;
pointer-events: none;
}
}
&--vertical {
height: 200px;
.van-swipe-item {
line-height: 200px;
}
}
.custom-indicator {
position: absolute;
right: 5px;
bottom: 5px;
padding: 2px 5px;
color: @white;
font-size: 12px;
background: rgba(0, 0, 0, .1);
}
}
</style>
+160
View File
@@ -0,0 +1,160 @@
# Swipe
### Install
``` javascript
import { Swipe, SwipeItem } from 'vant';
Vue.use(Swipe).use(SwipeItem);
```
## Usage
### Basic Usage
Use `autoplay` prop to set autoplay interval
```html
<van-swipe :autoplay="3000" indicator-color="white">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
```
### Image Lazyload
Use [Lazyload](#/en-US/lazyload) component to lazyload image
```html
<van-swipe>
<van-swipe-item v-for="(image, index) in images" :key="index">
<img v-lazy="image" />
</van-swipe-item>
</van-swipe>
```
```javascript
export default {
data() {
return {
images: [
'https://img.yzcdn.cn/1.jpg',
'https://img.yzcdn.cn/2.jpg'
]
}
}
}
```
### change event
```html
<van-swipe @change="onChange">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
```
```js
export default {
methods: {
onChange(index) {
Toast('Current Swipe index:' + index);
}
}
}
```
### Vertical Scrolling
```html
<van-swipe :autoplay="3000" vertical>
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
```
### Set Swiper Item Size
```html
<van-swipe :autoplay="3000" :width="300">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
```
### Custom Indicator
```html
<van-swipe @change="onChange">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
<div class="custom-indicator" slot="indicator">
{{ current + 1 }}/4
</div>
</van-swipe>
```
```js
export default {
data() {
return {
current: 0
}
},
methods: {
onChange(index) {
this.current = index;
}
}
}
```
## API
### Swipe Props
| Attribute | Description | Type | Default |
|------|------|------|------|
| autoplay | Autoplay interval (ms) | `Number` | - |
| duration | Animation duration (ms) | `Number` | `500` |
| loop | Whether to enable loop | `Boolean` | `true` |
| vertical | Vertical Scrolling | `Boolean` | `false` |
| touchable | Whether touchable | `Boolean` | `true` |
| show-indicators | Whether to show indicators | `Boolean` | `true` |
| indicator-color | Indicator color | `String` | `#1989fa` |
| initial-swipe | Index of initial swipe, start from 0 | `Number` | `0` |
| width | Set Swiper Item Width | `Number` | `0` |
| height | Set Swiper Item Height | `Number` | `0` |
### Swipe Events
| Event | Description | Arguments |
|------|------|------|
| change | Triggered when current swipe change | index: index of current swipe |
### Swipe Methods
Use ref to get swipe instance and call instance methods
| Name | Attribute | Return value | Description |
|------|------|------|------|
| swipeTo | index: target index | void | Swipe to target index |
### Swipe Slots
| Name | Description |
|------|------|
| default | Content |
| indicator | Custom indicator |
+299
View File
@@ -0,0 +1,299 @@
import { createNamespace } from '../utils';
import { preventDefault } from '../utils/dom/event';
import { TouchMixin } from '../mixins/touch';
import { BindEventMixin } from '../mixins/bind-event';
const [createComponent, bem] = createNamespace('swipe');
export default createComponent({
mixins: [
TouchMixin,
BindEventMixin(function (bind, isBind) {
bind(window, 'resize', this.onResize, true);
if (isBind) {
this.initialize();
} else {
this.clear();
}
})
],
props: {
width: Number,
height: Number,
autoplay: Number,
vertical: Boolean,
initialSwipe: Number,
indicatorColor: String,
loop: {
type: Boolean,
default: true
},
touchable: {
type: Boolean,
default: true
},
showIndicators: {
type: Boolean,
default: true
},
duration: {
type: Number,
default: 500
}
},
data() {
return {
computedWidth: 0,
computedHeight: 0,
offset: 0,
active: 0,
deltaX: 0,
deltaY: 0,
swipes: [],
swiping: false
};
},
watch: {
swipes() {
this.initialize();
},
initialSwipe() {
this.initialize();
},
autoplay(autoplay) {
if (!autoplay) {
this.clear();
} else {
this.autoPlay();
}
}
},
computed: {
count() {
return this.swipes.length;
},
delta() {
return this.vertical ? this.deltaY : this.deltaX;
},
size() {
return this[this.vertical ? 'computedHeight' : 'computedWidth'];
},
trackSize() {
return this.count * this.size;
},
activeIndicator() {
return (this.active + this.count) % this.count;
},
isCorrectDirection() {
const expect = this.vertical ? 'vertical' : 'horizontal';
return this.direction === expect;
},
trackStyle() {
const mainAxis = this.vertical ? 'height' : 'width';
const crossAxis = this.vertical ? 'width' : 'height';
return {
[mainAxis]: `${this.trackSize}px`,
[crossAxis]: this[crossAxis] ? `${this[crossAxis]}px` : '',
transitionDuration: `${this.swiping ? 0 : this.duration}ms`,
transform: `translate${this.vertical ? 'Y' : 'X'}(${this.offset}px)`
};
},
indicatorStyle() {
return {
backgroundColor: this.indicatorColor
};
}
},
methods: {
// initialize swipe position
initialize(active = this.initialSwipe) {
clearTimeout(this.timer);
if (this.$el) {
const rect = this.$el.getBoundingClientRect();
this.computedWidth = this.width || rect.width;
this.computedHeight = this.height || rect.height;
}
this.swiping = true;
this.active = active;
this.offset = this.count > 1 ? -this.size * this.active : 0;
this.swipes.forEach(swipe => {
swipe.offset = 0;
});
this.autoPlay();
},
onResize() {
this.initialize(this.activeIndicator);
},
onTouchStart(event) {
if (!this.touchable) return;
this.clear();
this.swiping = true;
this.touchStart(event);
this.correctPosition();
},
onTouchMove(event) {
if (!this.touchable || !this.swiping) return;
this.touchMove(event);
if (this.isCorrectDirection) {
preventDefault(event, true);
this.move({ offset: Math.min(Math.max(this.delta, -this.size), this.size) });
}
},
onTouchEnd() {
if (!this.touchable || !this.swiping) return;
if (this.delta && this.isCorrectDirection) {
const offset = this.vertical ? this.offsetY : this.offsetX;
this.move({
pace: offset > 0 ? (this.delta > 0 ? -1 : 1) : 0,
emitChange: true
});
}
this.swiping = false;
this.autoPlay();
},
move({ pace = 0, offset = 0, emitChange }) {
const { delta, active, count, swipes, trackSize } = this;
const atFirst = active === 0;
const atLast = active === count - 1;
const outOfBounds =
!this.loop &&
((atFirst && (offset > 0 || pace < 0)) || (atLast && (offset < 0 || pace > 0)));
if (outOfBounds || count <= 1) {
return;
}
if (swipes[0]) {
swipes[0].offset = atLast && (delta < 0 || pace > 0) ? trackSize : 0;
}
if (swipes[count - 1]) {
swipes[count - 1].offset = atFirst && (delta > 0 || pace < 0) ? -trackSize : 0;
}
if (pace && active + pace >= -1 && active + pace <= count) {
this.active += pace;
if (emitChange) {
this.$emit('change', this.activeIndicator);
}
}
this.offset = Math.round(offset - this.active * this.size);
},
swipeTo(index) {
this.swiping = true;
this.resetTouchStatus();
this.correctPosition();
setTimeout(() => {
this.swiping = false;
this.move({
pace: (index % this.count) - this.active,
emitChange: true
});
}, 30);
},
correctPosition() {
if (this.active <= -1) {
this.move({ pace: this.count });
}
if (this.active >= this.count) {
this.move({ pace: -this.count });
}
},
clear() {
clearTimeout(this.timer);
},
autoPlay() {
const { autoplay } = this;
if (autoplay && this.count > 1) {
this.clear();
this.timer = setTimeout(() => {
this.swiping = true;
this.resetTouchStatus();
this.correctPosition();
setTimeout(() => {
this.swiping = false;
this.move({
pace: 1,
emitChange: true
});
this.autoPlay();
}, 30);
}, autoplay);
}
},
renderIndicator() {
const { count, activeIndicator } = this;
const slot = this.slots('indicator');
if (slot) {
return slot;
}
if (this.showIndicators && count > 1) {
return (
<div class={bem('indicators', { vertical: this.vertical })}>
{Array(...Array(count)).map((empty, index) => (
<i
class={bem('indicator', { active: index === activeIndicator })}
style={index === activeIndicator ? this.indicatorStyle : null}
/>
))}
</div>
);
}
}
},
render(h) {
return (
<div class={bem()}>
<div
ref="track"
style={this.trackStyle}
class={bem('track')}
onTouchstart={this.onTouchStart}
onTouchmove={this.onTouchMove}
onTouchend={this.onTouchEnd}
onTouchcancel={this.onTouchEnd}
>
{this.slots()}
</div>
{this.renderIndicator()}
</div>
);
}
});
+49
View File
@@ -0,0 +1,49 @@
@import '../style/var';
.van-swipe {
position: relative;
overflow: hidden;
user-select: none;
&__track {
height: 100%;
}
&__indicators {
position: absolute;
bottom: @swipe-indicator-margin;
left: 50%;
display: flex;
transform: translateX(-50%);
&--vertical {
top: 50%;
bottom: auto;
left: @swipe-indicator-margin;
flex-direction: column;
transform: translateY(-50%);
.van-swipe__indicator:not(:last-child) {
margin-bottom: @swipe-indicator-size;
}
}
}
&__indicator {
width: @swipe-indicator-size;
height: @swipe-indicator-size;
background-color: @swipe-indicator-inactive-background-color;
border-radius: 100%;
opacity: @swipe-indicator-inactive-opacity;
transition: opacity .2s;
&:not(:last-child) {
margin-right: @swipe-indicator-size;
}
&--active {
background-color: @swipe-indicator-active-background-color;
opacity: @swipe-indicator-active-opacity;
}
}
}
@@ -0,0 +1,72 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-swipe">
<div class="van-swipe__track" style="width: 400px; transition-duration: 0ms; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">1</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">2</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">3</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">4</div>
</div>
<div class="van-swipe__indicators"><i class="van-swipe__indicator van-swipe__indicator--active" style="background-color: white;"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i></div>
</div>
</div>
<div>
<div class="van-swipe">
<div class="van-swipe__track" style="width: 400px; transition-duration: 0ms; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);"><img data-src="https://img.yzcdn.cn/public_files/2017/09/05/3bd347e44233a868c99cf0fe560232be.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" lazy="loading"></div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);"><img data-src="https://img.yzcdn.cn/public_files/2017/09/05/c0dab461920687911536621b345a0bc9.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" lazy="loading"></div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);"><img data-src="https://img.yzcdn.cn/public_files/2017/09/05/4e3ea0898b1c2c416eec8c11c5360833.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" lazy="loading"></div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);"><img data-src="https://img.yzcdn.cn/public_files/2017/09/05/fd08f07665ed67d50e11b32a21ce0682.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" lazy="loading"></div>
</div>
<div class="van-swipe__indicators"><i class="van-swipe__indicator van-swipe__indicator--active"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i></div>
</div>
</div>
<div>
<div class="van-swipe">
<div class="van-swipe__track" style="width: 400px; transition-duration: 0ms; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">1</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">2</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">3</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">4</div>
</div>
<div class="van-swipe__indicators"><i class="van-swipe__indicator van-swipe__indicator--active" style="background-color: white;"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i></div>
</div>
</div>
<div>
<div class="demo-swipe--vertical van-swipe">
<div class="van-swipe__track" style="height: 400px; transition-duration: 0ms; transform: translateY(0px);">
<div class="van-swipe-item" style="width: 100px; height: 100px; transform: translateY(0px);">1</div>
<div class="van-swipe-item" style="width: 100px; height: 100px; transform: translateY(0px);">2</div>
<div class="van-swipe-item" style="width: 100px; height: 100px; transform: translateY(0px);">3</div>
<div class="van-swipe-item" style="width: 100px; height: 100px; transform: translateY(0px);">4</div>
</div>
<div class="van-swipe__indicators van-swipe__indicators--vertical"><i class="van-swipe__indicator van-swipe__indicator--active" style="background-color: white;"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i></div>
</div>
</div>
<div>
<div class="van-swipe">
<div class="van-swipe__track" style="width: 1200px; transition-duration: 0ms; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 300px; height: 100%; transform: translateX(0px);">1</div>
<div class="van-swipe-item" style="width: 300px; height: 100%; transform: translateX(0px);">2</div>
<div class="van-swipe-item" style="width: 300px; height: 100%; transform: translateX(0px);">3</div>
<div class="van-swipe-item" style="width: 300px; height: 100%; transform: translateX(0px);">4</div>
</div>
<div class="van-swipe__indicators"><i class="van-swipe__indicator van-swipe__indicator--active" style="background-color: white;"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i><i class="van-swipe__indicator"></i></div>
</div>
</div>
<div>
<div class="van-swipe">
<div class="van-swipe__track" style="width: 400px; transition-duration: 0ms; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">1</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">2</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">3</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">4</div>
</div>
<div class="custom-indicator">1/4</div>
</div>
</div>
</div>
`;
+17
View File
@@ -0,0 +1,17 @@
import Demo from '../demo';
import demoTest from '../../../test/demo-test';
import { mockGetBoundingClientRect } from '../../../test/utils';
let restore;
demoTest(Demo, {
hookBeforeTest: () => {
restore = mockGetBoundingClientRect({
width: 100,
height: 100
});
},
hookAfterTest: () => {
restore();
}
});
+126
View File
@@ -0,0 +1,126 @@
import Swipe from '..';
import SwipeItem from '../../swipe-item';
import { mount, triggerDrag, later } from '../../../test/utils';
const Component = {
template: `
<swipe ref="swipe" v-bind="$props">
<swipe-item :style="style">1</swipe-item>
<swipe-item :style="style">2</swipe-item>
<swipe-item :style="style">3</swipe-item>
</swipe>
`,
components: {
Swipe,
SwipeItem
},
props: {
vertical: Boolean,
loop: {
type: Boolean,
default: true
},
touchable: {
type: Boolean,
default: true
},
autoplay: {
type: Number,
default: 0
},
initialSwipe: {
type: Number,
default: 0
}
},
data() {
return {
style: {
width: '100px',
height: '100px'
}
};
}
};
test('swipeTo', async () => {
const wrapper = mount(Component);
const { swipe } = wrapper.vm.$refs;
swipe.swipeTo(2);
await later(30);
expect(swipe.active).toEqual(2);
});
test('initial swipe', () => {
const wrapper = mount(Component);
const { swipe } = wrapper.vm.$refs;
expect(swipe.active).toEqual(0);
wrapper.setProps({ initialSwipe: 2 });
expect(swipe.active).toEqual(2);
});
test('vertical swipe', () => {
const wrapper = mount(Component, {
propsData: {
vertical: true
}
});
const { swipe } = wrapper.vm.$refs;
const track = wrapper.find('.van-swipe__track');
triggerDrag(track, 0, -100);
expect(swipe.active).toEqual(1);
});
test('untouchable', () => {
const wrapper = mount(Component, {
propsData: {
touchable: false
}
});
const { swipe } = wrapper.vm.$refs;
const track = wrapper.find('.van-swipe__track');
triggerDrag(track, 100, 0);
expect(swipe.active).toEqual(0);
});
test('loop', () => {
const wrapper = mount(Component);
const { swipe } = wrapper.vm.$refs;
const track = wrapper.find('.van-swipe__track');
triggerDrag(track, -100, 0);
expect(swipe.active).toEqual(1);
triggerDrag(track, -100, 0);
expect(swipe.active).toEqual(2);
triggerDrag(track, -100, 0);
expect(swipe.active).toEqual(3);
triggerDrag(track, -100, 0);
expect(swipe.active).toEqual(1);
triggerDrag(track, 100, 0);
expect(swipe.active).toEqual(0);
triggerDrag(track, 100, 0);
expect(swipe.active).toEqual(-1);
triggerDrag(track, 100, 0);
expect(swipe.active).toEqual(1);
});
test('not loop', () => {
const wrapper = mount(Component, {
propsData: {
loop: false
}
});
const { swipe } = wrapper.vm.$refs;
const track = wrapper.find('.van-swipe__track');
triggerDrag(track, -100, 0);
expect(swipe.active).toEqual(1);
triggerDrag(track, -100, 0);
expect(swipe.active).toEqual(2);
triggerDrag(track, -100, 0);
expect(swipe.active).toEqual(2);
});
+166
View File
@@ -0,0 +1,166 @@
# Swipe 轮播
### 引入
``` javascript
import { Swipe, SwipeItem } from 'vant';
Vue.use(Swipe).use(SwipeItem);
```
## 代码演示
### 基础用法
通过`autoplay`属性设置自动轮播间隔
```html
<van-swipe :autoplay="3000" indicator-color="white">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
```
### 图片懒加载
配合 [Lazyload](#/zh-CN/lazyload) 组件实现图片懒加载
```html
<van-swipe :autoplay="3000">
<van-swipe-item v-for="(image, index) in images" :key="index">
<img v-lazy="image" />
</van-swipe-item>
</van-swipe>
```
```javascript
export default {
data() {
return {
images: [
'https://img.yzcdn.cn/1.jpg',
'https://img.yzcdn.cn/2.jpg'
]
}
}
}
```
### 监听 change 事件
```html
<van-swipe @change="onChange">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
```
```js
export default {
methods: {
onChange(index) {
Toast('当前 Swipe 索引:' + index);
}
}
}
```
### 纵向滚动
```html
<van-swipe :autoplay="3000" vertical>
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
```
### 控制滑块大小
```html
<van-swipe :autoplay="3000" :width="300">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
```
### 自定义指示器
```html
<van-swipe @change="onChange">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
<div class="custom-indicator" slot="indicator">
{{ current + 1 }}/4
</div>
</van-swipe>
```
```js
export default {
data() {
return {
current: 0
}
},
methods: {
onChange(index) {
this.current = index;
}
}
}
```
## API
### Swipe Props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|------|------|------|------|------|
| autoplay | 自动轮播间隔,单位为 ms | `Number` | - | - |
| duration | 动画时长,单位为 ms | `Number` | `500` | - |
| initial-swipe | 初始位置索引值 | `Number` | `0` | - |
| loop | 是否开启循环播放 | `Boolean` | `true` | - |
| show-indicators | 是否显示指示器 | `Boolean` | `true` | - |
| indicator-color | 指示器颜色 | `String` | `#1989fa` | 1.4.5 |
| vertical | 是否为纵向滚动 | `Boolean` | `false` | 1.1.1 |
| touchable | 是否可以通过手势滑动 | `Boolean` | `true` | 1.1.1 |
| width | 滑块宽度 | `Number` | `0` | 1.2.1 |
| height | 滑块高度 | `Number` | `0` | 1.2.1 |
### Swipe Events
| 事件名 | 说明 | 回调参数 |
|------|------|------|
| change | 每一页轮播结束后触发 | index, 当前页的索引 |
### SwipeItem Events
| 事件名 | 说明 | 回调参数 |
|------|------|------|
| click | 点击时触发 | - |
### Swipe 方法
通过 ref 可以获取到 swipe 实例并调用实例方法
| 方法名 | 参数 | 返回值 | 介绍 |
|------|------|------|------|
| swipeTo | index: 目标位置的索引 | void | 滚动到目标位置 |
### Swipe Slots
| 名称 | 说明 |
|------|------|
| default | 轮播内容 |
| indicator | 自定义指示器 |