diff --git a/bin/build-entry.js b/bin/build-entry.js
index 4cbd41f8d..77e0b5ee2 100644
--- a/bin/build-entry.js
+++ b/bin/build-entry.js
@@ -21,6 +21,7 @@ const install = function(Vue) {
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
Vue.prototype.$notify = Notification;
+ Vue.prototype.$message = Message;
};
// auto install
diff --git a/components.json b/components.json
index 3f311394d..1aedb8f28 100644
--- a/components.json
+++ b/components.json
@@ -1,7 +1,4 @@
{
- "group": [
- "./packages/group/index.js"
- ],
"select-dropdown": [
"./packages/select-dropdown/index.js"
],
@@ -148,5 +145,8 @@
],
"spinner": [
"./packages/spinner/index.js"
+ ],
+ "message": [
+ "./packages/message/index.js"
]
}
diff --git a/examples/docs/checkbox.md b/examples/docs/checkbox.md
index 619ec4213..310343c51 100644
--- a/examples/docs/checkbox.md
+++ b/examples/docs/checkbox.md
@@ -41,22 +41,26 @@
### 多个勾选框,绑定到同一个数组
-
-
-
-
-
+
+
+
+
+
+
+
{{ checkList }}
```html
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+## 基本用法
+
+
+ 打开消息提示
+
+
+```html
+
+ 打开消息提示
+
+
+
+```
+
+## 不同状态
+
+ 成功
+ 警告
+ 错误
+
+
+```html
+
+ 成功
+ 警告
+ 错误
+
+
+
+```
+
+## 可关闭
+
+ 消息
+ 成功
+ 警告
+ 错误
+
+
+```html
+
+ 消息
+ 成功
+ 警告
+ 错误
+
+
+
+```
+
+## 全局方法
+
+element 为 Vue.prototype 添加了全局方法 $message。因此在 vue instance 中可以采用本页面中的方式调用 `Message`。
+
+## 单独引用
+
+单独引入 `Message`:
+
+```javascript
+import { Message } from 'element-ui';
+```
+
+此时调用方法为 `Message(options)`。
+
+## API
+| 参数 | 说明 | 类型 | 可选值 | 默认值 |
+|---------- |-------------- |---------- |-------------------------------- |-------- |
+| message | 消息文字 | string | | |
+| type | 主题 | string | 'success', 'warning', 'info', 'error' | 'info' |
+| duration | 显示时间, 毫秒。设为 0 则不会自动关闭 | number | | 3000 |
+| showClose | 是否显示关闭按钮 | boolean | | false |
+| onClose | 关闭时的回调函数, 参数为被关闭的 message 实例 | function | | |
diff --git a/examples/docs/pagination.md b/examples/docs/pagination.md
index 58344f70e..c51d709b9 100644
--- a/examples/docs/pagination.md
+++ b/examples/docs/pagination.md
@@ -50,8 +50,8 @@
@@ -85,6 +85,10 @@
| current-page | 当前页数 | Number | | 0|
| layout | 组件布局,子组件名用逗号分隔。| String | `prev`, `pager`, `next`, `jumper`, `slot`, `->`, `total` | 'prev, pager, next, jumper, slot, ->, total' |
| page-sizes | 切换每页显示个数的子组件值 | Number[] | | [10, 20, 30, 40, 50, 100] |
-| size-change | pageSize 改变时会触发的事件 | Function | | |
-| current-change | currentPage 改变时会触发的事件 | Function | | |
+
+## 事件
+| 事件名称 | 说明 | 回调函数 |
+|---------|--------|---------|
+| sizechange | pageSize 改变时会触发 | `size` |
+| currentchange | currentPage 改变时会触发 | `currentPage` |
diff --git a/examples/docs/radio.md b/examples/docs/radio.md
index 598dff6a1..862dfa7e5 100644
--- a/examples/docs/radio.md
+++ b/examples/docs/radio.md
@@ -16,16 +16,16 @@
## 基本用法
-
-
-
+
+
+
```html
-
-
-
+
+
+
diff --git a/packages/dialog/package.json b/packages/dialog/package.json
index a223e6050..aff2f4a59 100644
--- a/packages/dialog/package.json
+++ b/packages/dialog/package.json
@@ -12,6 +12,6 @@
"author": "elemefe",
"license": "MIT",
"devDependencies": {
- "vue-popup": "^0.2.1"
+ "vue-popup": "^0.2.2"
}
}
diff --git a/packages/message-box/package.json b/packages/message-box/package.json
index 1d36034cf..64d1610ef 100644
--- a/packages/message-box/package.json
+++ b/packages/message-box/package.json
@@ -12,6 +12,6 @@
"author": "elemefe",
"license": "MIT",
"dependencies": {
- "vue-popup": "^0.2.1"
+ "vue-popup": "^0.2.2"
}
}
diff --git a/packages/message/cooking.conf.js b/packages/message/cooking.conf.js
new file mode 100644
index 000000000..e9dcae592
--- /dev/null
+++ b/packages/message/cooking.conf.js
@@ -0,0 +1,31 @@
+var cooking = require('cooking');
+var path = require('path');
+
+cooking.set({
+ entry: {
+ index: path.join(__dirname, 'index.js')
+ },
+ dist: path.join(__dirname, 'lib'),
+ template: false,
+ format: 'umd',
+ moduleName: 'ElMessage',
+ extractCSS: 'style.css',
+
+ extends: ['vue', 'saladcss']
+});
+
+cooking.add('resolve.alias', {
+ 'main': path.join(__dirname, '../../src'),
+ 'packages': path.join(__dirname, '../../packages')
+});
+
+cooking.add('externals', {
+ vue: {
+ root: 'Vue',
+ commonjs: 'vue',
+ commonjs2: 'vue',
+ amd: 'vue'
+ }
+});
+
+module.exports = cooking.resolve();
diff --git a/packages/message/index.js b/packages/message/index.js
new file mode 100644
index 000000000..fe700f641
--- /dev/null
+++ b/packages/message/index.js
@@ -0,0 +1,3 @@
+import Message from './src/main.js';
+
+module.exports = Message;
diff --git a/packages/message/package.json b/packages/message/package.json
new file mode 100644
index 000000000..116095fdf
--- /dev/null
+++ b/packages/message/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "el-message",
+ "version": "0.0.0",
+ "description": "A message component for Vue.js.",
+ "keywords": [
+ "element",
+ "vue",
+ "component"
+ ],
+ "main": "./lib/index.js",
+ "repository": "https://github.com/element-component/element/tree/master/packages/message",
+ "author": "elemefe",
+ "license": "MIT",
+ "dependencies": {}
+}
diff --git a/packages/message/src/main.js b/packages/message/src/main.js
new file mode 100644
index 000000000..9b67a5a78
--- /dev/null
+++ b/packages/message/src/main.js
@@ -0,0 +1,57 @@
+import Vue from 'vue';
+let MessageConstructor = Vue.extend(require('./main.vue'));
+
+let instance;
+let instances = [];
+let seed = 1;
+
+var Message = function(options) {
+ options = options || {};
+ let userOnClose = options.onClose;
+ let id = 'message_' + seed++;
+
+ options.onClose = function() {
+ Message.close(id, userOnClose);
+ };
+
+ instance = new MessageConstructor({
+ data: options
+ });
+ instance.id = id;
+ instance.vm = instance.$mount();
+ document.body.appendChild(instance.vm.$el);
+ instance.vm.visible = true;
+ instance.dom = instance.vm.$el;
+
+ let topDist = 0;
+ for (let i = 0, len = instances.length; i < len; i++) {
+ topDist += instances[i].$el.offsetHeight + 20;
+ }
+ topDist += 20;
+ instance.top = topDist;
+ instances.push(instance);
+};
+
+Message.close = function(id, userOnClose) {
+ let index;
+ let removedHeight;
+ for (var i = 0, len = instances.length; i < len; i++) {
+ if (id === instances[i].id) {
+ if (typeof userOnClose === 'function') {
+ userOnClose(instances[i]);
+ }
+ index = i;
+ removedHeight = instances[i].dom.offsetHeight;
+ instances.splice(i, 1);
+ break;
+ }
+ }
+
+ if (len > 1) {
+ for (i = index; i < len - 1 ; i++) {
+ instances[i].dom.style.top = parseInt(instances[i].dom.style.top, 10) - removedHeight - 20 + 'px';
+ }
+ }
+};
+
+export default Message;
diff --git a/packages/message/src/main.vue b/packages/message/src/main.vue
new file mode 100644
index 000000000..db4787025
--- /dev/null
+++ b/packages/message/src/main.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/pagination/src/pager.vue b/packages/pagination/src/pager.vue
index a5a7dd004..879da2ea0 100644
--- a/packages/pagination/src/pager.vue
+++ b/packages/pagination/src/pager.vue
@@ -71,7 +71,7 @@
}
if (newPage !== currentPage) {
- this.$emit('currentChange', newPage);
+ this.$emit('currentchange', newPage);
}
}
},
diff --git a/packages/pagination/src/pagination.js b/packages/pagination/src/pagination.js
index 82a7b56d2..a4c0cf6e0 100644
--- a/packages/pagination/src/pagination.js
+++ b/packages/pagination/src/pagination.js
@@ -49,7 +49,7 @@ export default {
const TEMPLATE_MAP = {
prev: ,
jumper: ,
- pager: ,
+ pager: ,
next: ,
sizes: ,
slot: ,
@@ -114,6 +114,12 @@ export default {
},
Sizes: {
+ created() {
+ if (Array.isArray(this.$parent.pageSizes)) {
+ this.$parent.internalPageSize = this.$parent.pageSizes[0];
+ }
+ },
+
render(h) {
return (
- {{label}}
+ {{label}}
@@ -28,9 +28,7 @@
name: 'ElRadio',
props: {
- value: {
- twoWay: true
- },
+ value: [String, Number],
label: {
type: [String, Number],
required: true
@@ -43,11 +41,6 @@
focus: false
};
},
- watch: {
- value(value) {
- this.$emit('onchange', value);
- }
- },
computed: {
_value: {
get() {
@@ -55,9 +48,9 @@
},
set(newValue) {
if (this.value !== undefined) {
- this.value = newValue;
+ this.$emit('input', newValue);
} else {
- this.$parent.value = newValue;
+ this.$parent.$emit('input', newValue);
}
}
}
diff --git a/packages/select/src/select.vue b/packages/select/src/select.vue
index 74d7fd22f..bff1ef3e0 100644
--- a/packages/select/src/select.vue
+++ b/packages/select/src/select.vue
@@ -281,6 +281,7 @@
visible(val) {
if (!val) {
+ this.$refs.reference.$el.querySelector('input').blur();
this.$el.querySelector('.el-input__icon').classList.remove('is-reverse');
this.broadcast('select-dropdown', 'destroyPopper');
if (this.$refs.input) {
@@ -423,6 +424,9 @@
},
toggleMenu() {
+ if (this.filterable && this.query === '' && this.visible) {
+ return;
+ }
if (!this.disabled) {
this.visible = !this.visible;
if (this.remote && this.visible) {
@@ -472,7 +476,9 @@
},
selectOption() {
- this.handleOptionSelect(this.options[this.hoverIndex]);
+ if (this.options[this.hoverIndex]) {
+ this.handleOptionSelect(this.options[this.hoverIndex]);
+ }
},
deleteSelected(event) {
diff --git a/packages/tabs/src/tab-pane.vue b/packages/tabs/src/tab-pane.vue
index 888001f66..7f7cc5afc 100644
--- a/packages/tabs/src/tab-pane.vue
+++ b/packages/tabs/src/tab-pane.vue
@@ -7,9 +7,7 @@
type: String,
required: true
},
- key: {
- type: String
- }
+ name: String
},
data() {
@@ -18,7 +16,8 @@
transition: '',
paneStyle: {
position: 'relative'
- }
+ },
+ key: ''
};
},
@@ -28,17 +27,20 @@
}
},
- events: {
- },
-
computed: {
show() {
- return this.$parent.activeKey === this.key;
+ return this.$parent.currentName === this.key;
}
},
watch: {
- '$parent.activeKey'(newValue, oldValue) {
+ name: {
+ immediate: true,
+ handler(val) {
+ this.key = val;
+ }
+ },
+ '$parent.currentName'(newValue, oldValue) {
if (this.key === newValue) {
this.transition = newValue > oldValue ? 'slideInRight' : 'slideInLeft';
}
diff --git a/packages/tabs/src/tab.vue b/packages/tabs/src/tab.vue
index e1a66f45b..ea35ec505 100644
--- a/packages/tabs/src/tab.vue
+++ b/packages/tabs/src/tab.vue
@@ -8,20 +8,23 @@
required: true
},
closable: Boolean
- },
- data() {
- return {
- showClose: false
- };
}
};
- {{tab.label}}
+
+ {{tab.label}}
+
+
+
diff --git a/packages/tabs/src/tabs.vue b/packages/tabs/src/tabs.vue
index ab371f641..1e8b70588 100644
--- a/packages/tabs/src/tabs.vue
+++ b/packages/tabs/src/tabs.vue
@@ -11,12 +11,8 @@
props: {
type: String,
tabPosition: String,
- defaultActiveKey: {
- type: String
- },
- activeKey: {
- type: String
- },
+ defaultActiveName: String,
+ activeName: String,
closable: false,
tabWidth: 0
},
@@ -25,34 +21,22 @@
return {
tabs: [],
children: null,
- activeTab: null
+ activeTab: null,
+ currentName: 0,
+ barStyle: ''
};
},
- computed: {
- barStyle: {
- cache: false,
- get() {
- if (this.type) return {};
- var style = {};
- var offset = 0;
- var tabWidth = 0;
-
- this.tabs.every((tab, index) => {
- let $el = this.$refs.tabs[index].$el;
- if (tab.key !== this.activeKey) {
- offset += $el.clientWidth;
- return true;
- } else {
- tabWidth = $el.clientWidth;
- return false;
- }
- });
-
- style.width = tabWidth + 'px';
- style.transform = `translateX(${offset}px)`;
- return style;
+ watch: {
+ activeName: {
+ immediate: true,
+ handler(val) {
+ this.currentName = val || 0;
}
+ },
+
+ 'currentName'() {
+ this.calcBarStyle();
}
},
@@ -67,27 +51,49 @@
this.tabs.splice(index, 1);
}
- if (tab.key === this.activeKey) {
+ if (tab.key === this.currentName) {
let deleteIndex = this.$children.indexOf(tab);
let nextChild = this.$children[deleteIndex + 1];
let prevChild = this.$children[deleteIndex - 1];
- this.activeKey = nextChild ? nextChild.key : prevChild ? prevChild.key : '-1';
+ this.currentName = nextChild ? nextChild.key : prevChild ? prevChild.key : '-1';
}
this.$emit('tab.remove', tab);
},
handleTabClick(tab) {
- this.activeKey = tab.key;
+ this.currentName = tab.key;
this.$emit('tab.click', tab);
+ },
+ calcBarStyle() {
+ if (this.type) return {};
+ var style = {};
+ var offset = 0;
+ var tabWidth = 0;
+
+ this.tabs.every((tab, index) => {
+ let $el = this.$refs.tabs[index].$el;
+ if (tab.key !== this.currentName) {
+ offset += $el.clientWidth;
+ return true;
+ } else {
+ tabWidth = $el.clientWidth;
+ return false;
+ }
+ });
+
+ style.width = tabWidth + 'px';
+ style.transform = `translateX(${offset}px)`;
+
+ this.barStyle = style;
}
},
- ready() {
- if (!this.activeKey) {
- this.activeKey = this.defaultActiveKey || this.$children[0].key;
+
+ mounted() {
+ if (!this.currentName) {
+ this.currentName = this.defaultActiveName || this.$children[0].key;
}
- this.$children.forEach(tab => {
- this.tabs.push(tab);
- });
+ this.$children.forEach(tab => this.tabs.push(tab));
+ this.$nextTick(() => this.calcBarStyle());
}
};
@@ -97,13 +103,17 @@
diff --git a/packages/theme-default/src/index.css b/packages/theme-default/src/index.css
index f0900aa88..806a04761 100644
--- a/packages/theme-default/src/index.css
+++ b/packages/theme-default/src/index.css
@@ -15,6 +15,7 @@
@import "./popover.css";
@import "./tooltip.css";
@import "./autocomplete.css";
+@import "./message.css";
@import "./message-box.css";
@import "./date-picker.css";
@import "./time-picker.css";
diff --git a/packages/theme-default/src/message.css b/packages/theme-default/src/message.css
new file mode 100644
index 000000000..b7647011f
--- /dev/null
+++ b/packages/theme-default/src/message.css
@@ -0,0 +1,72 @@
+@charset "UTF-8";
+@import "./common/var.css";
+
+@component-namespace el {
+
+ @b message {
+ box-shadow:0 2px 4px 0 rgba(0, 0, 0, .12), 0 0 6px 0 rgba(0, 0, 0, .04);
+ width: 300px;
+ padding: 10px 12px;
+ box-sizing: border-box;
+ border-radius: 2px;
+ position: fixed;
+ left: 50%;
+ transform: translateX(-50%);
+ background-color: #fff;
+ transition: opacity 0.3s, top 0.4s;
+ overflow: hidden;
+ z-index: 1000;
+
+ @e group {
+ margin-left: 28px;
+ position: relative;
+
+ & p {
+ font-size: 14px;
+ line-height: 20px;
+ margin: 0 20px 0 0;
+ color: #8492a6;
+ text-align: justify;
+ }
+ }
+
+ @e icon {
+ size: 20px;
+ font-size: 20px;
+ float: left;
+ position: relative;
+ }
+
+ @e closeBtn {
+ position: absolute 3px 0 * *;
+ cursor: pointer;
+ color: #C0CCDA;
+ font-size: 14px;
+
+ &:hover {
+ color: #99A9BF;
+ }
+ }
+
+ & .el-icon-circle-check {
+ color: #13ce66;
+ }
+
+ & .el-icon-circle-cross {
+ color: #ff4949;
+ }
+
+ & .el-icon-information {
+ color: #50bfff;
+ }
+
+ & .el-icon-warning {
+ color: #f7ba2a;
+ }
+ }
+
+ .el-message-fade-enter,
+ .el-message-fade-leave-active {
+ opacity: 0;
+ }
+}
diff --git a/packages/tree/src/tree-node.vue b/packages/tree/src/tree-node.vue
index 4041002f2..7e11f8cab 100644
--- a/packages/tree/src/tree-node.vue
+++ b/packages/tree/src/tree-node.vue
@@ -6,7 +6,7 @@
-
+
{{ node.label }}
diff --git a/src/index.js b/src/index.js
index 878bd4d9f..fb956bc4f 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,4 +1,3 @@
-import Group from '../packages/group/index.js';
import SelectDropdown from '../packages/select-dropdown/index.js';
import Pagination from '../packages/pagination/index.js';
import Dialog from '../packages/dialog/index.js';
@@ -48,11 +47,11 @@ import Col from '../packages/col/index.js';
import Upload from '../packages/upload/index.js';
import Progress from '../packages/progress/index.js';
import Spinner from '../packages/spinner/index.js';
+import Message from '../packages/message/index.js';
const install = function(Vue) {
if (install.installed) return;
- Vue.component(Group.name, Group);
Vue.component(SelectDropdown.name, SelectDropdown);
Vue.component(Pagination.name, Pagination);
Vue.component(Dialog.name, Dialog);
@@ -99,6 +98,7 @@ const install = function(Vue) {
Vue.component(Upload.name, Upload);
Vue.component(Progress.name, Progress);
Vue.component(Spinner.name, Spinner);
+ Vue.component(Message.name, Message);
Vue.use(Loading);
@@ -107,6 +107,7 @@ const install = function(Vue) {
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
Vue.prototype.$notify = Notification;
+ Vue.prototype.$message = Message;
};
// auto install
@@ -116,7 +117,6 @@ if (typeof window !== 'undefined' && window.Vue) {
module.exports = {
install,
- Group,
SelectDropdown,
Pagination,
Dialog,
@@ -165,5 +165,6 @@ module.exports = {
Col,
Upload,
Progress,
- Spinner
+ Spinner,
+ Message
};