diff --git a/example/app.json b/example/app.json
index 1c070cf4..b9624ea4 100644
--- a/example/app.json
+++ b/example/app.json
@@ -1,4 +1,18 @@
{
+ "tabBar": {
+ "custom": true,
+ "color": "#000000",
+ "selectedColor": "#000000",
+ "backgroundColor": "#000000",
+ "list": [
+ {
+ "pagePath": "pages/tabbar/index"
+ },
+ {
+ "pagePath": "pages/tabbar1/index"
+ }
+ ]
+ },
"pages": [
"pages/dashboard/index",
"pages/action-sheet/index",
@@ -25,6 +39,7 @@
"pages/slider/index",
"pages/tab/index",
"pages/tabbar/index",
+ "pages/tabbar1/index",
"pages/tag/index",
"pages/toast/index",
"pages/transition/index",
@@ -99,4 +114,4 @@
"van-picker": "../../dist/picker/index"
},
"sitemapLocation": "sitemap.json"
-}
\ No newline at end of file
+}
diff --git a/example/custom-tab-bar/index.js b/example/custom-tab-bar/index.js
new file mode 100644
index 00000000..e4070b3b
--- /dev/null
+++ b/example/custom-tab-bar/index.js
@@ -0,0 +1,33 @@
+Component({
+ data: {
+ active: 0,
+ list: [
+ {
+ icon: 'home-o',
+ text: 'tabbar示例1',
+ url: '/pages/tabbar/index'
+ },
+ {
+ icon: 'search',
+ text: 'tabbar示例2',
+ url: '/pages/tabbar1/index'
+ }
+ ]
+ },
+
+ methods: {
+ onChange(event) {
+ this.setData({ active: event.detail });
+ wx.switchTab({
+ url: this.data.list[event.detail].url
+ });
+ },
+
+ init() {
+ const page = getCurrentPages().pop();
+ this.setData({
+ active: this.data.list.findIndex(item => item.url === `/${page.route}`)
+ });
+ }
+ }
+});
diff --git a/example/custom-tab-bar/index.json b/example/custom-tab-bar/index.json
new file mode 100644
index 00000000..8b7e402d
--- /dev/null
+++ b/example/custom-tab-bar/index.json
@@ -0,0 +1,7 @@
+{
+ "component": true,
+ "usingComponents": {
+ "van-tabbar": "../dist/tabbar/index",
+ "van-tabbar-item": "../dist/tabbar-item/index"
+ }
+}
diff --git a/example/custom-tab-bar/index.wxml b/example/custom-tab-bar/index.wxml
new file mode 100644
index 00000000..48f951bf
--- /dev/null
+++ b/example/custom-tab-bar/index.wxml
@@ -0,0 +1,5 @@
+
+ {{
+ item.text
+ }}
+
diff --git a/example/pages/dashboard/index.js b/example/pages/dashboard/index.js
index 6ceeb77c..4feaa9f8 100644
--- a/example/pages/dashboard/index.js
+++ b/example/pages/dashboard/index.js
@@ -11,5 +11,12 @@ Page({
this.setData({
activeNames: event.detail
});
+ },
+
+ onClick(event) {
+ const { switchTab, url } = event.currentTarget.dataset;
+ if (switchTab) {
+ wx.switchTab({ url });
+ }
}
});
diff --git a/example/pages/dashboard/index.wxml b/example/pages/dashboard/index.wxml
index 350dbb9a..9c6bcabf 100644
--- a/example/pages/dashboard/index.wxml
+++ b/example/pages/dashboard/index.wxml
@@ -32,7 +32,10 @@
wx:key="item.title"
is-link
url="/pages{{ item.path }}/index"
+ data-url="/pages{{ item.path }}/index"
+ data-switch-tab="{{ true }}"
title="{{ item.title }}"
+ bind:click="onClick"
/>
diff --git a/example/pages/tabbar/index.js b/example/pages/tabbar/index.js
index 127878b1..cab9d473 100644
--- a/example/pages/tabbar/index.js
+++ b/example/pages/tabbar/index.js
@@ -3,16 +3,16 @@ import Page from '../../common/page';
Page({
data: {
active: 0,
- active2: 0,
- icon: {
- normal:
- 'https://img.yzcdn.cn/public_files/2017/10/13/c547715be149dd3faa817e4a948b40c4.png',
- active:
- 'https://img.yzcdn.cn/public_files/2017/10/13/793c77793db8641c4c325b7f25bf130d.png'
- }
+ active2: 'home',
+ active3: 0
+ },
+
+ onShow() {
+ this.getTabBar().init();
},
onChange(event) {
- console.log(event.detail);
+ const { key } = event.currentTarget.dataset;
+ this.setData({ [key]: event.detail });
}
});
diff --git a/example/pages/tabbar/index.wxml b/example/pages/tabbar/index.wxml
index c14251ec..e9262b66 100644
--- a/example/pages/tabbar/index.wxml
+++ b/example/pages/tabbar/index.wxml
@@ -1,6 +1,37 @@
+ 标签
+ 标签
+ 标签
+ 标签
+
+
+
+
+
+ 标签
+ 标签
+ 标签
+ 标签
+
+
+
+
+ 标签
-
-
-
-
-
-
- 自定义
-
- 标签
- 标签
-
-
-
-
-
- 标签
- 标签
- 标签
- 标签
-
-
diff --git a/example/pages/tabbar1/index.js b/example/pages/tabbar1/index.js
new file mode 100644
index 00000000..9514a02e
--- /dev/null
+++ b/example/pages/tabbar1/index.js
@@ -0,0 +1,23 @@
+import Page from '../../common/page';
+
+Page({
+ data: {
+ active: 0,
+ active2: 0,
+ icon: {
+ normal:
+ 'https://img.yzcdn.cn/public_files/2017/10/13/c547715be149dd3faa817e4a948b40c4.png',
+ active:
+ 'https://img.yzcdn.cn/public_files/2017/10/13/793c77793db8641c4c325b7f25bf130d.png'
+ }
+ },
+
+ onShow() {
+ this.getTabBar().init();
+ },
+
+ onChange(event) {
+ const { key } = event.currentTarget.dataset;
+ this.setData({ [key]: event.detail });
+ }
+});
diff --git a/example/pages/tabbar1/index.json b/example/pages/tabbar1/index.json
new file mode 100644
index 00000000..93a01237
--- /dev/null
+++ b/example/pages/tabbar1/index.json
@@ -0,0 +1,3 @@
+{
+ "navigationBarTitleText": "Tabbar 标签栏"
+}
diff --git a/example/pages/tabbar1/index.wxml b/example/pages/tabbar1/index.wxml
new file mode 100644
index 00000000..068856ae
--- /dev/null
+++ b/example/pages/tabbar1/index.wxml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+ 自定义
+
+ 标签
+ 标签
+
+
+
+
+
+ 标签
+ 标签
+ 标签
+ 标签
+
+
diff --git a/example/pages/tabbar1/index.wxss b/example/pages/tabbar1/index.wxss
new file mode 100644
index 00000000..98ea1074
--- /dev/null
+++ b/example/pages/tabbar1/index.wxss
@@ -0,0 +1,3 @@
+.tabbar {
+ position: relative !important;
+}
diff --git a/packages/tabbar-item/index.ts b/packages/tabbar-item/index.ts
index 521fae35..da832c1a 100644
--- a/packages/tabbar-item/index.ts
+++ b/packages/tabbar-item/index.ts
@@ -4,15 +4,15 @@ VantComponent({
props: {
info: null,
icon: String,
- dot: Boolean
+ dot: Boolean,
+ name: {
+ type: [String, Number]
+ }
},
relation: {
name: 'tabbar',
- type: 'ancestor',
- linked(target: Weapp.Component) {
- this.parent = target;
- }
+ type: 'ancestor'
},
data: {
@@ -27,11 +27,31 @@ VantComponent({
this.$emit('click');
},
- setActive({ active, color }): Promise {
- if (this.data.active !== active) {
- return this.set({ active, color });
+ updateFromParent() {
+ const { parent } = this;
+ if (!parent) {
+ return;
}
- return Promise.resolve();
+
+ const index = parent.children.indexOf(this);
+ const parentData = parent.data;
+ const { data } = this;
+ const active = (data.name || index) === parentData.active;
+ const patch: { [key: string]: any } = {};
+
+ if (active !== data.active) {
+ patch.active = active;
+ }
+ if (parentData.activeColor !== data.activeColor) {
+ patch.activeColor = parentData.activeColor;
+ }
+ if (parentData.inactiveColor !== data.inactiveColor) {
+ patch.inactiveColor = parentData.inactiveColor;
+ }
+
+ return Object.keys(patch).length > 0
+ ? this.set(patch)
+ : Promise.resolve();
}
}
});
diff --git a/packages/tabbar-item/index.wxml b/packages/tabbar-item/index.wxml
index 58940604..b2649ae4 100644
--- a/packages/tabbar-item/index.wxml
+++ b/packages/tabbar-item/index.wxml
@@ -2,7 +2,7 @@
diff --git a/packages/tabbar/README.md b/packages/tabbar/README.md
index ce141141..80adc64d 100644
--- a/packages/tabbar/README.md
+++ b/packages/tabbar/README.md
@@ -17,9 +17,9 @@
```html
标签
- 标签
- 标签
- 标签
+ 标签
+ 标签
+ 标签
```
@@ -35,6 +35,41 @@ Page({
});
```
+### 通过名称匹配
+
+在标签指定`name`属性的情况下,`v-model`的值为当前标签的`name`
+
+```html
+
+ 标签
+ 标签
+ 标签
+ 标签
+
+```
+
+```javascript
+Page({
+ data: {
+ active: 'home'
+ },
+ onChange(event) {
+ console.log(event.detail);
+ }
+});
+```
+
+### 显示徽标
+
+```html
+
+ 标签
+ 标签
+ 标签
+ 标签
+
+```
+
### 自定义图标
可以通过 slot 自定义图标,其中 icon slot 代表未选中状态下的图标,icon-active slot 代表选中状态下的图标
@@ -81,6 +116,7 @@ Page({
标签
@@ -102,27 +138,33 @@ Page({
});
```
+### 结合自定义 tabBar
+
+请参考 [微信官方文档](https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html) 与 [代码片段](https://developers.weixin.qq.com/s/FjLU4mmp7r9s)
+
### Tabbar API
| 参数 | 说明 | 类型 | 默认值 |
|-----------|-----------|-----------|-------------|
| active | 当前选中标签的索引 | `Number` | - |
-| active-color | 选中标签的颜色 | `String` | `#1989fa` |
| fixed | 是否固定在底部 | `Boolean` | `true` |
| border | 是否展示外边框 | `Boolean` | `true` |
| z-index | 元素 z-index | `Number` | `1` |
+| active-color | 选中标签的颜色 | `String` | `#1989fa` |
+| inactive-color | 未选中标签的颜色 | `String` | `#7d7e80` |
| safe-area-inset-bottom | 是否为 iPhoneX 留出底部安全距离 | `Boolean` | `true` |
### Tabbar Event
| 事件名 | 说明 | 参数 |
|-----------|-----------|-----------|
-| bind:change | 切换标签时触发 | event.detail: 当前选中标签的索引 |
+| bind:change | 切换标签时触发 | event.detail: 当前选中标签的名称或索引值 |
### TabbarItem API
| 参数 | 说明 | 类型 | 默认值 |
|-----------|-----------|-----------|-----------|
+| name | 标签名称,作为匹配的标识符 | `String | Number` | 当前标签的索引值 |
| icon | 图标名称或图片链接,可选值见 Icon 组件 | `String` | - |
| dot | 是否显示小红点 | `Boolean` | - |
| info | 图标右上角提示信息 | `String | Number` | - |
diff --git a/packages/tabbar/index.ts b/packages/tabbar/index.ts
index cc841adb..286c332c 100644
--- a/packages/tabbar/index.ts
+++ b/packages/tabbar/index.ts
@@ -8,20 +8,31 @@ VantComponent({
name: 'tabbar-item',
type: 'descendant',
linked(target: Weapp.Component) {
- this.children = this.children || [];
this.children.push(target);
- this.setActiveItem();
+ target.parent = this;
+ target.updateFromParent();
},
unlinked(target: Weapp.Component) {
- this.children = this.children || [];
- this.children = this.children.filter(item => item !== target);
- this.setActiveItem();
+ this.children = this.children.filter(
+ (item: Weapp.Component) => item !== target
+ );
+ this.updateChildren();
}
},
props: {
- active: Number,
- activeColor: String,
+ active: {
+ type: [Number, String],
+ observer: 'updateChildren'
+ },
+ activeColor: {
+ type: String,
+ observer: 'updateChildren'
+ },
+ inactiveColor: {
+ type: String,
+ observer: 'updateChildren'
+ },
fixed: {
type: Boolean,
value: true
@@ -36,40 +47,28 @@ VantComponent({
}
},
- watch: {
- active(active: number) {
- this.currentActive = active;
- this.setActiveItem();
- }
- },
-
- created() {
- this.currentActive = this.data.active;
+ beforeCreate() {
+ this.children = [];
},
methods: {
- setActiveItem(): Promise {
- if (!Array.isArray(this.children) || !this.children.length) {
+ updateChildren() {
+ const { children } = this;
+ if (!Array.isArray(children) || !children.length) {
return Promise.resolve();
}
+
return Promise.all(
- this.children.map((item: Weapp.Component, index: number) =>
- item.setActive({
- active: index === this.currentActive,
- color: this.data.activeColor
- })
- )
+ children.map((child: Weapp.Component) => child.updateFromParent())
);
},
onChange(child: Weapp.Component) {
- const active = (this.children || []).indexOf(child);
+ const index = this.children.indexOf(child);
+ const active = child.data.name || index;
- if (active !== this.currentActive && active !== -1) {
- this.currentActive = active;
- this.setActiveItem().then(() => {
- this.$emit('change', active);
- });
+ if (active !== this.data.active) {
+ this.$emit('change', active);
}
}
}