diff --git a/docs/src/demo-entry.js b/docs/src/demo-entry.js
index 15fc1e21e..fbdac6068 100644
--- a/docs/src/demo-entry.js
+++ b/docs/src/demo-entry.js
@@ -27,6 +27,7 @@ export default {
'loading': () => wrapper(import('../../packages/loading/demo'), 'loading'),
'nav-bar': () => wrapper(import('../../packages/nav-bar/demo'), 'nav-bar'),
'notice-bar': () => wrapper(import('../../packages/notice-bar/demo'), 'notice-bar'),
+ 'notify': () => wrapper(import('../../packages/notify/demo'), 'notify'),
'number-keyboard': () => wrapper(import('../../packages/number-keyboard/demo'), 'number-keyboard'),
'pagination': () => wrapper(import('../../packages/pagination/demo'), 'pagination'),
'panel': () => wrapper(import('../../packages/panel/demo'), 'panel'),
diff --git a/docs/src/doc.config.js b/docs/src/doc.config.js
index 565bb1246..ca4ef296c 100644
--- a/docs/src/doc.config.js
+++ b/docs/src/doc.config.js
@@ -172,6 +172,10 @@ module.exports = {
path: '/loading',
title: 'Loading 加载'
},
+ {
+ path: '/notify',
+ title: 'Notify 消息通知'
+ },
{
path: '/pull-refresh',
title: 'PullRefresh 下拉刷新'
@@ -469,6 +473,10 @@ module.exports = {
path: '/loading',
title: 'Loading'
},
+ {
+ path: '/notify',
+ title: 'Notify'
+ },
{
path: '/pull-refresh',
title: 'PullRefresh'
diff --git a/docs/src/docs-entry.js b/docs/src/docs-entry.js
index a13c0f2ba..70b5caf4e 100644
--- a/docs/src/docs-entry.js
+++ b/docs/src/docs-entry.js
@@ -62,6 +62,8 @@ export default {
'nav-bar.zh-CN': () => import('../../packages/nav-bar/zh-CN.md'),
'notice-bar.en-US': () => import('../../packages/notice-bar/en-US.md'),
'notice-bar.zh-CN': () => import('../../packages/notice-bar/zh-CN.md'),
+ 'notify.en-US': () => import('../../packages/notify/en-US.md'),
+ 'notify.zh-CN': () => import('../../packages/notify/zh-CN.md'),
'number-keyboard.en-US': () => import('../../packages/number-keyboard/en-US.md'),
'number-keyboard.zh-CN': () => import('../../packages/number-keyboard/zh-CN.md'),
'pagination.en-US': () => import('../../packages/pagination/en-US.md'),
diff --git a/packages/circle/index.vue b/packages/circle/index.vue
index d6a338f8d..9b8c2de58 100644
--- a/packages/circle/index.vue
+++ b/packages/circle/index.vue
@@ -24,7 +24,7 @@
diff --git a/packages/notify/demo/index.vue b/packages/notify/demo/index.vue
new file mode 100644
index 000000000..bd8fad6b9
--- /dev/null
+++ b/packages/notify/demo/index.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/notify/en-US.md b/packages/notify/en-US.md
new file mode 100644
index 000000000..949a28358
--- /dev/null
+++ b/packages/notify/en-US.md
@@ -0,0 +1,57 @@
+## Notify
+
+### Install
+
+``` javascript
+import { Notify } from 'vant';
+
+Vue.use(Notify);
+```
+
+### Usage
+
+#### Basic Usage
+
+```js
+Notify('Notify Message');
+```
+
+#### Custom Config
+
+```js
+Notify({
+ message: 'Notify Message',
+ duration: 1000,
+ background: '#1989fa'
+});
+```
+
+#### $notify Method
+
+After import the Notify component, the $notify method is automatically mounted on Vue.prototype, making it easy to call within a vue component.
+
+```js
+export default {
+ mounted() {
+ this.$notify('Notify Message');
+ }
+}
+```
+
+### Methods
+
+| Methods | Attribute | Return value | Description |
+|------|------|------|------|
+| Notify | `options | message` | notify instance | Show notify |
+| Notify.clear | - | `void` | Close notify |
+| Notify.setDefaultOptions | `options` | `void` | Set default options of all notifies |
+| Notify.resetDefaultOptions | - | `void` | Reset default options of all notifies |
+
+### API
+
+| Attribute | Description | Type | Default |
+|------|------|------|------|
+| message | Message | `String` | - |
+| duration | Duration(ms), won't disappear if value is 0 | `Number` | `3000` |
+| color | Message color | `String` | `#fff` | |
+| background | Background color | `String` | `#f44` |
diff --git a/packages/notify/index.js b/packages/notify/index.js
new file mode 100644
index 000000000..428f5c411
--- /dev/null
+++ b/packages/notify/index.js
@@ -0,0 +1,74 @@
+import Vue from 'vue';
+import VanNotify from './Notify';
+import { RED, WHITE } from '../utils/color';
+import { isObj, isServer } from '../utils';
+
+let timer;
+let instance;
+
+const initInstance = () => {
+ instance = new (Vue.extend(VanNotify))({
+ el: document.createElement('div')
+ });
+
+ document.body.appendChild(instance.$el);
+};
+
+const parseOptions = message => (isObj(message) ? message : { message });
+
+const Notify = options => {
+ /* istanbul ignore if */
+ if (isServer) {
+ return;
+ }
+
+ if (!instance) {
+ initInstance();
+ }
+
+ options = {
+ ...Notify.currentOptions,
+ ...parseOptions(options)
+ };
+
+ Object.assign(instance, options);
+ clearTimeout(timer);
+
+ if (options.duration > 0) {
+ timer = setTimeout(Notify.clear, options.duration);
+ }
+
+ return instance;
+};
+
+Notify.clear = () => {
+ if (instance) {
+ instance.value = false;
+ }
+};
+
+Notify.defaultOptions = {
+ value: true,
+ text: '',
+ color: WHITE,
+ background: RED,
+ duration: 3000
+};
+
+Notify.setDefaultOptions = options => {
+ Object.assign(Notify.currentOptions, options);
+};
+
+Notify.resetDefaultOptions = () => {
+ Notify.currentOptions = { ...Notify.defaultOptions };
+};
+
+Notify.install = () => {
+ Vue.use(VanNotify);
+};
+
+Notify.resetDefaultOptions();
+
+Vue.prototype.$notify = Notify;
+
+export default Notify;
diff --git a/packages/notify/index.less b/packages/notify/index.less
new file mode 100644
index 000000000..aee0ee00b
--- /dev/null
+++ b/packages/notify/index.less
@@ -0,0 +1,12 @@
+@import '../style/var';
+
+.van-notify {
+ position: fixed;
+ top: 0;
+ width: 100%;
+ text-align: center;
+ box-sizing: border-box;
+ padding: @notify-padding;
+ font-size: @notify-font-size;
+ line-height: @notify-line-height;
+}
diff --git a/packages/notify/test/__snapshots__/demo.spec.js.snap b/packages/notify/test/__snapshots__/demo.spec.js.snap
new file mode 100644
index 000000000..7aac71288
--- /dev/null
+++ b/packages/notify/test/__snapshots__/demo.spec.js.snap
@@ -0,0 +1,12 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders demo correctly 1`] = `
+
+
+
+
+
+
+
+
+`;
diff --git a/packages/notify/test/__snapshots__/index.spec.js.snap b/packages/notify/test/__snapshots__/index.spec.js.snap
new file mode 100644
index 000000000..0637b69c0
--- /dev/null
+++ b/packages/notify/test/__snapshots__/index.spec.js.snap
@@ -0,0 +1,31 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`create a notify 1`] = `
+
+ test
+
+`;
+
+exports[`notify disappear 1`] = `
+
+ test
+
+`;
+
+exports[`notify disappear 2`] = `
+
+ test
+
+`;
+
+exports[`notify disappear 3`] = `
+
+ text2
+
+`;
+
+exports[`notify disappear 4`] = `
+
+ text2
+
+`;
diff --git a/packages/notify/test/demo.spec.js b/packages/notify/test/demo.spec.js
new file mode 100644
index 000000000..d647cfabc
--- /dev/null
+++ b/packages/notify/test/demo.spec.js
@@ -0,0 +1,4 @@
+import Demo from '../demo';
+import demoTest from '../../../test/demo-test';
+
+demoTest(Demo);
diff --git a/packages/notify/test/index.spec.js b/packages/notify/test/index.spec.js
new file mode 100644
index 000000000..6191a7311
--- /dev/null
+++ b/packages/notify/test/index.spec.js
@@ -0,0 +1,49 @@
+import Notify from '../';
+import { transitionStub, later } from '../../../test/utils';
+
+transitionStub();
+
+test('create a notify', async() => {
+ // should not cause error when call clear before show notify
+ Notify.clear();
+
+ const notify = Notify('test');
+
+ await later();
+ expect(notify.$el.outerHTML).toMatchSnapshot();
+});
+
+test('notify disappear', async() => {
+ const notify = Notify({
+ message: 'test',
+ color: 'red',
+ background: 'blue',
+ duration: 10
+ });
+
+ await later();
+ expect(notify.$el.outerHTML).toMatchSnapshot();
+
+ await later(20);
+ expect(notify.$el.outerHTML).toMatchSnapshot();
+
+ Notify({
+ message: 'text2',
+ duration: 0
+ });
+
+ await later();
+ expect(notify.$el.outerHTML).toMatchSnapshot();
+
+ Notify.clear();
+ await later();
+ expect(notify.$el.outerHTML).toMatchSnapshot();
+});
+
+test('set default options', () => {
+ Notify.setDefaultOptions({ duration: 1000 });
+ expect(Notify().duration).toEqual(1000);
+ Notify.resetDefaultOptions();
+ expect(Notify().duration).toEqual(3000);
+ Notify.clear();
+});
diff --git a/packages/notify/zh-CN.md b/packages/notify/zh-CN.md
new file mode 100644
index 000000000..8d86d10f5
--- /dev/null
+++ b/packages/notify/zh-CN.md
@@ -0,0 +1,56 @@
+## Notify 消息提示
+
+### 使用指南
+``` javascript
+import { Notify } from 'vant';
+
+Vue.use(Notify);
+```
+
+### 代码演示
+
+#### 基础用法
+
+```js
+Notify('通知内容');
+```
+
+#### 自定义配置
+
+```js
+Notify({
+ message: '通知内容',
+ duration: 1000,
+ background: '#1989fa'
+});
+```
+
+#### 组件内调用
+
+引入 Notify 组件后,会自动在 Vue 的 prototype 上挂载 $notify 方法,便于在组件内调用。
+
+```js
+export default {
+ mounted() {
+ this.$notify('提示文案');
+ }
+}
+```
+
+### 方法
+
+| 方法名 | 参数 | 返回值 | 介绍 |
+|------|------|------|------|
+| Notify | `options | message` | notify 实例 | 展示提示 |
+| Notify.clear | - | `void` | 关闭提示 |
+| Notify.setDefaultOptions | `options` | `void` | 修改默认配置,对所有 Notify 生效 |
+| Notify.resetDefaultOptions | - | `void` | 重置默认配置,对所有 Notify 生效 |
+
+### Options
+
+| 参数 | 说明 | 类型 | 默认值 | 版本 |
+|------|------|------|------|------|
+| message | 展示文案 | `String` | - | 1.4.6 |
+| duration | 展示时长(ms),值为 0 时,notify 不会消失 | `Number` | `3000` | 1.4.6 |
+| color | 字体颜色 | `String` | `#fff` | 1.4.6 |
+| background | 背景颜色 | `String` | `#f44` | 1.4.6 |
diff --git a/packages/progress/index.vue b/packages/progress/index.vue
index 3d4b650ee..07024c535 100644
--- a/packages/progress/index.vue
+++ b/packages/progress/index.vue
@@ -18,7 +18,7 @@