From 96b1d8f81d8545762bd6e7b43c858973a1962197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=98=89=E6=B6=B5?= Date: Mon, 13 May 2019 14:48:55 +0800 Subject: [PATCH] [new feature] Tabbar: add route prop --- docs/markdown/v2-progress-tracking.md | 1 + packages/tabbar-item/index.js | 15 +- packages/tabbar/en-US.md | 24 ++++ packages/tabbar/index.js | 1 + .../test/__snapshots__/index.spec.js.snap | 129 ++++++++++++++++++ packages/tabbar/test/index.spec.js | 90 ++++++++++++ packages/tabbar/zh-CN.md | 26 ++++ 7 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 packages/tabbar/test/__snapshots__/index.spec.js.snap create mode 100644 packages/tabbar/test/index.spec.js diff --git a/docs/markdown/v2-progress-tracking.md b/docs/markdown/v2-progress-tracking.md index 50cd57879..4becf6a98 100644 --- a/docs/markdown/v2-progress-tracking.md +++ b/docs/markdown/v2-progress-tracking.md @@ -143,6 +143,7 @@ ### Tabbar +- 新增`route`属性 - 新增`inactive-color`属性 ### TreeSelect diff --git a/packages/tabbar-item/index.js b/packages/tabbar-item/index.js index dd86de430..ec5d63b51 100644 --- a/packages/tabbar-item/index.js +++ b/packages/tabbar-item/index.js @@ -1,4 +1,4 @@ -import { use } from '../utils'; +import { use, isObj } from '../utils'; import Icon from '../icon'; import Info from '../info'; import { route, routeProps } from '../utils/router'; @@ -22,6 +22,16 @@ export default sfc({ }; }, + computed: { + routeActive() { + const { to, $route } = this; + if (to && $route) { + const path = isObj(to) ? to.path : to; + return $route.path === path; + } + } + }, + methods: { onClick(event) { this.parent.onChange(this.index); @@ -31,7 +41,8 @@ export default sfc({ }, render(h) { - const { icon, slots, active } = this; + const { icon, slots } = this; + const active = this.parent.route ? this.routeActive : this.active; const color = this.parent[active ? 'activeColor' : 'inactiveColor']; return ( diff --git a/packages/tabbar/en-US.md b/packages/tabbar/en-US.md index 1b4938a8b..4266fd40f 100644 --- a/packages/tabbar/en-US.md +++ b/packages/tabbar/en-US.md @@ -89,6 +89,29 @@ export default { ``` +#### Route Mode + +```html + + + + + Tab + + + Tab + + +``` + ### Tabbar Props | Attribute | Description | Type | Default | @@ -98,6 +121,7 @@ export default { | z-index | Z-index | `Number` | `1` | | active-color | Color of active tab item | `String` | `#1989fa` | | inactive-color | Color of inactive tab item | `String` | `#7d7e80` | +| route | Whether to enable route mode | `Boolean` | `false` | | safe-area-inset-bottom | Whether to enable bottom safe area adaptation, to enable those features use `viewport-fit=cover` in the `viewport` meta tag | `Boolean` | `false` | ### Tabbar Events diff --git a/packages/tabbar/index.js b/packages/tabbar/index.js index 90f37eb58..5261dae7b 100644 --- a/packages/tabbar/index.js +++ b/packages/tabbar/index.js @@ -8,6 +8,7 @@ export default sfc({ props: { value: Number, + route: Boolean, activeColor: String, inactiveColor: String, safeAreaInsetBottom: Boolean, diff --git a/packages/tabbar/test/__snapshots__/index.spec.js.snap b/packages/tabbar/test/__snapshots__/index.spec.js.snap new file mode 100644 index 000000000..0dd9075b3 --- /dev/null +++ b/packages/tabbar/test/__snapshots__/index.spec.js.snap @@ -0,0 +1,129 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`route mode 1`] = ` +
+
+
+ +
+
+ Tab +
+
+
+
+ +
+
+ Tab +
+
+
+
+ +
+
+ Tab +
+
+
+
+ +
+
+ Tab +
+
+
+`; + +exports[`route mode 2`] = ` +
+
+
+ +
+
+ Tab +
+
+
+
+ +
+
+ Tab +
+
+
+
+ +
+
+ Tab +
+
+
+
+ +
+
+ Tab +
+
+
+`; + +exports[`route mode 3`] = ` +
+
+
+ +
+
+ Tab +
+
+
+
+ +
+
+ Tab +
+
+
+
+ +
+
+ Tab +
+
+
+
+ +
+
+ Tab +
+
+
+`; + +exports[`watch tabbar value 1`] = ` +
+
+
+ +
+
Tab
+
+
+
+ +
+
Tab
+
+
+`; diff --git a/packages/tabbar/test/index.spec.js b/packages/tabbar/test/index.spec.js new file mode 100644 index 000000000..4ae7219c2 --- /dev/null +++ b/packages/tabbar/test/index.spec.js @@ -0,0 +1,90 @@ +import { mount, later } from '../../../test/utils'; +import Vue from 'vue'; +import Tabbar from '..'; +import TabbarItem from '../../tabbar-item'; + +Vue.use(Tabbar); +Vue.use(TabbarItem); + +test('route mode', async () => { + Vue.util.defineReactive(Vue.prototype, '$route', { path: '/home' }); + + Vue.prototype.$router = { + replace(to) { + Vue.prototype.$route.path = typeof to === 'string' ? to : to.path; + } + }; + + const wrapper = mount({ + template: ` + + + Tab + + + Tab + + + Tab + + + Tab + + + ` + }); + + expect(wrapper).toMatchSnapshot(); + + const items = wrapper.findAll('.van-tabbar-item'); + + items.at(1).trigger('click'); + await later(); + expect(wrapper).toMatchSnapshot(); + + items.at(2).trigger('click'); + items.at(3).trigger('click'); + await later(); + expect(wrapper).toMatchSnapshot(); +}); + + +test('watch tabbar value', () => { + const wrapper = mount({ + template: ` + + Tab + Tab + + `, + data() { + return { + value: 0 + }; + } + }); + + wrapper.setData({ value: 1 }); + expect(wrapper).toMatchSnapshot(); +}); + +test('click event', () => { + const onClick = jest.fn(); + const onChange = jest.fn(); + + const wrapper = mount({ + template: ` + + Tab + + `, + methods: { + onClick, + onChange + } + }); + + wrapper.find('.van-tabbar-item').trigger('click'); + expect(onClick).toHaveBeenCalledTimes(1); + expect(onChange).toHaveBeenCalledTimes(0); +}); diff --git a/packages/tabbar/zh-CN.md b/packages/tabbar/zh-CN.md index e54c30101..4edd12313 100644 --- a/packages/tabbar/zh-CN.md +++ b/packages/tabbar/zh-CN.md @@ -89,6 +89,31 @@ export default { ``` +#### 路由模式 + +标签栏支持路由模式,用于搭配`vue-router`使用。路由模式下会匹配页面路径和标签的`to`属性,并自动选中对应的标签 + +```html + + + + + 标签 + + + 标签 + + +``` + ### Tabbar Props | 参数 | 说明 | 类型 | 默认值 | 版本 | @@ -98,6 +123,7 @@ export default { | z-index | 元素 z-index | `Number` | `1` | 1.1.9 | | active-color | 选中标签的颜色 | `String` | `#1989fa` | 1.5.1 | | inactive-color | 未选中标签的颜色 | `String` | `#7d7e80` | 2.0.0 | +| route | 是否开启路由模式 | `Boolean` | `false` | 2.0.0 | | safe-area-inset-bottom | 是否开启 iPhone X 底部安全区适配,需要在 `viewport` meta 标签中设置 `viewport-fit=cover` | `Boolean` | `false` | 1.6.15 | ### Tabbar Events