element-ui——二级菜单和顶部导航联动

目前

原本数据结构

const users = [{
		id: 1,
		username: 'normal',
		password: 'normal',
		token: 'abcdefghijklmnopqrstuvwxyz',
		leftMenus: [{
				title: '用户管理',
				key: '/user',
				name: 'user',
				icon: 'el-icon-user-solid',
				rights: ['view', 'edit', 'add', 'delete']
			},
			{
				title: '商品管理',
				key: '/products',
				name: 'products',
				icon: 'el-icon-s-goods',
				children: [{
						title: '品类管理',
						key: '/category',
						name: 'category',
						icon: 'el-icon-s-ticket',
						rights: ['view', 'edit', 'add', 'delete']
					},
					{
						title: '商品生产',
						key: '/product',
						name: 'product',
						icon: 'el-icon-s-promotion',
						rights: ['view', 'edit', 'add', 'delete']
					}
				]
			},
			{
				title: '图形图表',
				key: '/charts',
				name: 'charts',
				icon: 'el-icon-picture',
				children: [{
						title: '柱线图',
						key: '/charts/bar',
						name: 'bar',
						icon: 'el-icon-s-data',
						rights: ['view', 'edit', 'add', 'delete']
					},
					{
						title: '折线图',
						key: '/charts/line',
						name: 'line',
						icon: 'el-icon-s-marketing',
						rights: ['view', 'edit', 'add', 'delete']
					},
					{
						title: '饼图',
						key: '/charts/pie',
						name: 'pie',
						icon: 'el-icon-s-help',
						rights: ['view', 'edit', 'add', 'delete']
					},
				]
			}
		]
	},
	{
		id: 2,
		username: 'admin',
		password: 'admin',
		token: 'abcdefghijklmnopqrstuvwxyz'.split('').reverse().join(''),
		leftMenus: [{
				title: '用户管理',
				key: '/user',
				name: 'user',
				icon: 'el-icon-user-solid',
				rights: ['view', 'edit', 'add', 'delete']
			},
			{
				title: '商品管理',
				key: '/products',
				name: 'products',
				icon: 'el-icon-s-goods',
				children: [{
						title: '品类管理',
						key: '/category',
						name: 'category',
						icon: 'el-icon-s-ticket',
						rights: ['view', 'edit', 'add', 'delete']
					},
					{
						title: '商品生产',
						key: '/product',
						name: 'product',
						icon: 'el-icon-s-promotion',
						rights: ['view', 'edit', 'add', 'delete']
					}
				]
			},
			{
				title: '角色管理',
				key: '/role',
				name: 'role',
				icon: 'el-icon-s-custom',
				rights: ['view', 'edit', 'add', 'delete']
			},
			{
				title: '图形图表',
				key: '/charts',
				name: 'charts',
				icon: 'el-icon-picture',
				children: [{
						title: '柱线图',
						key: '/charts/bar',
						name: 'bar',
						icon: 'el-icon-s-data',
						rights: ['view', 'edit', 'add', 'delete']
					},
					{
						title: '折线图',
						key: '/charts/line',
						name: 'line',
						icon: 'el-icon-s-marketing',
						rights: ['view', 'edit', 'add', 'delete']
					},
					{
						title: '饼图',
						key: '/charts/pie',
						name: 'pie',
						icon: 'el-icon-s-help',
						rights: ['view', 'edit', 'add', 'delete']
					},
				]
			}
		]
	}
]

因为新增顶部导航,所以要重新构建数据结构 。

修改后的数据结构

const users = [{
		id: 1,
		username: 'normal',
		password: 'normal',
		token: 'abcdefghijklmnopqrstuvwxyz',
		navBar: {
			active: '0',
			list: [{
					name: "首页",
					subActive: '0',
					leftMenus: [{
							id: 1,
							title: '用户管理1',
							key: '/user',
							name: 'user',
							icon: 'el-icon-user-solid',
							rights: ['view', 'edit', 'add', 'delete']
						},
						{
							id: 2,
							title: '商品管理',
							name: 'products',
							icon: 'el-icon-s-goods',
							children: [{
									id: 21,
									title: '品类管理',
									key: '/category',
									name: 'category',
									icon: 'bars',
									rights: ['view', 'edit', 'add', 'delete']
								},
								{
									id: 22,
									title: '商品生产',
									key: '/product',
									name: 'product',
									icon: 'tool',
									rights: ['view', 'edit', 'add', 'delete']
								}
							]
						},
						{
							id: 4,
							title: '图形图表',
							name: 'charts',
							icon: 'el-icon-s-platform',
							children: [{
									id: 41,
									title: '柱线图',
									key: '/charts/bar',
									name: 'bar',
									icon: 'el-icon-s-data',
									rights: ['view', 'edit', 'add', 'delete']
								},
								{
									id: 42,
									title: '折线图',
									key: '/charts/line',
									name: 'line',
									icon: 'el-icon-s-marketing',
									rights: ['view', 'edit', 'add', 'delete']
								},
								{
									id: 43,
									title: '饼图',
									key: '/charts/pie',
									name: 'pie',
									icon: 'el-icon-s-help',
									rights: ['view', 'edit', 'add', 'delete']
								},
							]
						}
					]
				},
				{
					name: "商品",
					subActive: '0',
					leftMenus: [{
						id: 1,
						title: '用户管理2',
						key: '/user2',
						name: 'user2',
						icon: 'el-icon-user-solid',
						rights: ['view', 'edit', 'add', 'delete']
					}]
				},
				{
					name: "订单",
					subActive: '0',
					leftMenus: [{
							id: 32,
							title: '订单管理',
							key: '/dingg',
							name: 'dingg',
							icon: 'el-icon-user-solid',
							rights: ['view', 'edit', 'add', 'delete']
						},
						{
							id: 34,
							title: '订单统计',
							name: 'ding',
							icon: 'el-icon-user-solid',
							children: [{
								id: 35,
								title: '订单汇总',
								key: '/ding/hui',
								name: 'dinghui',
								icon: 'el-icon-s-data',
								rights: ['view', 'edit', 'add', 'delete']
							}, ]
						}


					]
				},
				{
					name: "会员"
				},
				{
					name: "设置"
				},
			]
		}
	},
	{
		id: 2,
		username: 'admin',
		password: 'admin',
		token: 'abcdefghijklmnopqrstuvwxyz'.split('').reverse().join(''),
		/* rights: [{
      id: 1,
      authName: '用户管理',
      icon: 'icon-menu',
      children: [{
        id: 11,
        authName: '用户项目1',
        path: '/menu/one',
        rights: ['view', 'edit', 'add']
      }, {
        id: 12,
        authName: '用户项目2',
        path: '/menu/two',
        rights: ['view', 'edit', 'add', 'delete']
      }]
    }, {
      id: 2,
      authName: '用户权限',
      icon: 'icon-menu',
      children: [{
        id: 22,
        authName: '权限项目1',
        path: '/menu/three',
        rights: ['view', 'edit', 'add', 'delete']
      }]
    },
	{
	  id: 3,
	  authName: '用户信息',
	  icon: 'icon-menu'
	},
	] */
		leftMenus: [{
				id: 1,
				title: '用户管理',
				key: '/user',
				name: 'user',
				icon: 'el-icon-user-solid',
				rights: ['view', 'edit', 'add', 'delete']
			},
			{
				id: 2,
				title: '商品管理',
				key: '/products',
				name: 'products',
				icon: 'el-icon-s-goods',
				children: [{
						id: 21,
						title: '品类管理',
						key: '/category',
						name: 'category',
						icon: 'bars',
						rights: ['view', 'edit', 'add', 'delete']
					},
					{
						id: 22,
						title: '商品生产',
						key: '/product',
						name: 'product',
						icon: 'tool',
						rights: ['view', 'edit', 'add', 'delete']
					}
				]
			},
			{
				id: 3,
				title: '角色管理',
				key: '/role',
				name: 'role',
				icon: 'el-icon-s-custom',
				rights: ['view', 'edit', 'add', 'delete']
			},
			{
				id: 4,
				title: '图形图表',
				key: '/charts',
				name: 'charts',
				icon: 'el-icon-s-platform',
				children: [{
						id: 41,
						title: '柱线图',
						key: '/charts/bar',
						name: 'bar',
						icon: 'el-icon-s-data',
						rights: ['view', 'edit', 'add', 'delete']
					},
					{
						id: 42,
						title: '折线图',
						key: '/charts/line',
						name: 'line',
						icon: 'el-icon-s-marketing',
						rights: ['view', 'edit', 'add', 'delete']
					},
					{
						id: 43,
						title: '饼图',
						key: '/charts/pie',
						name: 'pie',
						icon: 'el-icon-s-help',
						rights: ['view', 'edit', 'add', 'delete']
					},
				]
			}
		]
	}
]

头部布局

		<div class="header-right">
			<el-menu :default-active="user.navBar.active" class="el-menu-demo" mode="horizontal" @select="handleSelect"
			 background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
				<el-menu-item :index="index+''" v-for="(item,index) in user.navBar.list" :key="index">{{item.name}}</el-menu-item>
				<el-submenu index="2">
					<template slot="title">{{user.username}}</template>
					<el-menu-item index="2-1">设置</el-menu-item>
					<el-menu-item index="2-2">退出</el-menu-item>
				</el-submenu>
			</el-menu>
		</div>
  methods: {
    ...mapMutations(["getslideMenus"]),
    handleSelect(key, keyPath) {
      this.user.navBar.active = key;
      let item = this.user.navBar.list[this.user.navBar.active];
      console.log(key, keyPath);
      this.getslideMenus(item.leftMenus);
	  this.$router.push({
		  name:item.leftMenus[0].name
	  })
	  if (key == '0') {
		  this.$router.push({
			  name:'welcome'
		  })
	  }
    },
    collapse() {
      this.isCollapseq = !this.isCollapseq;
      this.$bus.$emit("collapseaside", this.isCollapseq);
    },
  },
		mounted() {
			let item = this.user.navBar.list[this.user.navBar.active]
			this.getslideMenus(item.leftMenus)
		},
		computed: {
			...mapState(['user'])
		}

vuex

export default new Vuex.Store({
	state: {
		bread: [],
		slideMenus:[],
		user: JSON.parse(window.sessionStorage.getItem('rightlist')) || {}

	},
	mutations: {
		addBread(state,preload) {
            state.bread = preload
		},
		getslideMenus(state,preload){
			state.slideMenus = preload
	   },
		getLogin(state, preload) {
			state.user = preload
			window.sessionStorage.setItem('rightlist', JSON.stringify(preload))
		}

	},
	getters: {

	},
	actions: {}
})

Header.vue

<template>
  <div class="header">
    <div class="header-left">
      <div class="header-left__logo">
        <img src="@/assets/logo.png" alt="" />
      </div>
      <div class="header-left__title">后台管理系统权限Demo</div>
      <i class="el-icon-s-fold icon" @click="collapse"></i>
    </div>
    <div class="header-right">
      <el-menu
        :default-active="user.navBar.active"
        class="el-menu-demo"
        mode="horizontal"
        @select="handleSelect"
        background-color="#333333"
        text-color="#fff"
        active-text-color="#ffd04b"
		
      >
        <el-menu-item
          :index="index + ''"
          v-for="(item, index) in user.navBar.list"
          :key="index"
          >{{ item.name }}</el-menu-item
        >
        <el-submenu index="2">
          <template slot="title">{{ user.username }}</template>
          <el-menu-item index="2-1">设置</el-menu-item>
          <el-menu-item index="2-2">退出</el-menu-item>
        </el-submenu>
      </el-menu>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations } from "vuex";
export default {
  name: "Header",
  data() {
    return {
      isCollapseq: false,
    };
  },
  methods: {
    ...mapMutations(["getslideMenus","getData"]),
    handleSelect(key, keyPath) {
      this.user.navBar.active = key;
      // this.getLogin(this.user)
      let item = this.user.navBar.list[this.user.navBar.active];
      console.log(key, keyPath);
      this.getslideMenus(item.leftMenus);
	  this.$router.push({
		  name:item.leftMenus[0].name
	  })
	  if (key == '0') {
		  this.$router.push({
			  name:'welcome'
		  })
	  }
    window.sessionStorage.setItem('nactive',JSON.stringify(this.user.navBar.active))
    },
    collapse() {
      this.isCollapseq = !this.isCollapseq;
      this.$bus.$emit("collapseaside", this.isCollapseq);
    },
  },
  computed: {
    ...mapState(["user"]),
  },
  mounted() {
    let i = JSON.parse(window.sessionStorage.getItem('nactive'))
    this.user.navBar.active = i
    let item = this.user.navBar.list[this.user.navBar.active];
    this.getslideMenus(item.leftMenus);
  },
  watch:{
    $route(to,from){
      window.sessionStorage.setItem('nactive',JSON.stringify(this.user.navBar.active))
      if (to.path == '/welcome') {
          this.user.navBar.active = '0',
          window.sessionStorage.setItem('nactive',JSON.stringify(this.user.navBar.active))
          let item = this.user.navBar.list[this.user.navBar.active]
          this.getslideMenus(item.leftMenus)
      }
    }
  }
};
</script>

<style lang="less" scoped>
.header {
  width: 100%;
  height: 100%;
  background-color: #333;
  display: flex;
  justify-content: space-between;
  box-shadow: 0 2px 5px #333;
  &-left {
    height: 100%;
    display: flex;
    align-items: center;
    .icon {
      color: #fff;
      margin-left: 30px;
    }
    &__logo {
      width: 80px;
      height: 100%;
      padding: 5px;
      & > img {
        width: 100%;
        height: 100%;
      }
    }
    &__title {
      font-size: 20px;
      color: #fff;
      text-shadow: 10px 10px rgba(25, 255, 255, 0.3);
    }
  }
  &-right {
    display: flex;
    align-items: center;
    &__info {
      &-name {
        color: #f0ffff;
        font-size: 16px;
        margin-right: 15px;
      }
    }
  }
}
</style>

 

 Home.vue

  methods: {
    ...mapMutations(["addBread"]),
    /* 面包屑导航 */
    getbreadcrumb() {
      let getobj = this.$route.matched.filter((v) => v.name);
      console.log(getobj);
      let arr = [];
      getobj.forEach((v) => {
        if (v.name == "welcome" || v.name == "Home") {
          return;
        }
        arr.push({
          name: v.name,
          path: v.path,
          title: v.meta.title,
        });
        /* 多级导航 */
        this.slideMenus.forEach((item) => {
          console.log(item);
          if (item.children) {
            item.children.filter((i) => i.key == v.path).length > 0
              ? arr.unshift({ 
				  title: item.title 
				})
              : arr;
          }
        });
      });
        if (arr.length > 0) {
          arr.unshift({
            name: "Home",
            path: "/",
            title: "后台首页",
          });
        }
        this.bran = arr;
        this.addBread(this.bran);
    },
  },

HomeLeft添加个样式判断

<template>
  <div class="navMenu">
    <label v-for="(navMenu,n) in navMenus" :key="n">
      <!--只有一级菜单-->
      <el-menu-item v-if="!navMenu.children"
                    :index="n + ''"
                    :route="navMenu.key"
                    :style="$route.path == navMenu.key?'color:#ffd04b':''"
      >
        <!--图标-->
        <i :class="navMenu.icon" :style="$route.path == navMenu.key?'color:#ffd04b':''"></i>
        <!--标题-->
        <span slot="title">{{navMenu.title}}</span>
      </el-menu-item>
      <!--有多级菜单-->
      <el-submenu v-if="navMenu.children"
                  :key="navMenu.key"
                  :index="n+''"
      >
        <template slot="title">
          <i :class="navMenu.icon"></i>
          <span> {{navMenu.title}}</span>
        </template>
        <!--递归组件,把遍历的值传回子组件,完成递归调用-->
        <nav-menu :navMenus="navMenu.children"></nav-menu>
      </el-submenu>
    </label>

  </div>
</template>

<script>
  export default {
    name: 'NavMenu', //使用递归组件必须要有
    props: ['navMenus'], // 传入子组件的数据
    data() {
      return {}
    },
    methods: {
      handleSelect(key,keyPath){
        console.log('1212')
        console.log(key,keyPath)
      }
    }
  }
</script>

<style scoped>

</style>

加个路由

import User2 from '../views/User2.vue'			
            {
				path: '/user2',
				name:'user2',
				meta:{title:'用户管理2'},
				component: User2
			},

现在:

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 在 element-ui 中,可以通过 `cascader` 组件实现下拉框的联动。以下是一个示例代码片段,实现了两个下拉框的二级联动: ``` <template> <div> <el-cascader v-model="selectedCities" :options="cities" @change="handleCityChange" clearable ></el-cascader> <el-cascader v-model="selectedDistricts" :options="districts" :show-all-levels="false" clearable ></el-cascader> </div> </template> <script> export default { data() { return { cities: [ { value: 'beijing', label: '北京', children: [ { value: 'dongcheng', label: '东城', }, { value: 'xicheng', label: '西城', }, ], }, { value: 'shanghai', label: '上海', children: [ { value: 'pudong', label: '浦东', }, { value: 'minhang', label: '闵行', }, ], }, ], districts: [], selectedCities: [], selectedDistricts: [], }; }, methods: { handleCityChange(value) { const city = this.cities.find((c) => c.value === value[0]); if (city) { this.districts = city.children; } else { this.districts = []; } this.selectedDistricts = []; }, }, }; </script> ``` 在上述代码中,我们使用了两个 `el-cascader` 组件,第一个用于选择城市,第二个用于选择区县。当城市选择发生变化时,我们根据所选城市的子节点来更新区县下拉框的选项,并将其值清空,以避免用户选择错误的区县。 ### 回答2: element是一款基于Vue.js的UI组件库,提供了一系列的常用组件。其中,element中的select组件支持二级联动功能。下面我将详细解释如何使用element-ui实现select组件的二级联动。 首先,我们需要引入element-ui的select组件和option组件,并在Vue实例中注册这两个组件。 在template中,我们需要使用el-select和el-option标签来构建下拉框。el-select用于显示下拉框,el-option用于显示下拉框的选项。 二级联动的实现思路是,根据第一个下拉框的选项,动态生成第二个下拉框的选项。我们可以通过监听第一个下拉框的值的变化,动态更新第二个下拉框的选项。具体实现如下: 1. 在data中定义需要的数据,包括第一个下拉框和第二个下拉框的选项数据。 2. 在template中,使用el-select标签构建第一个下拉框,并绑定一个v-model,用来获取选中的值。 3. 监听第一个下拉框的值的变化,使用watch选项,在回调函数中根据选中的值动态生成第二个下拉框的选项。 4. 在template中,使用el-select标签构建第二个下拉框,并绑定一个v-model,用来获取选中的值。 通过以上步骤,我们可以实现element-ui select组件的二级联动。当第一个下拉框的值改变时,第二个下拉框的选项也会相应改变。 需要注意的是,我们可以根据实际需求进行修改和扩展,例如三级联动、四级联动等,只需要在第三个、第四个下拉框中添加相应的监听和选项即可。 希望以上回答能帮助到您,如有其他问题,欢迎继续提问。 ### 回答3: element 也是一个流行的前端 UI 框架,它提供了许多实用的组件,其中包括 select 下拉框。而在 element 的 select 中实现二级联动可以通过监听第一个下拉框的变化来动态修改第二个下拉框的选项。 首先,在 Vue 的实例中,我们需要定义两个变量,例如 province 和 city,分别用来保存第一级和第二级联动的选项。然后,我们在模板中使用 element 的 select 组件,并绑定相应的变量。 在第一个下拉框中,我们需要设定一个监听函数,例如 handleChangeProvince,当选择了某一个省份时,该函数会被触发。在该函数中,我们可以根据选择的省份来更新第二个下拉框的选项,例如将 city 设为该省份所对应的城市列表。 实现这一过程的关键在于如何将第一个下拉框的选项和第二个下拉框的选项进行关联。一种常见的做法是通过一个对象的键值对来表示对应关系,例如一个 provinces 对象保存了省份和城市的对应关系,其中键表示省份,值表示对应的城市列表。当选择了某一个省份时,我们可以通过 provinces[province] 来获取该省份所对应的城市列表。 最后,我们将更新后的城市列表赋给第二个下拉框的选项,这样就实现了二级联动。需要注意的是,当再次选择第一个下拉框时,第二个下拉框的选项也需要更新,以保证联动效果。 总之,通过利用 element 的 select 组件和 Vue 的监听函数,我们可以轻松实现二级联动的下拉框。这样用户可以根据自己的需求选择对应的选项,提升了用户体验和交互性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Southern Wind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值