diff --git a/example/app.json b/example/app.json
index 941074de..48717b4c 100644
--- a/example/app.json
+++ b/example/app.json
@@ -20,6 +20,7 @@
"pages/switch/index",
"pages/search/index",
"pages/tag/index",
+ "pages/toast/index",
"pages/tabbar/index",
"pages/tree-select/index"
],
diff --git a/example/config.js b/example/config.js
index 2622236e..5db5f75f 100644
--- a/example/config.js
+++ b/example/config.js
@@ -84,6 +84,10 @@ export default [
path: '/actionsheet',
title: 'Actionsheet 上拉菜单'
},
+ {
+ path: '/toast',
+ title: 'Toast 轻提示'
+ },
{
path: '/notify',
title: 'Notify 消息通知'
diff --git a/example/pages/toast/index.js b/example/pages/toast/index.js
new file mode 100644
index 00000000..2a1ffc45
--- /dev/null
+++ b/example/pages/toast/index.js
@@ -0,0 +1,41 @@
+import Page from '../../common/page';
+import Toast from '../../dist/toast/index';
+
+Page({
+ showToast() {
+ Toast('我是提示文案,建议不超过十五字~');
+ },
+
+ showLoadingToast() {
+ Toast.loading({ mask: true, message: '加载中...' });
+ },
+
+ showSuccessToast() {
+ Toast.success('成功文案');
+ },
+
+ showFailToast() {
+ Toast.fail('失败提示');
+ },
+
+ showCustomizedToast(duration) {
+ const text = second => `倒计时 ${second} 秒`;
+ const toast = Toast.loading({
+ duration: 0,
+ forbidClick: true,
+ loadingType: 'spinner',
+ message: text(3)
+ });
+
+ let second = 3;
+ const timer = setInterval(() => {
+ second--;
+ if (second) {
+ toast.setData({ message: text(second) });
+ } else {
+ clearInterval(timer);
+ Toast.clear();
+ }
+ }, 1000);
+ }
+});
diff --git a/example/pages/toast/index.json b/example/pages/toast/index.json
new file mode 100644
index 00000000..bcbe4b59
--- /dev/null
+++ b/example/pages/toast/index.json
@@ -0,0 +1,8 @@
+{
+ "navigationBarTitleText": "Toast 轻提示",
+ "usingComponents": {
+ "demo-block": "../../components/demo-block/index",
+ "van-toast": "../../dist/toast/index",
+ "van-button": "../../dist/button/index"
+ }
+}
diff --git a/example/pages/toast/index.wxml b/example/pages/toast/index.wxml
new file mode 100644
index 00000000..a776096d
--- /dev/null
+++ b/example/pages/toast/index.wxml
@@ -0,0 +1,18 @@
+
+ 文字提示
+
+
+
+ 加载提示
+
+
+
+ 成功提示
+ 失败提示
+
+
+
+ 高级用法
+
+
+
diff --git a/example/pages/toast/index.wxss b/example/pages/toast/index.wxss
new file mode 100644
index 00000000..e69de29b
diff --git a/packages/overlay/index.js b/packages/overlay/index.js
new file mode 100644
index 00000000..e2a08dc3
--- /dev/null
+++ b/packages/overlay/index.js
@@ -0,0 +1,11 @@
+Component({
+ properties: {
+ show: Boolean
+ },
+
+ methods: {
+ onClickOverlay() {
+
+ }
+ }
+});
diff --git a/packages/overlay/index.json b/packages/overlay/index.json
new file mode 100644
index 00000000..467ce294
--- /dev/null
+++ b/packages/overlay/index.json
@@ -0,0 +1,3 @@
+{
+ "component": true
+}
diff --git a/packages/overlay/index.pcss b/packages/overlay/index.pcss
new file mode 100644
index 00000000..e69de29b
diff --git a/packages/overlay/index.wxml b/packages/overlay/index.wxml
new file mode 100644
index 00000000..bf46ec1c
--- /dev/null
+++ b/packages/overlay/index.wxml
@@ -0,0 +1,5 @@
+
diff --git a/packages/toast/README.md b/packages/toast/README.md
new file mode 100644
index 00000000..4dad800e
--- /dev/null
+++ b/packages/toast/README.md
@@ -0,0 +1,96 @@
+## Toast 轻提示
+
+### 使用指南
+
+在 index.json 中引入组件
+```json
+"usingComponents": {
+ "van-toast": "path/to/vant-weapp/dist/toast/index"
+}
+```
+
+### 代码演示
+
+#### 文字提示
+
+```javascript
+const Toast = require('path/to/vant-weapp/dist/toast/index');
+
+Toast('我是提示文案,建议不超过十五字~');
+```
+
+```html
+
+```
+
+#### 加载提示
+
+```javascript
+Toast.loading({
+ mask: true,
+ message: '加载中...'
+});
+```
+
+
+#### 成功/失败提示
+
+```javascript
+Toast.success('成功文案');
+Toast.fail('失败文案');
+```
+
+
+#### 高级用法
+
+```javascript
+const toast = Toast.loading({
+ duration: 0, // 持续展示 toast
+ forbidClick: true, // 禁用背景点击
+ message: '倒计时 3 秒',
+ loadingType: 'spinner',
+ selector: '#custom-selector'
+});
+
+let second = 3;
+const timer = setInterval(() => {
+ second--;
+ if (second) {
+ toast.setData({
+ message: `倒计时 ${second} 秒`
+ });
+ } else {
+ clearInterval(timer);
+ Toast.clear();
+ }
+}, 1000);
+```
+
+```html
+
+```
+
+### 方法
+
+| 方法名 | 参数 | 返回值 | 介绍 |
+|-----------|-----------|-----------|-------------|
+| Toast | `options | message` | toast 实例 | 展示提示 |
+| Toast.loading | `options | message` | toast 实例 | 展示加载提示 |
+| Toast.success | `options | message` | toast 实例 | 展示成功提示 |
+| Toast.fail | `options | message` | toast 实例 | 展示失败提示 |
+| Toast.clear | `clearAll` | `void` | 关闭提示 |
+| Toast.setDefaultOptions | `options` | `void` | 修改默认配置,对所有 Toast 生效 |
+| Toast.resetDefaultOptions | - | `void` | 重置默认配置,对所有 Toast 生效 |
+
+### Options
+
+| 参数 | 说明 | 类型 | 默认值 |
+|-----------|-----------|-----------|-------------|
+| type | 提示类型,可选值为 `loading` `success` `fail` `html` | `String` | `text` |
+| position | 位置,可选值为 `top` `middle` `bottom` | `String` | `middle` |
+| message | 内容 | `String` | `''` | - |
+| mask | 是否显示背景蒙层 | `Boolean` | `false` |
+| forbidClick | 是否禁止背景点击 | `Boolean` | `false` |
+| loadingType | 加载图标类型, 可选值为 `spinner` | `String` | `circular` |
+| duration | 展示时长(ms),值为 0 时,toast 不会消失 | `Number` | `3000` |
+| selector | 自定义选择器 | `String` | `van-toast` |
diff --git a/packages/toast/index.js b/packages/toast/index.js
new file mode 100644
index 00000000..a64e1306
--- /dev/null
+++ b/packages/toast/index.js
@@ -0,0 +1,32 @@
+import Toast from './toast';
+
+Component({
+ properties: {
+ show: Boolean,
+ mask: Boolean,
+ message: String,
+ forbidClick: Boolean,
+ type: {
+ type: String,
+ value: 'text'
+ },
+ loadingType: {
+ type: String,
+ value: 'circular'
+ },
+ position: {
+ type: String,
+ value: 'middle'
+ }
+ },
+
+ methods: {
+ clear() {
+ this.setData({
+ show: false
+ });
+ }
+ }
+});
+
+export default Toast;
diff --git a/packages/toast/index.json b/packages/toast/index.json
new file mode 100644
index 00000000..19bf9891
--- /dev/null
+++ b/packages/toast/index.json
@@ -0,0 +1,8 @@
+{
+ "component": true,
+ "usingComponents": {
+ "van-icon": "../icon/index",
+ "van-popup": "../popup/index",
+ "van-loading": "../loading/index"
+ }
+}
diff --git a/packages/toast/index.pcss b/packages/toast/index.pcss
new file mode 100644
index 00000000..067af85d
--- /dev/null
+++ b/packages/toast/index.pcss
@@ -0,0 +1,69 @@
+@import '../common/style/var.pcss';
+
+.van-toast {
+ top: 50%;
+ left: 50%;
+ display: flex;
+ position: fixed;
+ color: $white;
+ font-size: 12px;
+ line-height: 1.2;
+ border-radius: 5px;
+ word-break: break-all;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ box-sizing: border-box;
+ transform: translate(-50%, -50%);
+ background-color: rgba(0, 0, 0, .7);
+ z-index: 3001;
+
+ &__overlay {
+ z-index: 3000;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+
+ &--mask {
+ background-color: rgba(0, 0, 0, .7);
+ }
+ }
+
+ &--text {
+ padding: 12px;
+ min-width: 220px;
+ }
+
+ &--icon {
+ width: 120px;
+ min-height: 120px;
+ padding: 15px;
+
+ .van-toast__icon {
+ height: 1em;
+ font-size: 50px;
+ }
+
+ .van-toast__text {
+ font-size: 14px;
+ padding-top: 10px;
+ }
+ }
+
+ &__loading {
+ margin: 10px 0 5px;
+ }
+
+ &--top {
+ top: 50px;
+ transform: translate(-50%, 0);
+ }
+
+ &--bottom {
+ top: auto;
+ bottom: 50px;
+ transform: translate(-50%, 0);
+ }
+}
diff --git a/packages/toast/index.wxml b/packages/toast/index.wxml
new file mode 100644
index 00000000..89565eca
--- /dev/null
+++ b/packages/toast/index.wxml
@@ -0,0 +1,23 @@
+
+
+
+ {{ message }}
+
+
+
+
+
+ {{ message }}
+
+
diff --git a/packages/toast/toast.js b/packages/toast/toast.js
new file mode 100644
index 00000000..c72dab44
--- /dev/null
+++ b/packages/toast/toast.js
@@ -0,0 +1,68 @@
+import { isObj } from '../utils/index';
+
+const defaultOptions = {
+ type: 'text',
+ mask: false,
+ message: '',
+ show: true,
+ duration: 3000,
+ position: 'middle',
+ forbidClick: false,
+ loadingType: 'circular',
+ selector: '#van-toast'
+};
+const parseOptions = message => isObj(message) ? message : { message };
+
+let queue = [];
+let currentOptions = { ...defaultOptions };
+
+function Toast(options = {}) {
+ options = {
+ ...currentOptions,
+ ...parseOptions(options)
+ };
+
+ const pages = getCurrentPages();
+ const ctx = pages[pages.length - 1];
+
+ const toast = ctx.selectComponent(options.selector);
+ delete options.selector;
+
+ queue.push(toast);
+ toast.setData(options);
+ clearTimeout(toast.timer);
+
+ if (options.duration > 0) {
+ toast.timer = setTimeout(() => {
+ toast.clear();
+ queue = queue.filter(item => item !== toast);
+ }, options.duration);
+ }
+
+ return toast;
+};
+
+const createMethod = type => options => Toast({
+ type, ...parseOptions(options)
+});
+
+['loading', 'success', 'fail'].forEach(method => {
+ Toast[method] = createMethod(method);
+});
+
+Toast.clear = all => {
+ queue.forEach(toast => {
+ toast.clear();
+ });
+ queue = [];
+};
+
+Toast.setDefaultOptions = options => {
+ Object.assign(currentOptions, options);
+};
+
+Toast.resetDefaultOptions = () => {
+ currentOptions = { ...defaultOptions };
+};
+
+export default Toast;