diff --git a/examples/routers/form.vue b/examples/routers/form.vue
index d494cf3e..b4b3a82e 100644
--- a/examples/routers/form.vue
+++ b/examples/routers/form.vue
@@ -2,12 +2,7 @@
-
-
-
-
-
-
+
提交
@@ -21,12 +16,15 @@
data () {
return {
formValidate: {
- interest: ['吃饭', '跑步']
+ interest: ''
},
ruleValidate: {
interest: [
- { required: true, type: 'array', min: 1, message: '至少选择一个爱好', trigger: 'change' },
- { type: 'array', max: 2, message: '最多选择两个爱好', trigger: 'change' }
+ {
+ required: true,
+ type: 'number',
+ trigger: 'change'
+ }
]
}
}
diff --git a/examples/routers/menu.vue b/examples/routers/menu.vue
index 3d2f8251..8190a9e6 100644
--- a/examples/routers/menu.vue
+++ b/examples/routers/menu.vue
@@ -1,44 +1,48 @@
-
+
+
新增用户
+
活跃用户
+
+
+
+
+ 统计分析
+
+
+ 新增和启动
+ 活跃分析
+ 时段分析
+
+
+ 用户留存
+ 流失用户
+
+
+
+
+
切换主题
-
+
-
@@ -46,149 +50,8 @@
export default {
data () {
return {
- theme1: 'light'
- }
- },
- methods: {
- s (s) {
- console.log(s)
+ theme2: 'light'
}
}
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/base/collapse-transition.js b/src/components/base/collapse-transition.js
new file mode 100644
index 00000000..4c3c43dc
--- /dev/null
+++ b/src/components/base/collapse-transition.js
@@ -0,0 +1,79 @@
+// Thanks to https://github.com/ElemeFE/element/blob/dev/src/transitions/collapse-transition.js
+
+import { addClass, removeClass } from '../../utils/assist';
+
+const Transition = {
+ beforeEnter(el) {
+ addClass(el, 'collapse-transition');
+ if (!el.dataset) el.dataset = {};
+
+ el.dataset.oldPaddingTop = el.style.paddingTop;
+ el.dataset.oldPaddingBottom = el.style.paddingBottom;
+
+ el.style.height = '0';
+ el.style.paddingTop = 0;
+ el.style.paddingBottom = 0;
+ },
+
+ enter(el) {
+ el.dataset.oldOverflow = el.style.overflow;
+ if (el.scrollHeight !== 0) {
+ el.style.height = el.scrollHeight + 'px';
+ el.style.paddingTop = el.dataset.oldPaddingTop;
+ el.style.paddingBottom = el.dataset.oldPaddingBottom;
+ } else {
+ el.style.height = '';
+ el.style.paddingTop = el.dataset.oldPaddingTop;
+ el.style.paddingBottom = el.dataset.oldPaddingBottom;
+ }
+
+ el.style.overflow = 'hidden';
+ },
+
+ afterEnter(el) {
+ // for safari: remove class then reset height is necessary
+ removeClass(el, 'collapse-transition');
+ el.style.height = '';
+ el.style.overflow = el.dataset.oldOverflow;
+ },
+
+ beforeLeave(el) {
+ if (!el.dataset) el.dataset = {};
+ el.dataset.oldPaddingTop = el.style.paddingTop;
+ el.dataset.oldPaddingBottom = el.style.paddingBottom;
+ el.dataset.oldOverflow = el.style.overflow;
+
+ el.style.height = el.scrollHeight + 'px';
+ el.style.overflow = 'hidden';
+ },
+
+ leave(el) {
+ if (el.scrollHeight !== 0) {
+ // for safari: add class after set height, or it will jump to zero height suddenly, weired
+ addClass(el, 'collapse-transition');
+ el.style.height = 0;
+ el.style.paddingTop = 0;
+ el.style.paddingBottom = 0;
+ }
+ },
+
+ afterLeave(el) {
+ removeClass(el, 'collapse-transition');
+ el.style.height = '';
+ el.style.overflow = el.dataset.oldOverflow;
+ el.style.paddingTop = el.dataset.oldPaddingTop;
+ el.style.paddingBottom = el.dataset.oldPaddingBottom;
+ }
+};
+
+export default {
+ name: 'CollapseTransition',
+ functional: true,
+ render(h, { children }) {
+ const data = {
+ on: Transition
+ };
+
+ return h('transition', data, children);
+ }
+};
diff --git a/src/components/menu/submenu.vue b/src/components/menu/submenu.vue
index b0cba7db..1fcdc55b 100644
--- a/src/components/menu/submenu.vue
+++ b/src/components/menu/submenu.vue
@@ -4,7 +4,9 @@
-
+
+
+
import Drop from '../select/dropdown.vue';
import Icon from '../icon/icon.vue';
+ import CollapseTransition from '../base/collapse-transition';
import { getStyle, findComponentUpward } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
@@ -25,7 +28,7 @@
export default {
name: 'Submenu',
mixins: [ Emitter ],
- components: { Icon, Drop },
+ components: { Icon, Drop, CollapseTransition },
props: {
name: {
type: [String, Number],
diff --git a/src/styles/animation/index.less b/src/styles/animation/index.less
index 66033203..116f9b69 100644
--- a/src/styles/animation/index.less
+++ b/src/styles/animation/index.less
@@ -25,4 +25,8 @@
@import "fade";
@import "move";
@import "ease";
-@import "slide";
\ No newline at end of file
+@import "slide";
+
+.collapse-transition {
+ transition: @transition-time height ease-in-out, @transition-time padding-top ease-in-out, @transition-time padding-bottom ease-in-out;
+}
\ No newline at end of file
diff --git a/src/utils/assist.js b/src/utils/assist.js
index daabffd7..71ece1cf 100644
--- a/src/utils/assist.js
+++ b/src/utils/assist.js
@@ -232,4 +232,66 @@ function findComponentsDownward (context, componentName, components = []) {
}
return components;
}
-export {findComponentsDownward};
\ No newline at end of file
+export {findComponentsDownward};
+
+/* istanbul ignore next */
+const trim = function(string) {
+ return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '');
+};
+
+/* istanbul ignore next */
+export function hasClass(el, cls) {
+ if (!el || !cls) return false;
+ if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
+ if (el.classList) {
+ return el.classList.contains(cls);
+ } else {
+ return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
+ }
+}
+
+/* istanbul ignore next */
+export function addClass(el, cls) {
+ if (!el) return;
+ let curClass = el.className;
+ const classes = (cls || '').split(' ');
+
+ for (let i = 0, j = classes.length; i < j; i++) {
+ const clsName = classes[i];
+ if (!clsName) continue;
+
+ if (el.classList) {
+ el.classList.add(clsName);
+ } else {
+ if (!hasClass(el, clsName)) {
+ curClass += ' ' + clsName;
+ }
+ }
+ }
+ if (!el.classList) {
+ el.className = curClass;
+ }
+}
+
+/* istanbul ignore next */
+export function removeClass(el, cls) {
+ if (!el || !cls) return;
+ const classes = cls.split(' ');
+ let curClass = ' ' + el.className + ' ';
+
+ for (let i = 0, j = classes.length; i < j; i++) {
+ const clsName = classes[i];
+ if (!clsName) continue;
+
+ if (el.classList) {
+ el.classList.remove(clsName);
+ } else {
+ if (hasClass(el, clsName)) {
+ curClass = curClass.replace(' ' + clsName + ' ', ' ');
+ }
+ }
+ }
+ if (!el.classList) {
+ el.className = trim(curClass);
+ }
+}
\ No newline at end of file