diff --git a/src/tab/README.md b/src/tab/README.md index ef80688fb..009dc2637 100644 --- a/src/tab/README.md +++ b/src/tab/README.md @@ -241,6 +241,7 @@ Use [ref](https://vuejs.org/v2/api/#ref) to get Tabs instance and call instance | Name | Description | Attribute | Return value | | --- | --- | --- | --- | | resize | Resize Tabs when container element resized | - | void | +| scrollTo `v2.9.3` | Go to specified tab in scrollspy mode | name | void | ### Tabs Slots diff --git a/src/tab/README.zh-CN.md b/src/tab/README.zh-CN.md index db16f8397..757ea4aeb 100644 --- a/src/tab/README.zh-CN.md +++ b/src/tab/README.zh-CN.md @@ -243,9 +243,10 @@ export default { 通过 ref 可以获取到 Tabs 实例并调用实例方法,详见[组件实例方法](#/zh-CN/quickstart#zu-jian-shi-li-fang-fa) -| 方法名 | 说明 | 参数 | 返回值 | -| ------ | -------------------------------------------- | ---- | ------ | -| resize | 外层元素大小变化后,可以调用此方法来触发重绘 | - | void | +| 方法名 | 说明 | 参数 | 返回值 | +| --- | --- | --- | --- | +| resize | 外层元素大小变化后,可以调用此方法来触发重绘 | - | void | +| scrollTo `v2.9.3` | 滚动到指定的标签页,在滚动导航模式下可用 | name: 标识符 | void | ### Tabs Slots diff --git a/src/tab/test/__snapshots__/index.spec.js.snap b/src/tab/test/__snapshots__/index.spec.js.snap index 6f4a6c641..4cc331f17 100644 --- a/src/tab/test/__snapshots__/index.spec.js.snap +++ b/src/tab/test/__snapshots__/index.spec.js.snap @@ -229,7 +229,7 @@ exports[`render nav-left & nav-right slot 1`] = ` exports[`rendered event 1`] = `<div role="tabpanel" class="van-tab__pane" style="">Text</div>`; -exports[`scrollspy 1`] = ` +exports[`scrollspy prop 1`] = ` <div class="van-tabs van-tabs--line"> <div> <div class="van-sticky"> @@ -251,7 +251,7 @@ exports[`scrollspy 1`] = ` </div> `; -exports[`scrollspy 2`] = ` +exports[`scrollspy prop 2`] = ` <div class="van-tabs van-tabs--line"> <div> <div class="van-sticky"> diff --git a/src/tab/test/index.spec.js b/src/tab/test/index.spec.js index 9c9d326c4..cf1b6ec39 100644 --- a/src/tab/test/index.spec.js +++ b/src/tab/test/index.spec.js @@ -258,7 +258,7 @@ test('info prop', () => { expect(wrapper).toMatchSnapshot(); }); -test('scrollspy', async () => { +test('scrollspy prop', async () => { const onChange = jest.fn(); window.scrollTo = jest.fn(); @@ -288,6 +288,30 @@ test('scrollspy', async () => { expect(onChange).toHaveBeenCalledWith('c', 'title3'); }); +test('scrollTo method', async () => { + const onChange = jest.fn(); + window.scrollTo = jest.fn(); + + mount({ + template: ` + <van-tabs scrollspy sticky @change="onChange" ref="root"> + <van-tab name="a" title="title1">Text</van-tab> + <van-tab name="b" title="title2">Text</van-tab> + <van-tab name="c" title="title3">Text</van-tab> + </van-tabs> + `, + methods: { + onChange, + }, + mounted() { + this.$refs.root.scrollTo('b'); + }, + }); + + await later(); + expect(onChange).toHaveBeenCalledWith('b', 'title2'); +}); + test('rendered event', async () => { const onRendered = jest.fn(); diff --git a/src/tabs/index.js b/src/tabs/index.js index 9765c0e2f..d52d35eea 100644 --- a/src/tabs/index.js +++ b/src/tabs/index.js @@ -299,7 +299,15 @@ export default createComponent({ this.$emit('scroll', params); }, - scrollToCurrentContent() { + // @exposed-api + scrollTo(name) { + this.$nextTick(() => { + this.setCurrentIndexByName(name); + this.scrollToCurrentContent(true); + }); + }, + + scrollToCurrentContent(immediate = false) { if (this.scrollspy) { const target = this.children[this.currentIndex]; const el = target?.$el; @@ -308,7 +316,7 @@ export default createComponent({ const to = getElementTop(el, this.scroller) - this.scrollOffset; this.lockScroll = true; - scrollTopTo(this.scroller, to, +this.duration, () => { + scrollTopTo(this.scroller, to, immediate ? 0 : +this.duration, () => { this.lockScroll = false; }); } diff --git a/types/tabs.d.ts b/types/tabs.d.ts index 57b8cad0a..1b9d9becd 100644 --- a/types/tabs.d.ts +++ b/types/tabs.d.ts @@ -2,4 +2,6 @@ import { VanComponent } from './component'; export class Tabs extends VanComponent { resize(): void; + + scrollTo(name: string | number): void; }