Commit 0acdae198342cd9da1006896b5068b684346ec8b
1 parent
e05d7289
update Menu
update Menu
Showing
5 changed files
with
157 additions
and
31 deletions
Show diff stats
src/components/menu/menu-item.vue
src/components/menu/menu.vue
| @@ -73,6 +73,10 @@ | @@ -73,6 +73,10 @@ | ||
| 73 | } | 73 | } |
| 74 | } | 74 | } |
| 75 | }) | 75 | }) |
| 76 | + } else if (item.$options.name === 'MenuGroup') { | ||
| 77 | + item.$children.forEach(groupItem => { | ||
| 78 | + groupItem.active = groupItem.key === this.activeKey; | ||
| 79 | + }) | ||
| 76 | } else { | 80 | } else { |
| 77 | item.active = item.key === this.activeKey; | 81 | item.active = item.key === this.activeKey; |
| 78 | } | 82 | } |
src/components/menu/submenu.vue
| 1 | <template> | 1 | <template> |
| 2 | <li :class="classes" @mouseenter="handleMouseenter" @mouseleave="handleMouseleave"> | 2 | <li :class="classes" @mouseenter="handleMouseenter" @mouseleave="handleMouseleave"> |
| 3 | - <div :class="[prefixCls + '-title']" v-el:reference> | ||
| 4 | - <span><slot name="title"></slot></span> | ||
| 5 | - <Icon type="ios-arrow-down"></Icon> | 3 | + <div :class="[prefixCls + '-submenu-title']" v-el:reference @click="handleClick"> |
| 4 | + <slot name="title"></slot> | ||
| 5 | + <Icon type="ios-arrow-down" :class="[prefixCls + '-submenu-title-icon']"></Icon> | ||
| 6 | </div> | 6 | </div> |
| 7 | - <ul :class="[prefixCls]" v-if="mode === 'vertical'"></ul> | 7 | + <ul :class="[prefixCls]" v-if="mode === 'vertical'" v-show="opened"><slot></slot></ul> |
| 8 | <Drop v-else v-show="opened" placement="bottom" transition="slide-up" v-ref:drop><slot></slot></Drop> | 8 | <Drop v-else v-show="opened" placement="bottom" transition="slide-up" v-ref:drop><slot></slot></Drop> |
| 9 | </li> | 9 | </li> |
| 10 | </template> | 10 | </template> |
| @@ -20,6 +20,10 @@ | @@ -20,6 +20,10 @@ | ||
| 20 | key: { | 20 | key: { |
| 21 | type: [String, Number], | 21 | type: [String, Number], |
| 22 | required: true | 22 | required: true |
| 23 | + }, | ||
| 24 | + disabled: { | ||
| 25 | + type: Boolean, | ||
| 26 | + default: false | ||
| 23 | } | 27 | } |
| 24 | }, | 28 | }, |
| 25 | data () { | 29 | data () { |
| @@ -35,28 +39,47 @@ | @@ -35,28 +39,47 @@ | ||
| 35 | `${prefixCls}-submenu`, | 39 | `${prefixCls}-submenu`, |
| 36 | { | 40 | { |
| 37 | [`${prefixCls}-item-active`]: this.active, | 41 | [`${prefixCls}-item-active`]: this.active, |
| 38 | - [`${prefixCls}-opened`]: this.opened | 42 | + [`${prefixCls}-opened`]: this.opened, |
| 43 | + [`${prefixCls}-submenu-disabled`]: this.disabled | ||
| 39 | } | 44 | } |
| 40 | ] | 45 | ] |
| 41 | }, | 46 | }, |
| 42 | mode () { | 47 | mode () { |
| 43 | return this.$parent.mode; | 48 | return this.$parent.mode; |
| 49 | + }, | ||
| 50 | + accordion () { | ||
| 51 | + return this.$parent.accordion; | ||
| 44 | } | 52 | } |
| 45 | }, | 53 | }, |
| 46 | methods: { | 54 | methods: { |
| 47 | handleMouseenter () { | 55 | handleMouseenter () { |
| 56 | + if (this.disabled) return; | ||
| 48 | if (this.mode === 'vertical') return; | 57 | if (this.mode === 'vertical') return; |
| 58 | + | ||
| 49 | clearTimeout(this.timeout); | 59 | clearTimeout(this.timeout); |
| 50 | this.timeout = setTimeout(() => { | 60 | this.timeout = setTimeout(() => { |
| 51 | this.opened = true; | 61 | this.opened = true; |
| 52 | }, 250); | 62 | }, 250); |
| 53 | }, | 63 | }, |
| 54 | handleMouseleave () { | 64 | handleMouseleave () { |
| 65 | + if (this.disabled) return; | ||
| 55 | if (this.mode === 'vertical') return; | 66 | if (this.mode === 'vertical') return; |
| 67 | + | ||
| 56 | clearTimeout(this.timeout); | 68 | clearTimeout(this.timeout); |
| 57 | this.timeout = setTimeout(() => { | 69 | this.timeout = setTimeout(() => { |
| 58 | this.opened = false; | 70 | this.opened = false; |
| 59 | }, 150); | 71 | }, 150); |
| 72 | + }, | ||
| 73 | + handleClick () { | ||
| 74 | + if (this.disabled) return; | ||
| 75 | + if (this.mode === 'horizontal') return; | ||
| 76 | + const opened = this.opened; | ||
| 77 | + if (this.accordion) { | ||
| 78 | + this.$parent.$children.forEach(item => { | ||
| 79 | + if (item.$options.name === 'Submenu') item.opened = false; | ||
| 80 | + }); | ||
| 81 | + } | ||
| 82 | + this.opened = !opened; | ||
| 60 | } | 83 | } |
| 61 | }, | 84 | }, |
| 62 | watch: { | 85 | watch: { |
src/styles/components/menu.less
| @@ -41,6 +41,7 @@ | @@ -41,6 +41,7 @@ | ||
| 41 | top: 0; | 41 | top: 0; |
| 42 | bottom: 0; | 42 | bottom: 0; |
| 43 | right: 0; | 43 | right: 0; |
| 44 | + z-index: 1; | ||
| 44 | } | 45 | } |
| 45 | } | 46 | } |
| 46 | } | 47 | } |
| @@ -64,23 +65,14 @@ | @@ -64,23 +65,14 @@ | ||
| 64 | z-index: 1; | 65 | z-index: 1; |
| 65 | cursor: pointer; | 66 | cursor: pointer; |
| 66 | transition: all @transition-time @ease-in-out; | 67 | transition: all @transition-time @ease-in-out; |
| 67 | - | ||
| 68 | - .@{menu-prefix-cls}-light &{ | ||
| 69 | - color: @text-color; | ||
| 70 | - } | ||
| 71 | - .@{menu-prefix-cls}-dark &{ | ||
| 72 | - color: @subsidiary-color; | ||
| 73 | - &-active, &:hover{ | ||
| 74 | - color: #fff; | ||
| 75 | - } | ||
| 76 | - } | ||
| 77 | - .@{menu-prefix-cls}-primary &{ | ||
| 78 | - color: #fff; | ||
| 79 | - &-active, &:hover{ | ||
| 80 | - background: @link-active-color; | ||
| 81 | - } | ||
| 82 | - } | ||
| 83 | } | 68 | } |
| 69 | + &-item > i{ | ||
| 70 | + margin-right: 6px; | ||
| 71 | + } | ||
| 72 | + &-submenu-title > i, &-submenu-title span > i{ | ||
| 73 | + margin-right: 8px; | ||
| 74 | + } | ||
| 75 | + | ||
| 84 | &-horizontal &-item, | 76 | &-horizontal &-item, |
| 85 | &-horizontal &-submenu | 77 | &-horizontal &-submenu |
| 86 | { | 78 | { |
| @@ -88,7 +80,7 @@ | @@ -88,7 +80,7 @@ | ||
| 88 | padding: 0 20px; | 80 | padding: 0 20px; |
| 89 | position: relative; | 81 | position: relative; |
| 90 | cursor: pointer; | 82 | cursor: pointer; |
| 91 | - z-index: 1; | 83 | + z-index: 3; |
| 92 | transition: all @transition-time @ease-in-out; | 84 | transition: all @transition-time @ease-in-out; |
| 93 | } | 85 | } |
| 94 | 86 | ||
| @@ -96,19 +88,22 @@ | @@ -96,19 +88,22 @@ | ||
| 96 | height: inherit; | 88 | height: inherit; |
| 97 | line-height: inherit; | 89 | line-height: inherit; |
| 98 | border-bottom: 2px solid transparent; | 90 | border-bottom: 2px solid transparent; |
| 91 | + color: @text-color; | ||
| 99 | &-active, &:hover{ | 92 | &-active, &:hover{ |
| 100 | color: @primary-color; | 93 | color: @primary-color; |
| 101 | border-bottom: 2px solid @primary-color; | 94 | border-bottom: 2px solid @primary-color; |
| 102 | } | 95 | } |
| 103 | } | 96 | } |
| 104 | 97 | ||
| 105 | - &-dark&-horizontal &-item{ | 98 | + &-dark&-horizontal &-item, &-dark&-horizontal &-submenu{ |
| 99 | + color: @subsidiary-color; | ||
| 106 | &-active, &:hover{ | 100 | &-active, &:hover{ |
| 107 | color: #fff; | 101 | color: #fff; |
| 108 | } | 102 | } |
| 109 | } | 103 | } |
| 110 | 104 | ||
| 111 | - &-primary&-horizontal &-item{ | 105 | + &-primary&-horizontal &-item, &-primary&-horizontal &-submenu{ |
| 106 | + color: #fff; | ||
| 112 | &-active, &:hover{ | 107 | &-active, &:hover{ |
| 113 | background: @link-active-color; | 108 | background: @link-active-color; |
| 114 | } | 109 | } |
| @@ -128,11 +123,57 @@ | @@ -128,11 +123,57 @@ | ||
| 128 | line-height: normal; | 123 | line-height: normal; |
| 129 | &-title { | 124 | &-title { |
| 130 | padding-left: 8px; | 125 | padding-left: 8px; |
| 131 | - font-size: 12px; | 126 | + font-size: @font-size-small; |
| 132 | color: @legend-color; | 127 | color: @legend-color; |
| 133 | height: 30px; | 128 | height: 30px; |
| 134 | line-height: 30px; | 129 | line-height: 30px; |
| 135 | } | 130 | } |
| 136 | } | 131 | } |
| 132 | + | ||
| 133 | + // vertical | ||
| 134 | + &-vertical &-item, | ||
| 135 | + &-vertical &-submenu-title | ||
| 136 | + { | ||
| 137 | + padding: 14px 24px; | ||
| 138 | + position: relative; | ||
| 139 | + cursor: pointer; | ||
| 140 | + z-index: 1; | ||
| 141 | + transition: all @transition-time @ease-in-out; | ||
| 142 | + | ||
| 143 | + &:hover{ | ||
| 144 | + background: @background-color-select-hover; | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + &-vertical &-submenu-title-icon{ | ||
| 149 | + float: right; | ||
| 150 | + position: relative; | ||
| 151 | + top: 4px; | ||
| 152 | + } | ||
| 153 | + &-submenu-title-icon { | ||
| 154 | + transition: transform @transition-time @ease-in-out; | ||
| 155 | + } | ||
| 156 | + &-opened &-submenu-title-icon{ | ||
| 157 | + transform: rotate(180deg); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + &-vertical &-submenu &-item{ | ||
| 161 | + padding-left: 43px; | ||
| 162 | + } | ||
| 163 | + &-vertical &-item-group{ | ||
| 164 | + &-title{ | ||
| 165 | + font-size: @font-size-base; | ||
| 166 | + padding-left: 28px; | ||
| 167 | + } | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + &-light&-vertical &-item{ | ||
| 171 | + border-right: 2px solid transparent; | ||
| 172 | + &-active:not(.@{menu-prefix-cls}-submenu){ | ||
| 173 | + color: @primary-color; | ||
| 174 | + border-right: 2px solid @primary-color; | ||
| 175 | + z-index: 2; | ||
| 176 | + } | ||
| 177 | + } | ||
| 137 | } | 178 | } |
| 138 | .select-item(@menu-prefix-cls, @menu-dropdown-item-prefix-cls); | 179 | .select-item(@menu-prefix-cls, @menu-dropdown-item-prefix-cls); |
| 139 | \ No newline at end of file | 180 | \ No newline at end of file |
test/routers/menu.vue
| 1 | <template> | 1 | <template> |
| 2 | <div> | 2 | <div> |
| 3 | - <i-button @click="toggleMode">调整方向</i-button> | ||
| 4 | - <Menu :mode="mode" active-key="1"> | 3 | + <Menu mode="horizontal" active-key="1"> |
| 5 | <Menu-item key="1"> | 4 | <Menu-item key="1"> |
| 6 | - <Icon type="ionic"></Icon> | ||
| 7 | - <span>导航一</span> | 5 | + <Icon type="ionic"></Icon><span>导航一</span> |
| 8 | </Menu-item> | 6 | </Menu-item> |
| 9 | <Menu-item key="2">导航二</Menu-item> | 7 | <Menu-item key="2">导航二</Menu-item> |
| 10 | <Submenu key="3"> | 8 | <Submenu key="3"> |
| 11 | - <span slot="title">导航三</span> | 9 | + <template slot="title"><Icon type="ionic"></Icon>导航三</template> |
| 12 | <Menu-group title="集合1"> | 10 | <Menu-group title="集合1"> |
| 13 | <Menu-item key="3-1">导航三 - 一</Menu-item> | 11 | <Menu-item key="3-1">导航三 - 一</Menu-item> |
| 14 | <Menu-item key="3-2">导航三 - 二</Menu-item> | 12 | <Menu-item key="3-2">导航三 - 二</Menu-item> |
| @@ -21,6 +19,65 @@ | @@ -21,6 +19,65 @@ | ||
| 21 | <Menu-item key="4">导航四</Menu-item> | 19 | <Menu-item key="4">导航四</Menu-item> |
| 22 | </Menu> | 20 | </Menu> |
| 23 | <br><br> | 21 | <br><br> |
| 22 | + <Menu :mode="mode" active-key="1" accordion> | ||
| 23 | + <Menu-item key="1"> | ||
| 24 | + <Icon type="ionic"></Icon> | ||
| 25 | + <span>导航一</span> | ||
| 26 | + </Menu-item> | ||
| 27 | + <Menu-group title="集合1"> | ||
| 28 | + <Menu-item key="2"> | ||
| 29 | + <Icon type="ionic"></Icon> | ||
| 30 | + 导航二 | ||
| 31 | + </Menu-item> | ||
| 32 | + <Menu-item key="3">导航三</Menu-item> | ||
| 33 | + </Menu-group> | ||
| 34 | + <Menu-group title="集合2"> | ||
| 35 | + <Menu-item key="4">导航四</Menu-item> | ||
| 36 | + <Menu-item key="5">导航五</Menu-item> | ||
| 37 | + </Menu-group> | ||
| 38 | + <Submenu key="6"> | ||
| 39 | + <template slot="title"><Icon type="ionic"></Icon>导航六</template> | ||
| 40 | + <Menu-group title="集合1"> | ||
| 41 | + <Menu-item key="3-1">导航三 - 一</Menu-item> | ||
| 42 | + <Menu-item key="3-2">导航三 - 二</Menu-item> | ||
| 43 | + </Menu-group> | ||
| 44 | + <Menu-group title="集合2"> | ||
| 45 | + <Menu-item key="3-3">导航三 - 三</Menu-item> | ||
| 46 | + <Menu-item key="3-4">导航三 - 四</Menu-item> | ||
| 47 | + </Menu-group> | ||
| 48 | + </Submenu> | ||
| 49 | + <Submenu key="7"> | ||
| 50 | + <template slot="title"><Icon type="ionic"></Icon>导航七</template> | ||
| 51 | + <Menu-group title="集合1"> | ||
| 52 | + <Menu-item key="7-1">导航三 - 一</Menu-item> | ||
| 53 | + <Menu-item key="7-2">导航三 - 二</Menu-item> | ||
| 54 | + </Menu-group> | ||
| 55 | + <Menu-group title="集合2"> | ||
| 56 | + <Menu-item key="7-3">导航三 - 三</Menu-item> | ||
| 57 | + <Menu-item key="7-4">导航三 - 四</Menu-item> | ||
| 58 | + </Menu-group> | ||
| 59 | + </Submenu> | ||
| 60 | + </Menu> | ||
| 61 | + <!--<Menu :mode="mode" active-key="1">--> | ||
| 62 | + <!--<Menu-item key="1">--> | ||
| 63 | + <!--<Icon type="ionic"></Icon>--> | ||
| 64 | + <!--<span>导航一</span>--> | ||
| 65 | + <!--</Menu-item>--> | ||
| 66 | + <!--<Menu-item key="2">导航二</Menu-item>--> | ||
| 67 | + <!--<Submenu key="3">--> | ||
| 68 | + <!--<template slot="title"><Icon type="ionic"></Icon><span>导航三</span></template>--> | ||
| 69 | + <!--<Menu-group title="集合1">--> | ||
| 70 | + <!--<Menu-item key="3-1">导航三 - 一</Menu-item>--> | ||
| 71 | + <!--<Menu-item key="3-2">导航三 - 二</Menu-item>--> | ||
| 72 | + <!--</Menu-group>--> | ||
| 73 | + <!--<Menu-group title="集合2">--> | ||
| 74 | + <!--<Menu-item key="3-3">导航三 - 三</Menu-item>--> | ||
| 75 | + <!--<Menu-item key="3-4">导航三 - 四</Menu-item>--> | ||
| 76 | + <!--</Menu-group>--> | ||
| 77 | + <!--</Submenu>--> | ||
| 78 | + <!--<Menu-item key="4">导航四</Menu-item>--> | ||
| 79 | + <!--</Menu>--> | ||
| 80 | + <!--<br><br>--> | ||
| 24 | <!--<Menu mode="horizontal" theme="dark" active-key="1">--> | 81 | <!--<Menu mode="horizontal" theme="dark" active-key="1">--> |
| 25 | <!--<Menu-item key="1">--> | 82 | <!--<Menu-item key="1">--> |
| 26 | <!--<Icon type="ionic"></Icon>--> | 83 | <!--<Icon type="ionic"></Icon>--> |
| @@ -57,7 +114,7 @@ | @@ -57,7 +114,7 @@ | ||
| 57 | props: {}, | 114 | props: {}, |
| 58 | data () { | 115 | data () { |
| 59 | return { | 116 | return { |
| 60 | - mode: 'horizontal' | 117 | + mode: 'vertical' |
| 61 | } | 118 | } |
| 62 | }, | 119 | }, |
| 63 | computed: {}, | 120 | computed: {}, |