mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[improvement] Tabs: use relation mixin
This commit is contained in:
parent
912d691f9e
commit
c1da495cb7
@ -1,11 +1,11 @@
|
|||||||
/* eslint-disable object-shorthand */
|
/* eslint-disable object-shorthand */
|
||||||
import { use } from '../utils';
|
import { use } from '../utils';
|
||||||
import { FindParentMixin } from '../mixins/find-parent';
|
import { ChildrenMixin } from '../mixins/relation';
|
||||||
|
|
||||||
const [sfc, bem] = use('tab');
|
const [sfc, bem] = use('tab');
|
||||||
|
|
||||||
export default sfc({
|
export default sfc({
|
||||||
mixins: [FindParentMixin],
|
mixins: [ChildrenMixin('vanTabs')],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
title: String,
|
title: String,
|
||||||
@ -19,10 +19,6 @@ export default sfc({
|
|||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
index() {
|
|
||||||
return this.parent.tabs.indexOf(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
selected() {
|
selected() {
|
||||||
return this.index === this.parent.curActive;
|
return this.index === this.parent.curActive;
|
||||||
}
|
}
|
||||||
@ -38,24 +34,12 @@ export default sfc({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
|
||||||
this.findParent('van-tabs');
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
const { tabs } = this.parent;
|
|
||||||
const index = this.parent.slots().indexOf(this.$vnode);
|
|
||||||
tabs.splice(index === -1 ? tabs.length : index, 0, this);
|
|
||||||
|
|
||||||
if (this.slots('title')) {
|
if (this.slots('title')) {
|
||||||
this.parent.renderTitle(this.$refs.title, this.index);
|
this.parent.renderTitle(this.$refs.title, this.index);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
|
||||||
this.parent.tabs.splice(this.index, 1);
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h) {
|
render(h) {
|
||||||
const { slots } = this;
|
const { slots } = this;
|
||||||
const shouldRender = this.inited || !this.parent.lazyRender;
|
const shouldRender = this.inited || !this.parent.lazyRender;
|
||||||
|
@ -6,15 +6,16 @@ exports[`change tabs data 1`] = `
|
|||||||
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
||||||
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68);"></div>
|
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68);"></div>
|
||||||
<div class="van-tab van-tab--active"><span class="van-ellipsis">title1</span></div>
|
<div class="van-tab van-tab--active"><span class="van-ellipsis">title1</span></div>
|
||||||
<div class="van-tab"><span class="van-ellipsis"></span></div>
|
<div class="van-tab">
|
||||||
|
<div><span>title2</span></div>
|
||||||
|
</div>
|
||||||
<div class="van-tab van-tab--disabled"><span class="van-ellipsis">title3</span></div>
|
<div class="van-tab van-tab--disabled"><span class="van-ellipsis">title3</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-tabs__content">
|
<div class="van-tabs__content">
|
||||||
<div class="van-tab__pane" style="">Text</div>
|
<div class="van-tab__pane">Text</div>
|
||||||
<div class="van-tab__pane" style="display: none;">
|
<div class="van-tab__pane" style="display: none;">
|
||||||
<!---->
|
<!---->
|
||||||
<div><span>title2</span></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="van-tab__pane" style="display: none;">
|
<div class="van-tab__pane" style="display: none;">
|
||||||
<!---->
|
<!---->
|
||||||
@ -35,7 +36,7 @@ exports[`change tabs data 2`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-tabs__content">
|
<div class="van-tabs__content">
|
||||||
<div class="van-tab__pane" style="">Text</div>
|
<div class="van-tab__pane">Text</div>
|
||||||
<div class="van-tab__pane" style="display: none;">
|
<div class="van-tab__pane" style="display: none;">
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
@ -105,7 +106,7 @@ exports[`lazy render 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-tabs__content">
|
<div class="van-tabs__content">
|
||||||
<div class="van-tab__pane" style="">Text</div>
|
<div class="van-tab__pane">Text</div>
|
||||||
<div class="van-tab__pane" style="display: none;">
|
<div class="van-tab__pane" style="display: none;">
|
||||||
<!---->
|
<!---->
|
||||||
<div><span>title2</span></div>
|
<div><span>title2</span></div>
|
||||||
@ -130,7 +131,7 @@ exports[`lazy render 2`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-tabs__content">
|
<div class="van-tabs__content">
|
||||||
<div class="van-tab__pane" style="">Text</div>
|
<div class="van-tab__pane">Text</div>
|
||||||
<div class="van-tab__pane" style="display: none;">
|
<div class="van-tab__pane" style="display: none;">
|
||||||
Text
|
Text
|
||||||
</div>
|
</div>
|
||||||
@ -149,7 +150,7 @@ exports[`render nav-left & nav-right slot 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-tabs__content">
|
<div class="van-tabs__content">
|
||||||
<div class="van-tab__pane" style="">Text</div>
|
<div class="van-tab__pane">Text</div>
|
||||||
<div class="van-tab__pane" style="display: none;">
|
<div class="van-tab__pane" style="display: none;">
|
||||||
<!---->
|
<!---->
|
||||||
<div><span>title2</span></div>
|
<div><span>title2</span></div>
|
||||||
@ -165,7 +166,7 @@ exports[`swipe to switch tab 1`] = `
|
|||||||
<div class="van-tabs van-tabs--line">
|
<div class="van-tabs van-tabs--line">
|
||||||
<div class="van-tabs__wrap van-hairline--top-bottom">
|
<div class="van-tabs__wrap van-hairline--top-bottom">
|
||||||
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
||||||
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68); width: 2px; transform: translateX(-1px);"></div>
|
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68);"></div>
|
||||||
<div class="van-tab van-tab--active"><span class="van-ellipsis">title1</span></div>
|
<div class="van-tab van-tab--active"><span class="van-ellipsis">title1</span></div>
|
||||||
<div class="van-tab">
|
<div class="van-tab">
|
||||||
<div><span>title2</span></div>
|
<div><span>title2</span></div>
|
||||||
@ -174,7 +175,7 @@ exports[`swipe to switch tab 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-tabs__content">
|
<div class="van-tabs__content">
|
||||||
<div class="van-tab__pane" style="">Text</div>
|
<div class="van-tab__pane">Text</div>
|
||||||
<div class="van-tab__pane" style="display: none;">
|
<div class="van-tab__pane" style="display: none;">
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
@ -189,9 +190,9 @@ exports[`swipe to switch tab 2`] = `
|
|||||||
<div class="van-tabs van-tabs--line">
|
<div class="van-tabs van-tabs--line">
|
||||||
<div class="van-tabs__wrap van-hairline--top-bottom">
|
<div class="van-tabs__wrap van-hairline--top-bottom">
|
||||||
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
||||||
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68); width: 2px; transform: translateX(-1px);"></div>
|
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68);"></div>
|
||||||
<div class="van-tab"><span class="van-ellipsis">title1</span></div>
|
<div class="van-tab van-tab--active"><span class="van-ellipsis">title1</span></div>
|
||||||
<div class="van-tab van-tab--active">
|
<div class="van-tab">
|
||||||
<div><span>title2</span></div>
|
<div><span>title2</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-tab van-tab--disabled"><span class="van-ellipsis">title3</span></div>
|
<div class="van-tab van-tab--disabled"><span class="van-ellipsis">title3</span></div>
|
||||||
@ -213,9 +214,9 @@ exports[`swipe to switch tab 3`] = `
|
|||||||
<div class="van-tabs van-tabs--line">
|
<div class="van-tabs van-tabs--line">
|
||||||
<div class="van-tabs__wrap van-hairline--top-bottom">
|
<div class="van-tabs__wrap van-hairline--top-bottom">
|
||||||
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
||||||
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68); width: 2px; transform: translateX(-1px);"></div>
|
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68);"></div>
|
||||||
<div class="van-tab"><span class="van-ellipsis">title1</span></div>
|
<div class="van-tab van-tab--active"><span class="van-ellipsis">title1</span></div>
|
||||||
<div class="van-tab van-tab--active">
|
<div class="van-tab">
|
||||||
<div><span>title2</span></div>
|
<div><span>title2</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-tab van-tab--disabled"><span class="van-ellipsis">title3</span></div>
|
<div class="van-tab van-tab--disabled"><span class="van-ellipsis">title3</span></div>
|
||||||
@ -237,7 +238,7 @@ exports[`swipe to switch tab 4`] = `
|
|||||||
<div class="van-tabs van-tabs--line">
|
<div class="van-tabs van-tabs--line">
|
||||||
<div class="van-tabs__wrap van-hairline--top-bottom">
|
<div class="van-tabs__wrap van-hairline--top-bottom">
|
||||||
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
<div class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">
|
||||||
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68); width: 2px; transform: translateX(-1px);"></div>
|
<div class="van-tabs__line" style="background-color: rgb(255, 68, 68);"></div>
|
||||||
<div class="van-tab van-tab--active"><span class="van-ellipsis">title1</span></div>
|
<div class="van-tab van-tab--active"><span class="van-ellipsis">title1</span></div>
|
||||||
<div class="van-tab">
|
<div class="van-tab">
|
||||||
<div><span>title2</span></div>
|
<div><span>title2</span></div>
|
||||||
|
@ -88,6 +88,8 @@ test('swipe to switch tab', async () => {
|
|||||||
test('change tabs data', async () => {
|
test('change tabs data', async () => {
|
||||||
const wrapper = createWrapper();
|
const wrapper = createWrapper();
|
||||||
|
|
||||||
|
await later();
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
|
||||||
wrapper.setData({
|
wrapper.setData({
|
||||||
|
@ -2,13 +2,19 @@ import { use, isDef } from '../utils';
|
|||||||
import { raf } from '../utils/raf';
|
import { raf } from '../utils/raf';
|
||||||
import { on, off } from '../utils/event';
|
import { on, off } from '../utils/event';
|
||||||
import { TouchMixin } from '../mixins/touch';
|
import { TouchMixin } from '../mixins/touch';
|
||||||
import { setScrollTop, getScrollTop, getElementTop, getScrollEventTarget } from '../utils/scroll';
|
import { ParentMixin } from '../mixins/relation';
|
||||||
|
import {
|
||||||
|
setScrollTop,
|
||||||
|
getScrollTop,
|
||||||
|
getElementTop,
|
||||||
|
getScrollEventTarget
|
||||||
|
} from '../utils/scroll';
|
||||||
|
|
||||||
const [sfc, bem] = use('tabs');
|
const [sfc, bem] = use('tabs');
|
||||||
const tabBem = use('tab')[1];
|
const tabBem = use('tab')[1];
|
||||||
|
|
||||||
export default sfc({
|
export default sfc({
|
||||||
mixins: [TouchMixin],
|
mixins: [TouchMixin, ParentMixin('vanTabs')],
|
||||||
|
|
||||||
model: {
|
model: {
|
||||||
prop: 'active'
|
prop: 'active'
|
||||||
@ -59,7 +65,6 @@ export default sfc({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tabs: [],
|
|
||||||
position: '',
|
position: '',
|
||||||
curActive: null,
|
curActive: null,
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
@ -76,7 +81,7 @@ export default sfc({
|
|||||||
computed: {
|
computed: {
|
||||||
// whether the nav is scrollable
|
// whether the nav is scrollable
|
||||||
scrollable() {
|
scrollable() {
|
||||||
return this.tabs.length > this.swipeThreshold || !this.ellipsis;
|
return this.children.length > this.swipeThreshold || !this.ellipsis;
|
||||||
},
|
},
|
||||||
|
|
||||||
wrapStyle() {
|
wrapStyle() {
|
||||||
@ -124,7 +129,7 @@ export default sfc({
|
|||||||
this.setLine();
|
this.setLine();
|
||||||
},
|
},
|
||||||
|
|
||||||
tabs() {
|
children() {
|
||||||
this.correctActive(this.curActive || this.active);
|
this.correctActive(this.curActive || this.active);
|
||||||
this.scrollIntoView();
|
this.scrollIntoView();
|
||||||
this.setLine();
|
this.setLine();
|
||||||
@ -218,7 +223,7 @@ export default sfc({
|
|||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
if (deltaX > 0 && curActive !== 0) {
|
if (deltaX > 0 && curActive !== 0) {
|
||||||
this.setCurActive(curActive - 1);
|
this.setCurActive(curActive - 1);
|
||||||
} else if (deltaX < 0 && curActive !== this.tabs.length - 1) {
|
} else if (deltaX < 0 && curActive !== this.children.length - 1) {
|
||||||
this.setCurActive(curActive + 1);
|
this.setCurActive(curActive + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,8 +288,8 @@ export default sfc({
|
|||||||
// correct the value of active
|
// correct the value of active
|
||||||
correctActive(active) {
|
correctActive(active) {
|
||||||
active = +active;
|
active = +active;
|
||||||
const exist = this.tabs.some(tab => tab.index === active);
|
const exist = this.children.some(tab => tab.index === active);
|
||||||
const defaultActive = (this.tabs[0] || {}).index || 0;
|
const defaultActive = (this.children[0] || {}).index || 0;
|
||||||
this.setCurActive(exist ? active : defaultActive);
|
this.setCurActive(exist ? active : defaultActive);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -294,7 +299,7 @@ export default sfc({
|
|||||||
this.$emit('input', active);
|
this.$emit('input', active);
|
||||||
|
|
||||||
if (this.curActive !== null) {
|
if (this.curActive !== null) {
|
||||||
this.$emit('change', active, this.tabs[active].title);
|
this.$emit('change', active, this.children[active].title);
|
||||||
}
|
}
|
||||||
this.curActive = active;
|
this.curActive = active;
|
||||||
}
|
}
|
||||||
@ -304,8 +309,8 @@ export default sfc({
|
|||||||
const diff = reverse ? -1 : 1;
|
const diff = reverse ? -1 : 1;
|
||||||
let index = active;
|
let index = active;
|
||||||
|
|
||||||
while (index >= 0 && index < this.tabs.length) {
|
while (index >= 0 && index < this.children.length) {
|
||||||
if (!this.tabs[index].disabled) {
|
if (!this.children[index].disabled) {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
index += diff;
|
index += diff;
|
||||||
@ -314,7 +319,7 @@ export default sfc({
|
|||||||
|
|
||||||
// emit event when clicked
|
// emit event when clicked
|
||||||
onClick(index) {
|
onClick(index) {
|
||||||
const { title, disabled } = this.tabs[index];
|
const { title, disabled } = this.children[index];
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
this.$emit('disabled', index, title);
|
this.$emit('disabled', index, title);
|
||||||
} else {
|
} else {
|
||||||
@ -400,7 +405,7 @@ export default sfc({
|
|||||||
render(h) {
|
render(h) {
|
||||||
const { type, ellipsis, animated, scrollable } = this;
|
const { type, ellipsis, animated, scrollable } = this;
|
||||||
|
|
||||||
const Nav = this.tabs.map((tab, index) => (
|
const Nav = this.children.map((tab, index) => (
|
||||||
<div
|
<div
|
||||||
ref="tabs"
|
ref="tabs"
|
||||||
refInFor
|
refInFor
|
||||||
@ -425,7 +430,10 @@ export default sfc({
|
|||||||
<div
|
<div
|
||||||
ref="wrap"
|
ref="wrap"
|
||||||
style={this.wrapStyle}
|
style={this.wrapStyle}
|
||||||
class={[bem('wrap', { scrollable }), { 'van-hairline--top-bottom': type === 'line' }]}
|
class={[
|
||||||
|
bem('wrap', { scrollable }),
|
||||||
|
{ 'van-hairline--top-bottom': type === 'line' }
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<div ref="nav" class={bem('nav', [type])} style={this.navStyle}>
|
<div ref="nav" class={bem('nav', [type])} style={this.navStyle}>
|
||||||
{this.slots('nav-left')}
|
{this.slots('nav-left')}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user