#### 菜单点击跳转和样式问题
1.在el-menu-item中设置点击事件,script中写入相关代码
2.在Main中的el-main标签中写入routerview标签,实现跳转路由页面
3.关于图标:要进行额外的一个引入
1.下载依赖:cnpm install @element-plus/icons-vue
2.注册所有图标,放在main.js中
// 如果您正在使用CDN引入,请删除下面一行。
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
treeMenu.vue页面代码
<template>
<!-- <el-sub-menu index="1">
<template #title>
<el-icon><location /></el-icon>
<span>Navigator One</span>
</template>
<el-menu-item-group title="Group One">
<el-menu-item index="1-1">item one</el-menu-item>
<el-menu-item index="1-2">item two</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="Group Two">
<el-menu-item index="1-3">item three</el-menu-item>
</el-menu-item-group>
<el-sub-menu index="1-4">
<template #title>item four</template>
<el-menu-item index="1-4-1">item one</el-menu-item>
</el-sub-menu>
</el-sub-menu>
<el-menu-item index="2">
<el-icon><icon-menu /></el-icon>
<span>Navigator Two</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<el-icon><document /></el-icon>
<span>Navigator Three</span>
</el-menu-item> -->
<template v-for="(item,index) in props.menuData">
<!-- 没子菜单的情况 -->
<el-menu-item
@click="handleClick(item,`${ props.index }-${item.meta.id}`)"
v-if="!item.children || item.children.length == 0"
:index="`${ props.index }-${item.meta.id}`"
:key="`${ props.index }-${item.meta.id}`">
<!-- <el-icon><setting /></el-icon>
<span>Navigator Four</span> -->
<el-icon size="20">
<!-- 动态组件 -->
<component :is="item.meta.icon">
</component>
</el-icon>
<span>{{ item.meta.name }}</span>
</el-menu-item>
<!-- 有子菜单的情况 -->
<el-sub-menu
v-else
:index="`${ props.index }-${item.meta.id}`">
<template #title>
<el-icon size="20">
<!-- 动态组件 -->
<component :is="item.meta.icon">
</component>
</el-icon>
<span>{{ item.meta.name }}</span>
</template>
<tree-menu
:index="`${ props.index }-${item.meta.id}`"
:menuData="item.children"/>
</el-sub-menu>
</template>
</template>
<script setup>
import { useRouter } from 'vue-router'
const props = defineProps(['menuData','index'])
//创建router实例
const router = useRouter()
//点击菜单
const handleClick = (item,active) => {
router.push(item.meta.path)
}
</script>
<style scoped>
</style>
#### header组件创建和编写样式
1.在components中创建navHeader.vue
2.在main.vue中引入header.vue
3.给navHeader添加图标样式和下拉样式
navHeader.vue代码部分
<template>
<div class="header-container">
<div class="header-left flex-box">
<el-icon class="icon" size="20"><Fold /></el-icon>
</div>
<div class="header-right">
<el-dropdown :hide-on-click="false">
<div class="el-dropdown-link flex-box">
<!-- 头像显示 -->
<el-avatar
src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
/>
<!-- 用户名 -->
<p class="user-name">admin</p>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item disabled>Action 4</el-dropdown-item>
<el-dropdown-item divided>Action 5</el-dropdown-item>
<el-dropdown-item divided>Action 6</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script setup>
</script>
<style lang="less" scoped>
//只要用到这两个属性,可以直接在class中加上
.flex-box {
display: flex;
//垂直方向上的一个居中
align-items: center;
}
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
padding-right: 25px;
background-color: #fff;
.header-left {
height: 100%;
.icon {
width: 45px;
height: 100%;
}
//伪类
.icon:hover {
background-color: #f5f5f5;
//小手效果
cursor: pointer;
}
}
.header-right {
.user-name {
margin-left: 10px;
}
}
}
</style>
#### vuex引入和菜单展开收起功能实现
1.vuex下载
cnpm install vuex@next --save
2.src中创建文件夹store,在store中创建index.js和menu.js
index.js代码展示
import { createStore } from 'vuex'
import menu from './menu'
//对外进行暴露
export default createStore({
modules: {
menu
}
})
menu.js代码展示
import { Select } from "@element-plus/icons-vue"
//定义状态
const state = {
isCollapse: false,
selectMenu: []
}
const mutations = {
collapseMenu (state){
state.isCollapse = !state.isCollapse
}
}
export default {
state,
mutations
}
store中存放多个组件要用到的东西
3.在main.js中实现路由挂载
import store from './store'
//store挂载
app.use(store)
4.在navHeader.vue中修改
<el-icon class="icon" size="20" @click="store.commit('collapseMenu')"><Fold /></el-icon>
5.在aside.vue中对菜单进行展开和修改的属性添加
<template>
<el-menu
:style="{ width: !isCollapse ? '230px' : '64px'}"
active-text-color="#ffd04b"
background-color="#545c64"
class="aside-container"
default-active="2"
text-color="#fff"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
>
<!-- 添加logo -->
<p class="logo-lg">{{ isCollapse ? '' : 'DIDI陪诊' }}</p>
<TreeMenu index="1" :menuData = "menuData"/>
</el-menu>
</template>
<script setup>
//引入treeMenu
import TreeMenu from './treeMenu.vue'
//获取一个router实例
import { useRouter } from 'vue-router'
//创建响应式数据
import { reactive } from 'vue'
const router = useRouter()
const menuData = reactive(router.options.routes[0].children)
//收起展开菜单
import { computed } from 'vue'
import { useStore } from 'vuex'
const store = useStore()
const isCollapse = computed(() => store.state.menu.isCollapse)
//展开指定的子菜单
const handleOpen = () => {}
//关闭指定的子菜单
const handleClose = () =>{}
</script>
<style lang="less" scoped>
.aside-container{
height: 100%;
.logo-lg {
font-size: 20px;
text-align: center;
height: 50px;
line-height: 50px;
color: #fff;
}
}
</style>
#### tag样式编写和高亮效果实现
1.在menu.js中定义数据
import { Select } from "@element-plus/icons-vue"
//定义状态
const state = {
isCollapse: false,
selectMenu: []
}
const mutations = {
collapseMenu (state){
state.isCollapse = !state.isCollapse
},
addMenu (state,payload){
//对数据进行去重
if(state.selectMenu.findIndex(item => item.path === payload.path) === -1){
state.selectMenu.push(payload)
}
}
}
export default {
state,
mutations
}
2.在treeMenu中传入数据
<template>
<template v-for="(item,index) in props.menuData">
<!-- 没子菜单的情况 -->
<el-menu-item
@click="handleClick(item,`${ props.index }-${item.meta.id}`)"
v-if="!item.children || item.children.length == 0"
:index="`${ props.index }-${item.meta.id}`"
:key="`${ props.index }-${item.meta.id}`">
<!-- <el-icon><setting /></el-icon>
<span>Navigator Four</span> -->
<el-icon size="20">
<!-- 动态组件 -->
<component :is="item.meta.icon">
</component>
</el-icon>
<span>{{ item.meta.name }}</span>
</el-menu-item>
<!-- 有子菜单的情况 -->
<el-sub-menu
v-else
:index="`${ props.index }-${item.meta.id}`">
<template #title>
<el-icon size="20">
<!-- 动态组件 -->
<component :is="item.meta.icon">
</component>
</el-icon>
<span>{{ item.meta.name }}</span>
</template>
<tree-menu
:index="`${ props.index }-${item.meta.id}`"
:menuData="item.children"/>
</el-sub-menu>
</template>
</template>
<script setup>
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
const props = defineProps(['menuData','index'])
//创建router实例
const router = useRouter()
const store = useStore()
//点击菜单
const handleClick = (item,active) => {
store.commit('addMenu',item.meta)
router.push(item.meta.path)
}
</script>
<style scoped>
</style>
3.在navHeader中做显示
<template>
<div class="header-container">
<div class="header-left flex-box">
<el-icon class="icon" size="20" @click="store.commit('collapseMenu')"><Fold /></el-icon>
<ul class="flex-box">
<li v-for="(item,index) in selectMenu"
:key="item.path"
:class="{ selected: route.path === item.path}"
class="tab flex-box">
<el-icon size="12" ><component :is="item.icon"/></el-icon>
<!-- 点击跳转到对应页面 -->
<router-link class="text flex-box" :to="{path: item.path}">
{{ item.name }}
</router-link>
<el-icon class="close" size="12" ><Close /></el-icon>
</li>
</ul>
</div>
<div class="header-right">
<el-dropdown :hide-on-click="false">
<div class="el-dropdown-link flex-box">
<!-- 头像显示 -->
<el-avatar
src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
/>
<!-- 用户名 -->
<p class="user-name">admin</p>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item disabled>Action 4</el-dropdown-item>
<el-dropdown-item divided>Action 5</el-dropdown-item>
<el-dropdown-item divided>Action 6</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script setup>
import { useStore } from 'vuex'
import { computed } from 'vue'
//useRoute表示当前的路由对象
import { useRoute} from 'vue-router'
//拿到store实例
const store = useStore()
//当前的路由对象
const route = useRoute()
const selectMenu = computed(() => store.state.menu.selectMenu)
</script>
<style lang="less" scoped>
//只要用到这两个属性,可以直接在class中加上
.flex-box {
display: flex;
//垂直方向上的一个居中
align-items: center;
height: 100%;
}
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
padding-right: 25px;
background-color: #fff;
.header-left {
height: 100%;
.icon {
width: 45px;
height: 100%;
}
//伪类
.icon:hover {
background-color: #f5f5f5;
//小手效果
cursor: pointer;
}
.tab {
padding: 0 10px;
height: 100%;
.text {
margin: 0 5px;
}
.close {
visibility: hidden;
}
//&表示同级
&.selected {
a {
color: #409eff;
}
i {
color: #409eff;
}
background-color: #f5f5f5;
}
}
.tab:hover {
background-color: #f5f5f5;
.close {
visibility: inherit;
cursor: pointer;
color: #000;
}
}
}
.header-right {
.user-name {
margin-left: 10px;
}
}
a {
height: 100%;
color: #333;
font-size: 15px;
}
}
</style>