Compare commits

...

6 Commits

Author SHA1 Message Date
neverland
4d27e8b969
feat(Swipe): indicator slot add active param (#8645)
* feat(Swipe): indicator slot add active param

* docs: upd
2021-05-01 17:31:20 +08:00
neverland
b0129722cf
Create codeql-analysis.yml 2021-05-01 17:20:39 +08:00
neverland
40171e4d74
docs(Swipe): improve document (#8644) 2021-05-01 17:20:09 +08:00
neverland
c2b2e799e4
fix(Swipe): re-initialize when popup reopened (#8643) 2021-05-01 17:07:53 +08:00
neverland
8db718d2bd
fix(Tabs): setLine when popup reopened (#8642) 2021-05-01 16:44:02 +08:00
neverland
b43822562f
feat: add onPopupReopen (#8641) 2021-05-01 16:40:50 +08:00
8 changed files with 147 additions and 103 deletions

71
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@ -0,0 +1,71 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ dev ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ dev ]
schedule:
- cron: '36 21 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@ -0,0 +1,19 @@
import { inject, watch } from 'vue';
// eslint-disable-next-line
export const POPUP_TOGGLE_KEY = Symbol();
export function onPopupReopen(callback: () => void) {
const popupToggleStatus = inject<(() => boolean) | null>(
POPUP_TOGGLE_KEY,
null
);
if (popupToggleStatus) {
watch(popupToggleStatus, (show) => {
if (show) {
callback();
}
});
}
}

View File

@ -1,6 +1,7 @@
import {
ref,
watch,
provide,
Teleport,
computed,
PropType,
@ -21,6 +22,7 @@ import { useEventListener } from '@vant/use';
import { useExpose } from '../composables/use-expose';
import { useLockScroll } from '../composables/use-lock-scroll';
import { useLazyRender } from '../composables/use-lazy-render';
import { POPUP_TOGGLE_KEY } from '../composables/on-popup-reopen';
// Components
import { Icon } from '../icon';
@ -245,6 +247,8 @@ export default defineComponent({
}
});
provide(POPUP_TOGGLE_KEY, () => props.show);
return () => {
if (props.teleport) {
return (

View File

@ -115,13 +115,13 @@ export default {
### Custom Indicator
```html
<van-swipe @change="onChange">
<van-swipe>
<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 #indicator="{ active }">
<div class="custom-indicator">{{ active + 1 }}/4</div>
</template>
</van-swipe>
@ -137,23 +137,6 @@ export default {
</style>
```
```js
import { ref } from 'vue';
export default {
setup() {
const current = ref(0);
const onChange = (index) => {
current.value = index;
};
return {
current,
onChange,
};
},
};
```
## API
### Swipe Props
@ -193,10 +176,10 @@ Use [ref](https://v3.vuejs.org/guide/component-template-refs.html) to get Swipe
| --- | --- | --- | --- |
| prev | Swipe to prev item | - | - |
| next | Swipe to next item | - | - |
| swipeTo | Swipe to target index | index: target index, options: Options | - |
| swipeTo | Swipe to target index | _index: number, options: SwipeToOptions_ | - |
| resize | Resize Swipe when container element resized or visibility changed | - | - |
### swipeTo Options
### SwipeToOptions
| Name | Description | Type |
| --------- | ------------------------- | --------- |
@ -204,10 +187,10 @@ Use [ref](https://v3.vuejs.org/guide/component-template-refs.html) to get Swipe
### Swipe Slots
| Name | Description |
| --------- | ---------------- |
| default | Content |
| indicator | Custom indicator |
| Name | Description | SlotProps |
| ------------------- | ---------------- | -------------------- |
| default | Content | - |
| indicator `v3.0.16` | Custom indicator | _{ active: number }_ |
### Less Variables

View File

@ -68,6 +68,8 @@ export default {
### 监听 change 事件
在每一页轮播结束后,会触发 `change` 事件。
```html
<van-swipe @change="onChange">
<van-swipe-item>1</van-swipe-item>
@ -121,13 +123,13 @@ export default {
通过 `indicator` 插槽可以自定义指示器的样式。
```html
<van-swipe @change="onChange">
<van-swipe>
<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 #indicator="{ active }">
<div class="custom-indicator">{{ active + 1 }}/4</div>
</template>
</van-swipe>
@ -143,23 +145,6 @@ export default {
</style>
```
```js
import { ref } from 'vue';
export default {
setup() {
const current = ref(0);
const onChange = (index) => {
current.value = index;
};
return {
current,
onChange,
};
},
};
```
## API
### Swipe Props
@ -169,8 +154,8 @@ export default {
| autoplay | 自动轮播间隔,单位为 ms | _number \| string_ | - |
| duration | 动画时长,单位为 ms | _number \| string_ | `500` |
| initial-swipe | 初始位置索引值 | _number \| string_ | `0` |
| width | 滑块宽度,单位为`px` | _number \| string_ | `auto` |
| height | 滑块高度,单位为`px` | _number \| string_ | `auto` |
| width | 滑块宽度,单位为 `px` | _number \| string_ | `auto` |
| height | 滑块高度,单位为 `px` | _number \| string_ | `auto` |
| loop | 是否开启循环播放 | _boolean_ | `true` |
| show-indicators | 是否显示指示器 | _boolean_ | `true` |
| vertical | 是否为纵向滚动 | _boolean_ | `false` |
@ -199,10 +184,10 @@ export default {
| --- | --- | --- | --- |
| prev | 切换到上一轮播 | - | - |
| next | 切换到下一轮播 | - | - |
| swipeTo | 切换到指定位置 | index: number, options: Options | - |
| swipeTo | 切换到指定位置 | _index: number, options: SwipeToOptions_ | - |
| resize | 外层元素大小或组件显示状态变化时,可以调用此方法来触发重绘 | - | - |
### swipeTo Options 格式
### SwipeToOptions 格式
| 名称 | 说明 | 类型 |
| --------- | ------------ | --------- |
@ -210,10 +195,10 @@ export default {
### Swipe Slots
| 名称 | 说明 |
| --------- | ------------ |
| default | 轮播内容 |
| indicator | 自定义指示器 |
| 名称 | 说明 | 参数 |
| ------------------- | ------------ | -------------------- |
| default | 轮播内容 | - |
| indicator `v3.0.16` | 自定义指示器 | _{ active: number }_ |
### 样式变量
@ -232,7 +217,7 @@ export default {
### 滑动轮播时为什么触发了 click 事件?
这种情况通常是由于项目中引入了`fastclick`库导致的。`fastclick`的原理是通过 Touch 事件模拟出 click 事件,而 Swipe 内部默认会阻止 touchmove 事件冒泡,干扰了 fastclick 的判断,导致出现这个问题。
这种情况通常是由于项目中引入了 `fastclick` 库导致的。`fastclick` 的原理是通过 Touch 事件模拟出 click 事件,而 Swipe 内部默认会阻止 touchmove 事件冒泡,干扰了 fastclick 的判断,导致出现这个问题。
将 Swipe 组件的 stop-propagation 属性设置为 false 即可避免该问题。

View File

@ -32,6 +32,7 @@ import {
} from '@vant/use';
import { useTouch } from '../composables/use-touch';
import { useExpose } from '../composables/use-expose';
import { onPopupReopen } from '../composables/on-popup-reopen';
const [name, bem] = createNamespace('swipe');
@ -219,6 +220,7 @@ export default defineComponent({
}
};
// swipe to prev item
const prev = () => {
correctPosition();
touch.reset();
@ -232,6 +234,7 @@ export default defineComponent({
});
};
// swipe to next item
const next = () => {
correctPosition();
touch.reset();
@ -247,13 +250,11 @@ export default defineComponent({
let autoplayTimer: NodeJS.Timeout;
const stopAutoplay = () => {
clearTimeout(autoplayTimer);
};
const stopAutoplay = () => clearTimeout(autoplayTimer);
const autoplay = () => {
stopAutoplay();
if (props.autoplay > 0 && count.value > 1) {
stopAutoplay();
autoplayTimer = setTimeout(() => {
next();
autoplay();
@ -263,32 +264,30 @@ export default defineComponent({
// initialize swipe position
const initialize = (active = +props.initialSwipe) => {
if (!root.value || isHidden(root)) {
if (!root.value) {
return;
}
stopAutoplay();
const rect = {
width: root.value.offsetWidth,
height: root.value.offsetHeight,
};
if (!isHidden(root)) {
const rect = {
width: root.value.offsetWidth,
height: root.value.offsetHeight,
};
state.rect = rect;
state.width = +(props.width ?? rect.width);
state.height = +(props.height ?? rect.height);
}
if (count.value) {
active = Math.min(count.value - 1, active);
}
state.rect = rect;
state.swiping = true;
state.active = active;
state.width = +(props.width ?? rect.width);
state.height = +(props.height ?? rect.height);
state.swiping = true;
state.offset = getTargetOffset(active);
children.forEach((swipe) => {
swipe.setOffset(0);
});
autoplay();
};
const resize = () => initialize(state.active);
@ -393,7 +392,9 @@ export default defineComponent({
const renderIndicator = () => {
if (slots.indicator) {
return slots.indicator();
return slots.indicator({
active: activeIndicator.value,
});
}
if (props.showIndicators && count.value > 1) {
return (
@ -425,20 +426,8 @@ export default defineComponent({
);
watch(count, () => initialize(state.active));
watch(
() => props.autoplay,
(value) => {
if (value > 0) {
autoplay();
} else {
stopAutoplay();
}
}
);
watch([count, () => props.autoplay], autoplay);
watch([windowSize.width, windowSize.height], resize);
watch(usePageVisibility(), (visible) => {
if (visible === 'visible') {
autoplay();
@ -449,6 +438,7 @@ export default defineComponent({
onMounted(initialize);
onActivated(() => initialize(state.active));
onPopupReopen(() => initialize(state.active));
onDeactivated(stopAutoplay);
onBeforeUnmount(stopAutoplay);

View File

@ -17,7 +17,7 @@
</demo-block>
<demo-block :title="t('title3')">
<van-swipe indicator-color="white" @change="onChange1">
<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>
@ -50,21 +50,19 @@
</demo-block>
<demo-block :title="t('title6')">
<van-swipe @change="onChange2">
<van-swipe>
<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 #indicator="{ active }">
<div class="custom-indicator">{{ active + 1 }}/4</div>
</template>
</van-swipe>
</demo-block>
</template>
<script lang="ts">
import { ref } from 'vue';
import { useTranslate } from '@demo/use-translate';
import { Toast } from '../../toast';
@ -90,7 +88,6 @@ const i18n = {
export default {
setup() {
const t = useTranslate(i18n);
const current = ref(0);
const images = [
'https://img.yzcdn.cn/vant/apple-1.jpg',
'https://img.yzcdn.cn/vant/apple-2.jpg',
@ -98,17 +95,12 @@ export default {
'https://img.yzcdn.cn/vant/apple-4.jpg',
];
const onChange1 = (index: number) => Toast(t('message') + index);
const onChange2 = (index: number) => {
current.value = index;
};
const onChange = (index: number) => Toast(t('message') + index);
return {
t,
images,
current,
onChange1,
onChange2,
onChange,
};
},
};

View File

@ -42,6 +42,7 @@ import {
import { route, RouteProps } from '../composables/use-route';
import { useRefs } from '../composables/use-refs';
import { useExpose } from '../composables/use-expose';
import { onPopupReopen } from '../composables/on-popup-reopen';
// Components
import { Sticky } from '../sticky';
@ -123,10 +124,8 @@ export default defineComponent({
const state = reactive({
inited: false,
position: '',
lineStyle: {} as CSSProperties,
currentIndex: -1,
lineStyle: {
backgroundColor: props.color,
} as CSSProperties,
});
// whether the nav is scrollable
@ -443,6 +442,7 @@ export default defineComponent({
});
onActivated(setLine);
onPopupReopen(setLine);
onMountedOrActivated(init);
useEventListener('scroll', onScroll, { target: scroller.value });