Menu support transition fixed #514

This commit is contained in:
Aresn 2017-06-02 14:23:34 +08:00
parent 75c32564f0
commit 841cb1fe67
6 changed files with 195 additions and 186 deletions

View file

@ -2,12 +2,7 @@
<div style="width: 300px;">
<i-form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
<Form-item label="爱好" prop="interest">
<Checkbox-group v-model="formValidate.interest">
<Checkbox label="吃饭"></Checkbox>
<Checkbox label="睡觉"></Checkbox>
<Checkbox label="跑步"></Checkbox>
<Checkbox label="看电影"></Checkbox>
</Checkbox-group>
<Input v-model="formValidate.interest" number></Input>
</Form-item>
<Form-item>
<i-button type="primary" @click="handleSubmit('formValidate')">提交</i-button>
@ -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'
}
]
}
}

View file

@ -1,16 +1,25 @@
<template>
<div>
<Menu mode="horizontal" :theme="theme1" @on-select="s">
<Row type="flex" justify="center" align="middle">
<i-col span="12">
<Menu-item name="1">
<Row>
<i-col span="8">
<Menu :theme="theme2">
<Submenu name="1">
<template slot="title">
<Icon type="ios-paper"></Icon>
内容管理
</Menu-item>
<Menu-item name="2">
</template>
<Menu-item name="1-1">文章管理</Menu-item>
<Menu-item name="1-2">评论管理</Menu-item>
<Menu-item name="1-3">举报管理</Menu-item>
</Submenu>
<Submenu name="2">
<template slot="title">
<Icon type="ios-people"></Icon>
用户管理
</Menu-item>
</template>
<Menu-item name="2-1">新增用户</Menu-item>
<Menu-item name="2-2">活跃用户</Menu-item>
</Submenu>
<Submenu name="3">
<template slot="title">
<Icon type="stats-bars"></Icon>
@ -26,19 +35,14 @@
<Menu-item name="3-5">流失用户</Menu-item>
</Menu-group>
</Submenu>
<Menu-item name="4">
<Icon type="settings"></Icon>
综合设置
</Menu-item>
</Menu>
</i-col>
</Row>
</Menu>
<br>
<p>切换主题</p>
<Radio-group v-model="theme1">
<Radio-group v-model="theme2">
<Radio label="light"></Radio>
<Radio label="dark"></Radio>
<Radio label="primary"></Radio>
</Radio-group>
</div>
</template>
@ -46,149 +50,8 @@
export default {
data () {
return {
theme1: 'light'
}
},
methods: {
s (s) {
console.log(s)
theme2: 'light'
}
}
}
</script>
<!--<template>-->
<!--<div>-->
<!--<Row>-->
<!--<i-col span="8">-->
<!--<Menu :theme="theme2" @on-select="s">-->
<!--<Submenu name="1">-->
<!--<template slot="title">-->
<!--<Icon type="ios-paper"></Icon>-->
<!--内容管理-->
<!--</template>-->
<!--<Menu-item name="1-1">文章管理</Menu-item>-->
<!--<Menu-item name="1-2">评论管理</Menu-item>-->
<!--<Menu-item name="1-3">举报管理</Menu-item>-->
<!--</Submenu>-->
<!--<Submenu name="2">-->
<!--<template slot="title">-->
<!--<Icon type="ios-people"></Icon>-->
<!--用户管理-->
<!--</template>-->
<!--<Menu-item name="2-1">新增用户</Menu-item>-->
<!--<Menu-item name="2-2">活跃用户</Menu-item>-->
<!--</Submenu>-->
<!--<Submenu name="3">-->
<!--<template slot="title">-->
<!--<Icon type="stats-bars"></Icon>-->
<!--统计分析-->
<!--</template>-->
<!--<Menu-group title="使用">-->
<!--<Menu-item name="3-1">新增和启动</Menu-item>-->
<!--<Menu-item name="3-2">活跃分析</Menu-item>-->
<!--<Menu-item name="3-3">时段分析</Menu-item>-->
<!--</Menu-group>-->
<!--<Menu-group title="留存">-->
<!--<Menu-item name="3-4">用户留存</Menu-item>-->
<!--<Menu-item name="3-5">流失用户</Menu-item>-->
<!--</Menu-group>-->
<!--</Submenu>-->
<!--</Menu>-->
<!--</i-col>-->
<!--<i-col span="8">-->
<!--<Menu :theme="theme2" active-name="1-2" :open-names="['1']" @on-select="s">-->
<!--<Submenu name="1">-->
<!--<template slot="title">-->
<!--<Icon type="ios-paper"></Icon>-->
<!--内容管理-->
<!--</template>-->
<!--<Menu-item name="1-1">文章管理</Menu-item>-->
<!--<Menu-item name="1-2">评论管理</Menu-item>-->
<!--<Menu-item name="1-3">举报管理</Menu-item>-->
<!--</Submenu>-->
<!--<Submenu name="2">-->
<!--<template slot="title">-->
<!--<Icon type="ios-people"></Icon>-->
<!--用户管理-->
<!--</template>-->
<!--<Menu-item name="2-1">新增用户</Menu-item>-->
<!--<Menu-item name="2-2">活跃用户</Menu-item>-->
<!--</Submenu>-->
<!--<Submenu name="3">-->
<!--<template slot="title">-->
<!--<Icon type="stats-bars"></Icon>-->
<!--统计分析-->
<!--</template>-->
<!--<Menu-group title="使用">-->
<!--<Menu-item name="3-1">新增和启动</Menu-item>-->
<!--<Menu-item name="3-2">活跃分析</Menu-item>-->
<!--<Menu-item name="3-3">时段分析</Menu-item>-->
<!--</Menu-group>-->
<!--<Menu-group title="留存">-->
<!--<Menu-item name="3-4">用户留存</Menu-item>-->
<!--<Menu-item name="3-5">流失用户</Menu-item>-->
<!--</Menu-group>-->
<!--</Submenu>-->
<!--</Menu>-->
<!--</i-col>-->
<!--<i-col span="8">-->
<!--<Menu :theme="theme2" :open-names="['1']" accordion @on-select="s">-->
<!--<Submenu name="1">-->
<!--<template slot="title">-->
<!--<Icon type="ios-paper"></Icon>-->
<!--内容管理-->
<!--</template>-->
<!--<Menu-item name="1-1">文章管理</Menu-item>-->
<!--<Menu-item name="1-2">评论管理</Menu-item>-->
<!--<Menu-item name="1-3">举报管理</Menu-item>-->
<!--</Submenu>-->
<!--<Submenu name="2">-->
<!--<template slot="title">-->
<!--<Icon type="ios-people"></Icon>-->
<!--用户管理-->
<!--</template>-->
<!--<Menu-item name="2-1">新增用户</Menu-item>-->
<!--<Menu-item name="2-2">活跃用户</Menu-item>-->
<!--</Submenu>-->
<!--<Submenu name="3">-->
<!--<template slot="title">-->
<!--<Icon type="stats-bars"></Icon>-->
<!--统计分析-->
<!--</template>-->
<!--<Menu-group title="使用">-->
<!--<Menu-item name="3-1">新增和启动</Menu-item>-->
<!--<Menu-item name="3-2">活跃分析</Menu-item>-->
<!--<Menu-item name="3-3">时段分析</Menu-item>-->
<!--</Menu-group>-->
<!--<Menu-group title="留存">-->
<!--<Menu-item name="3-4">用户留存</Menu-item>-->
<!--<Menu-item name="3-5">流失用户</Menu-item>-->
<!--</Menu-group>-->
<!--</Submenu>-->
<!--</Menu>-->
<!--</i-col>-->
<!--</Row>-->
<!--<br>-->
<!--<p>切换主题</p>-->
<!--<Radio-group v-model="theme2">-->
<!--<Radio label="light"></Radio>-->
<!--<Radio label="dark"></Radio>-->
<!--</Radio-group>-->
<!--</div>-->
<!--</template>-->
<!--<script>-->
<!--export default {-->
<!--data () {-->
<!--return {-->
<!--theme2: 'light'-->
<!--}-->
<!--},-->
<!--methods: {-->
<!--s (s) {-->
<!--console.log(s);-->
<!--}-->
<!--}-->
<!--}-->
<!--</script>-->

View file

@ -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);
}
};

View file

@ -4,7 +4,9 @@
<slot name="title"></slot>
<Icon type="ios-arrow-down" :class="[prefixCls + '-submenu-title-icon']"></Icon>
</div>
<ul :class="[prefixCls]" v-if="mode === 'vertical'" v-show="opened"><slot></slot></ul>
<collapse-transition v-if="mode === 'vertical'">
<ul :class="[prefixCls]" v-show="opened"><slot></slot></ul>
</collapse-transition>
<transition name="slide-up" v-else>
<Drop
v-show="opened"
@ -17,6 +19,7 @@
<script>
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],

View file

@ -26,3 +26,7 @@
@import "move";
@import "ease";
@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;
}

View file

@ -233,3 +233,65 @@ function findComponentsDownward (context, componentName, components = []) {
return components;
}
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);
}
}