|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 771 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 662 B |
|
After Width: | Height: | Size: 49 KiB |
@ -0,0 +1,287 @@ |
|||||
|
|
||||
|
<template> |
||||
|
<transition :name="customize ? '' : 'menu-collapse'"> |
||||
|
<el-menu v-if="!customize" class="el-menu-vertical-demo custom-menu" @open="handleOpen" |
||||
|
:default-active="currentMenuItem?.index" |
||||
|
@close="handleClose" @select="handleSelect" :collapse="isCollapse" :collapse-transition="true" |
||||
|
> |
||||
|
<div style="height: 100%;padding: 0 0 20px;box-sizing: border-box;"> |
||||
|
<div class="menu-top"> |
||||
|
<span v-show="!isCollapse"> |
||||
|
导航 |
||||
|
</span> |
||||
|
<GuipToolTip :content="isCollapse ? '展开' : '收起'"> |
||||
|
<img v-if="!isCollapse" class="point" src="../assets/menu-close.svg" @click="changeMenuStatus(true)" alt=""> |
||||
|
<img v-else class="point" src="../assets/menu-open.svg" @click="changeMenuStatus(false)" alt=""> |
||||
|
</GuipToolTip> |
||||
|
</div> |
||||
|
<template v-for="item in menuData" > |
||||
|
<el-submenu v-if="item.children" :key="item.index" :index="item.index"> |
||||
|
<template slot="title"> |
||||
|
<SvgIcon1 :iconPath="require(`@/assets/menu/${item.icon}.svg`)" defaultColor="#8A9099" |
||||
|
activeColor="#006AFF" :isActive="item.index == currentMenuItem?.index?.substring(0,1) && isCollapse" /> |
||||
|
<span class="title_text" >{{ item.title }}</span> |
||||
|
</template> |
||||
|
<el-menu-item style="padding: 0 22px 0 32px;" v-for="subItem in item.children" :key="subItem.index" |
||||
|
:index="subItem.index" @click="handleSelect(subItem.index, [item.index, subItem.index], subItem)"> |
||||
|
{{ subItem.title }} |
||||
|
</el-menu-item> |
||||
|
</el-submenu> |
||||
|
<el-menu-item v-else :index="item.index" :key="item.index" @click="handleSelect(item.index, [item.index], item)"> |
||||
|
<div class="flex"> |
||||
|
<SvgIcon1 :iconPath="require(`@/assets/menu/${item.icon}.svg`)" defaultColor="#8A9099" |
||||
|
activeColor="#006AFF" :isActive="item.index == currentMenuItem?.index" /> |
||||
|
<span class="title_text" slot="title">{{ item.title }}</span> |
||||
|
</div> |
||||
|
</el-menu-item> |
||||
|
</template> |
||||
|
</div> |
||||
|
</el-menu> |
||||
|
|
||||
|
<SetLeftMenu v-else :menuList="menuData"/> |
||||
|
</transition> |
||||
|
|
||||
|
</template> |
||||
|
<script> |
||||
|
import SetLeftMenu from '@/components/SetLeftMenu.vue' |
||||
|
import SvgIcon1 from '@/components/SvgIcon1.vue'; |
||||
|
import GuipToolTip from '@/components/GuipToolTip.vue'; |
||||
|
export default { |
||||
|
name: 'SliderMenu', |
||||
|
components: { |
||||
|
SvgIcon1, |
||||
|
GuipToolTip, |
||||
|
SetLeftMenu |
||||
|
}, |
||||
|
props: { |
||||
|
menuData: { |
||||
|
type: Array, |
||||
|
default: () => [] |
||||
|
}, |
||||
|
customize:{ |
||||
|
type:Boolean, |
||||
|
default:false |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
isCollapse: false, |
||||
|
routerList: [], |
||||
|
currentMenuItem:'', |
||||
|
currentMenuParent:'' |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
"$route.path"() { |
||||
|
if(this.customize)return |
||||
|
this.updateCurrentMenu(); |
||||
|
}, |
||||
|
}, |
||||
|
methods: { |
||||
|
changeMenuStatus(flag) { |
||||
|
this.isCollapse = flag; |
||||
|
}, |
||||
|
handleOpen(key, keyPath) { |
||||
|
console.log(key, keyPath); |
||||
|
}, |
||||
|
handleClose(key, keyPath) { |
||||
|
console.log(key, keyPath); |
||||
|
}, |
||||
|
// handleSelect(index,indexPath) { |
||||
|
// this.activeMenu = index; |
||||
|
// console.log(index,indexPath, '---index'); |
||||
|
// // 找到被点击的 menu 项对应的 path |
||||
|
// const allItems = this.menuData.flatMap(menu => menu.children); |
||||
|
// const targetItem = allItems.find(item => item.index === index); |
||||
|
|
||||
|
// if (targetItem && this.$route.path !== targetItem.path) { |
||||
|
// this.$router.push(targetItem.path); |
||||
|
// } |
||||
|
// }, |
||||
|
handleSelect(index, indexPath, menuItem) { |
||||
|
if (menuItem.path && this.$route.path !== menuItem.path) { |
||||
|
this.$router.push(menuItem.path); |
||||
|
} |
||||
|
}, |
||||
|
updateCurrentMenu() { |
||||
|
const result = this.findMenuItemByPath(this.menuData, this.$route.path); |
||||
|
this.currentMenuItem = result?.item; |
||||
|
}, |
||||
|
findMenuItemByPath(menuItems, targetPath, parent = null) { |
||||
|
for (const item of menuItems) { |
||||
|
if (item.path === targetPath) return { item, parent }; |
||||
|
if (item.children?.length) { |
||||
|
const found = this.findMenuItemByPath(item.children, targetPath, item); |
||||
|
if (found) return found; |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
}, |
||||
|
}, |
||||
|
mounted() { |
||||
|
// console.log(this.$route.path,'this.$route.path----'); |
||||
|
// const allItems = this.menuData.flatMap(menu =>menu.children ? menu.children?.map(child => ({ ...child, parentIndex: menu.index })) : menu.children); |
||||
|
// console.log(allItems,'====='); |
||||
|
// const current = allItems.find(item => item.path === this.$route.path); |
||||
|
// this.activeMenu = current ? current.index : ''; |
||||
|
// this.defaultOpeneds = current ? [current.parentIndex] : []; |
||||
|
|
||||
|
// this.routerList = this.$router.options.router;//配置路由 |
||||
|
// console.log(this.$route.path, this.$router.options.router, 'this.$route.path==='); |
||||
|
// // 初始化时设置默认激活的菜单项 |
||||
|
// this.activeMenu = this.$route.path; |
||||
|
this.updateCurrentMenu(); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.menu-collapse-leave-active, |
||||
|
.menu-collapse-enter-active { |
||||
|
transition: all 0.5s; |
||||
|
} |
||||
|
|
||||
|
.menu-collapse-enter, |
||||
|
.menu-collapse-leave-to { |
||||
|
opacity: 0; |
||||
|
transform: translateX(-30px); |
||||
|
} |
||||
|
|
||||
|
.el-menu--vertical { |
||||
|
.el-menu-item { |
||||
|
height: 40px; |
||||
|
line-height: 40px; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
.el-menu-item.is-active { |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.title_img { |
||||
|
width: 16px; |
||||
|
margin-right: 4px; |
||||
|
} |
||||
|
|
||||
|
.title_text { |
||||
|
margin-left: 4px; |
||||
|
font-size: 14px; |
||||
|
font-weight: bold; |
||||
|
display: block; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
.el-menu--collapse .title_text { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.el-menu--collapse ::v-deep .el-submenu__icon-arrow { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.el-menu-vertical-demo:not(.el-menu--collapse) { |
||||
|
width: 158px; |
||||
|
min-width: 158px; |
||||
|
min-height: calc(100vh - 62px); |
||||
|
overflow-y: auto; |
||||
|
} |
||||
|
|
||||
|
.el-menu-item { |
||||
|
padding: 0 22px; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
.menu-top { |
||||
|
background: #FFFFFF; |
||||
|
box-sizing: border-box; |
||||
|
/* middle/middle_line_1 */ |
||||
|
border-width: 0px 0px 1px 0px; |
||||
|
border-style: solid; |
||||
|
border-color: #DFE2E6; |
||||
|
padding: 15px 0px; |
||||
|
margin: 0 22px; |
||||
|
display: flex; |
||||
|
font-size: 14px; |
||||
|
color: #1E2226; |
||||
|
font-weight: bold; |
||||
|
line-height: normal; |
||||
|
letter-spacing: 0.08em; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
|
||||
|
img { |
||||
|
width: 14px; |
||||
|
height: 14px; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-submenu { |
||||
|
// width: 16px; |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-submenu .el-menu-item { |
||||
|
min-width: 138px; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-submenu__title { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: flex-start; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-submenu__title:hover { |
||||
|
background-color: transparent; |
||||
|
// cursor: not-allowed; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-submenu__title .el-submenu__icon-arrow.el-icon-arrow-down { |
||||
|
// display: none; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-submenu .el-menu-item { |
||||
|
padding: 0 22px; |
||||
|
display: flex; |
||||
|
justify-content: flex-start; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-submenu .el-menu-item { |
||||
|
height: 36px; |
||||
|
} |
||||
|
|
||||
|
::v-deep.el-submenu .el-menu-item { |
||||
|
height: 36px; |
||||
|
line-height: 36px; |
||||
|
color: #8A9099; |
||||
|
letter-spacing: 0.08em; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-menu-item:hover { |
||||
|
background: #F6F7FA; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-menu-item.is-active { |
||||
|
color: #006AFF; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
// .el-submenu .el-menu { |
||||
|
// transition: all 0.3s ease; |
||||
|
// } |
||||
|
|
||||
|
// .el-menu--collapse .el-submenu > .el-menu { |
||||
|
// display: block !important; |
||||
|
// overflow: hidden; |
||||
|
// transition: all 0.3s ease; |
||||
|
// opacity: 0; |
||||
|
// height: 0; |
||||
|
// transform: translateY(-10px); |
||||
|
// } |
||||
|
|
||||
|
// .el-menu--collapse .el-submenu.is-opened > .el-menu { |
||||
|
// opacity: 0; |
||||
|
// height: 0; |
||||
|
// } |
||||
|
</style> |
||||
@ -0,0 +1,7 @@ |
|||||
|
import GuipSwitch from './src/index.vue' |
||||
|
|
||||
|
GuipSwitch.install = function(Vue) { |
||||
|
Vue.component(GuipSwitch.name || 'GuipSwitch', GuipSwitch) |
||||
|
} |
||||
|
|
||||
|
export default GuipSwitch |
||||
@ -0,0 +1,109 @@ |
|||||
|
<template> |
||||
|
<el-form-item :prop="prop" :label="label" :rules="rules"> |
||||
|
<div class="guip_switchWrap"> |
||||
|
<span :class="['switchDesc', { 'fl': float == 'left' }, { 'fr': float == 'right' }]" |
||||
|
v-if="activeText || inactiveText"> |
||||
|
{{ internalValue === activeValue ? activeText : inactiveText |
||||
|
}}</span> |
||||
|
|
||||
|
<el-switch v-model="internalValue" :active-color="activeColor" :inactive-color="inactiveColor" |
||||
|
v-bind="$attrs" :disabled="disabled" :active-value="activeValue" :inactive-value="inactiveValue" |
||||
|
@change="handleChange"> |
||||
|
<!-- 自定义开启时的图标 --> |
||||
|
<template #active-icon> |
||||
|
</template> |
||||
|
<!-- 自定义关闭时的图标 --> |
||||
|
<template #inactive-icon> |
||||
|
</template> |
||||
|
</el-switch> |
||||
|
</div> |
||||
|
</el-form-item> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'GuipSwitch', |
||||
|
inheritAttrs: false, |
||||
|
props: { |
||||
|
// modelValue: { type: [Boolean, String, Number], default: undefined }, |
||||
|
value: { type: [Boolean, String, Number], default: undefined }, |
||||
|
prop: String, |
||||
|
label: String, |
||||
|
rules: Array, |
||||
|
labelWidth: String, |
||||
|
|
||||
|
activeText: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
inactiveText: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
activeValue: { |
||||
|
type: [Boolean, String, Number], |
||||
|
default: true, |
||||
|
}, |
||||
|
inactiveValue: { |
||||
|
type: [Boolean, String, Number], |
||||
|
default: false, |
||||
|
}, |
||||
|
activeColor: { |
||||
|
type: String, |
||||
|
default: '#00C261', |
||||
|
}, |
||||
|
inactiveColor: { |
||||
|
type: String, |
||||
|
default: '#BABDC2', |
||||
|
}, |
||||
|
float: { |
||||
|
type: String, |
||||
|
default: 'left', |
||||
|
}, |
||||
|
disabled: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
internalValue: this.value, |
||||
|
errorMsg: '' |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
// internalValue: { |
||||
|
// get() { |
||||
|
// return this.modelValue !== undefined ? this.modelValue : this.value |
||||
|
// }, |
||||
|
// set(val) { |
||||
|
// this.$emit('update:modelValue', val) |
||||
|
// this.$emit('input', val) |
||||
|
// } |
||||
|
// } |
||||
|
}, |
||||
|
watch: { |
||||
|
value(newVal) { |
||||
|
this.internalValue = newVal |
||||
|
}, |
||||
|
// modelValue(newVal) { |
||||
|
// this.internalValue = newVal |
||||
|
// }, |
||||
|
}, |
||||
|
methods: { |
||||
|
handleChange(val) { |
||||
|
// this.$emit('update:modelValue', val) |
||||
|
this.$emit('input', val) |
||||
|
this.$emit('change', val) |
||||
|
this.validateField() |
||||
|
}, |
||||
|
validateField() { |
||||
|
if (this.prop && this.$parent.validateField) { |
||||
|
this.$parent.validateField(this.prop, (error) => { |
||||
|
this.errorMsg = error || '' |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||