mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[new feature] Tabbar: add route prop
This commit is contained in:
parent
f94df82ceb
commit
96b1d8f81d
@ -143,6 +143,7 @@
|
|||||||
|
|
||||||
### Tabbar
|
### Tabbar
|
||||||
|
|
||||||
|
- 新增`route`属性
|
||||||
- 新增`inactive-color`属性
|
- 新增`inactive-color`属性
|
||||||
|
|
||||||
### TreeSelect
|
### TreeSelect
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { use } from '../utils';
|
import { use, isObj } from '../utils';
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
import Info from '../info';
|
import Info from '../info';
|
||||||
import { route, routeProps } from '../utils/router';
|
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: {
|
methods: {
|
||||||
onClick(event) {
|
onClick(event) {
|
||||||
this.parent.onChange(this.index);
|
this.parent.onChange(this.index);
|
||||||
@ -31,7 +41,8 @@ export default sfc({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render(h) {
|
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'];
|
const color = this.parent[active ? 'activeColor' : 'inactiveColor'];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -89,6 +89,29 @@ export default {
|
|||||||
</van-tabbar>
|
</van-tabbar>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Route Mode
|
||||||
|
|
||||||
|
```html
|
||||||
|
<router-view />
|
||||||
|
|
||||||
|
<van-tabbar route>
|
||||||
|
<van-tabbar-item
|
||||||
|
replace
|
||||||
|
to="/home"
|
||||||
|
icon="home-o"
|
||||||
|
>
|
||||||
|
Tab
|
||||||
|
</van-tabbar-item>
|
||||||
|
<van-tabbar-item
|
||||||
|
replace
|
||||||
|
to="/search"
|
||||||
|
icon="search"
|
||||||
|
>
|
||||||
|
Tab
|
||||||
|
</van-tabbar-item>
|
||||||
|
</van-tabbar>
|
||||||
|
```
|
||||||
|
|
||||||
### Tabbar Props
|
### Tabbar Props
|
||||||
|
|
||||||
| Attribute | Description | Type | Default |
|
| Attribute | Description | Type | Default |
|
||||||
@ -98,6 +121,7 @@ export default {
|
|||||||
| z-index | Z-index | `Number` | `1` |
|
| z-index | Z-index | `Number` | `1` |
|
||||||
| active-color | Color of active tab item | `String` | `#1989fa` |
|
| active-color | Color of active tab item | `String` | `#1989fa` |
|
||||||
| inactive-color | Color of inactive tab item | `String` | `#7d7e80` |
|
| 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` |
|
| 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
|
### Tabbar Events
|
||||||
|
@ -8,6 +8,7 @@ export default sfc({
|
|||||||
|
|
||||||
props: {
|
props: {
|
||||||
value: Number,
|
value: Number,
|
||||||
|
route: Boolean,
|
||||||
activeColor: String,
|
activeColor: String,
|
||||||
inactiveColor: String,
|
inactiveColor: String,
|
||||||
safeAreaInsetBottom: Boolean,
|
safeAreaInsetBottom: Boolean,
|
||||||
|
129
packages/tabbar/test/__snapshots__/index.spec.js.snap
Normal file
129
packages/tabbar/test/__snapshots__/index.spec.js.snap
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`route mode 1`] = `
|
||||||
|
<div class="van-hairline--top-bottom van-tabbar van-tabbar--fixed" style="z-index: 1;">
|
||||||
|
<div class="van-tabbar-item van-tabbar-item--active">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`route mode 2`] = `
|
||||||
|
<div class="van-hairline--top-bottom van-tabbar van-tabbar--fixed" style="z-index: 1;">
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item van-tabbar-item--active">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`route mode 3`] = `
|
||||||
|
<div class="van-hairline--top-bottom van-tabbar van-tabbar--fixed" style="z-index: 1;">
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item van-tabbar-item--active">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">
|
||||||
|
Tab
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`watch tabbar value 1`] = `
|
||||||
|
<div class="van-hairline--top-bottom van-tabbar van-tabbar--fixed" style="z-index: 1;">
|
||||||
|
<div class="van-tabbar-item">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">Tab</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item van-tabbar-item--active">
|
||||||
|
<div class="van-tabbar-item__icon">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="van-tabbar-item__text">Tab</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
90
packages/tabbar/test/index.spec.js
Normal file
90
packages/tabbar/test/index.spec.js
Normal file
@ -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: `
|
||||||
|
<van-tabbar route>
|
||||||
|
<van-tabbar-item replace to="/home">
|
||||||
|
Tab
|
||||||
|
</van-tabbar-item>
|
||||||
|
<van-tabbar-item replace to="/search">
|
||||||
|
Tab
|
||||||
|
</van-tabbar-item>
|
||||||
|
<van-tabbar-item replace :to="{ path: '/star' }">
|
||||||
|
Tab
|
||||||
|
</van-tabbar-item>
|
||||||
|
<van-tabbar-item>
|
||||||
|
Tab
|
||||||
|
</van-tabbar-item>
|
||||||
|
</van-tabbar>
|
||||||
|
`
|
||||||
|
});
|
||||||
|
|
||||||
|
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: `
|
||||||
|
<van-tabbar :value="value">
|
||||||
|
<van-tabbar-item>Tab</van-tabbar-item>
|
||||||
|
<van-tabbar-item>Tab</van-tabbar-item>
|
||||||
|
</van-tabbar>
|
||||||
|
`,
|
||||||
|
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: `
|
||||||
|
<van-tabbar @change="onChange">
|
||||||
|
<van-tabbar-item @click="onClick">Tab</van-tabbar-item>
|
||||||
|
</van-tabbar>
|
||||||
|
`,
|
||||||
|
methods: {
|
||||||
|
onClick,
|
||||||
|
onChange
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.find('.van-tabbar-item').trigger('click');
|
||||||
|
expect(onClick).toHaveBeenCalledTimes(1);
|
||||||
|
expect(onChange).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
@ -89,6 +89,31 @@ export default {
|
|||||||
</van-tabbar>
|
</van-tabbar>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 路由模式
|
||||||
|
|
||||||
|
标签栏支持路由模式,用于搭配`vue-router`使用。路由模式下会匹配页面路径和标签的`to`属性,并自动选中对应的标签
|
||||||
|
|
||||||
|
```html
|
||||||
|
<router-view />
|
||||||
|
|
||||||
|
<van-tabbar route>
|
||||||
|
<van-tabbar-item
|
||||||
|
replace
|
||||||
|
to="/home"
|
||||||
|
icon="home-o"
|
||||||
|
>
|
||||||
|
标签
|
||||||
|
</van-tabbar-item>
|
||||||
|
<van-tabbar-item
|
||||||
|
replace
|
||||||
|
to="/search"
|
||||||
|
icon="search"
|
||||||
|
>
|
||||||
|
标签
|
||||||
|
</van-tabbar-item>
|
||||||
|
</van-tabbar>
|
||||||
|
```
|
||||||
|
|
||||||
### Tabbar Props
|
### Tabbar Props
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
@ -98,6 +123,7 @@ export default {
|
|||||||
| z-index | 元素 z-index | `Number` | `1` | 1.1.9 |
|
| z-index | 元素 z-index | `Number` | `1` | 1.1.9 |
|
||||||
| active-color | 选中标签的颜色 | `String` | `#1989fa` | 1.5.1 |
|
| active-color | 选中标签的颜色 | `String` | `#1989fa` | 1.5.1 |
|
||||||
| inactive-color | 未选中标签的颜色 | `String` | `#7d7e80` | 2.0.0 |
|
| 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 |
|
| safe-area-inset-bottom | 是否开启 iPhone X 底部安全区适配,需要在 `viewport` meta 标签中设置 `viewport-fit=cover` | `Boolean` | `false` | 1.6.15 |
|
||||||
|
|
||||||
### Tabbar Events
|
### Tabbar Events
|
||||||
|
Loading…
x
Reference in New Issue
Block a user