|
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> |
|||