当前位置: 代码网 > it编程>编程语言>Javascript > Vue嵌套路由的各种用法详解

Vue嵌套路由的各种用法详解

2025年02月13日 Javascript 我要评论
一、vue 嵌套路由基础1. 定义嵌套路由在 vue router 中,嵌套路由可以通过在路由配置中定义 children 属性来实现。例如,以下是一个简单的嵌套路由配置:import { creat

一、vue 嵌套路由基础

1. 定义嵌套路由

在 vue router 中,嵌套路由可以通过在路由配置中定义 children 属性来实现。例如,以下是一个简单的嵌套路由配置:

import { createrouter, createwebhistory } from 'vue-router';

const routes = [
  {
    path: '/',
    component: () => import('./views/home.vue'),
  },
  {
    path: '/dashboard',
    component: () => import('./views/dashboard.vue'),
    children: [
      {
        path: 'profile',
        component: () => import('./views/profile.vue'),
      },
      {
        path: 'settings',
        component: () => import('./views/settings.vue'),
      },
    ],
  },
];

const router = createrouter({
  history: createwebhistory(),
  routes,
});

export default router;

在这个例子中,/dashboard 是父路由,/dashboard/profile 和 /dashboard/settings 是子路由。

2. 使用嵌套路由

在父组件中,可以通过 来渲染子路由的组件:

<template>
  <el-menu :default-active="$route.path" router>
    <el-menu-item index="/home">首页</el-menu-item>
    <el-menu-item index="/users">用户管理</el-menu-item>
    <el-sub-menu index="/dashboard">
      <template #title>仪表盘</template>
      <el-menu-item index="/dashboard/profile">个人资料</el-menu-item>
      <el-menu-item index="/dashboard/settings">设置</el-menu-item>
    </el-sub-menu>
  </el-menu>
</template>

二、element plus menu 基础用法

element plus 的 menu 组件支持多种用法,包括水平菜单、垂直菜单、折叠菜单等。以下是一些基本用法:

1. 垂直菜单

<template>
  <el-menu :default-active="$route.path" router>
    <el-menu-item index="/home">首页</el-menu-item>
    <el-menu-item index="/users">用户管理</el-menu-item>
    <el-sub-menu index="/dashboard">
      <template #title>仪表盘</template>
      <el-menu-item index="/dashboard/profile">个人资料</el-menu-item>
      <el-menu-item index="/dashboard/settings">设置</el-menu-item>
    </el-sub-menu>
  </el-menu>
</template>

在这个例子中,el-menu 的 router 属性用于激活当前路由对应的菜单项。

2. 水平菜单

水平菜单可以通过设置 mode=“horizontal” 来实现:

<template>
  <el-menu mode="horizontal" :default-active="$route.path" router>
    <el-menu-item index="/home">首页</el-menu-item>
    <el-menu-item index="/users">用户管理</el-menu-item>
    <el-sub-menu index="/dashboard">
      <template #title>仪表盘</template>
      <el-menu-item index="/dashboard/profile">个人资料</el-menu-item>
      <el-menu-item index="/dashboard/settings">设置</el-menu-item>
    </el-sub-menu>
  </el-menu>
</template>

三、vue 嵌套路由与 element plus menu 的结合

1. 动态菜单

可以通过动态绑定数据来生成菜单项。例如,从后端获取菜单数据并渲染:

<template>
  <el-menu :default-active="$route.path" router>
    <template v-for="item in menudata" :key="item.index">
      <el-menu-item v-if="!item.children" :index="item.index">
        {{ item.label }}
      </el-menu-item>
      <el-sub-menu v-else :index="item.index">
        <template #title>{{ item.label }}</template>
        <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index">
          {{ child.label }}
        </el-menu-item>
      </el-sub-menu>
    </template>
  </el-menu>
</template>

<script setup>
import { ref } from 'vue';

const menudata = ref([
  { index: '/home', label: '首页' },
  { index: '/users', label: '用户管理' },
  {
    index: '/dashboard',
    label: '仪表盘',
    children: [
      { index: '/dashboard/profile', label: '个人资料' },
      { index: '/dashboard/settings', label: '设置' },
    ],
  },
]);
</script>

在这个例子中,menudata 是一个动态生成的菜单数据数组。

2. 路由模式

当与 vue router 结合使用时,可以通过 router 属性激活当前路由对应的菜单项。例如:

<template>
  <el-menu :default-active="$route.path" router>
    <el-menu-item index="/home">首页</el-menu-item>
    <el-menu-item index="/users">用户管理</el-menu-item>
    <el-sub-menu index="/dashboard">
      <template #title>仪表盘</template>
      <el-menu-item index="/dashboard/profile">个人资料</el-menu-item>
      <el-menu-item index="/dashboard/settings">设置</el-menu-item>
    </el-sub-menu>
  </el-menu>
</template>

在这个例子中,el-menu 的 router 属性会根据当前路由路径($route.path)自动激活对应的菜单项。

3. 菜单事件处理

element plus 的 menu 组件提供了多种事件,例如 select、open 和 close。可以通过这些事件来处理菜单的交互逻辑。例如:

<template>
  <el-menu :default-active="$route.path" router @select="handleselect">
    <el-menu-item index="/home">首页</el-menu-item>
    <el-menu-item index="/users">用户管理</el-menu-item>
    <el-sub-menu index="/dashboard">
      <template #title>仪表盘</template>
      <el-menu-item index="/dashboard/profile">个人资料</el-menu-item>
      <el-menu-item index="/dashboard/settings">设置</el-menu-item>
    </el-sub-menu>
  </el-menu>
</template>

<script setup>
import { ref } from 'vue';

const handleselect = (index) => {
  console.log(`selected menu: ${index}`);
};
</script>

在这个例子中,handleselect 方法会在菜单项被选中时触发。

四、高级用法

1. 权限控制

在实际应用中,通常需要根据用户的权限动态显示菜单项。可以通过在路由配置中添加权限属性,并在菜单渲染时进行过滤。例如:

const routes = [
  {
    path: '/home',
    component: () => import('./views/home.vue'),
    meta: { requiresauth: false },
  },
  {
    path: '/users',
    component: () => import('./views/users.vue'),
    meta: { requiresauth: true },
  },
  {
    path: '/dashboard',
    component: () => import('./views/dashboard.vue'),
    children: [
      {
        path: 'profile',
        component: () => import('./views/profile.vue'),
        meta: { requiresauth: true },
      },
      {
        path: 'settings',
        component: () => import('./views/settings.vue'),
        meta: { requiresauth: true },
      },
    ],
  },
];

然后在菜单渲染时,根据用户权限过滤菜单项:

<template>
  <el-menu :default-active="$route.path" router>
    <template v-for="item in filteredmenudata" :key="item.index">
      <el-menu-item v-if="!item.children" :index="item.index">
        {{ item.label }}
      </el-menu-item>
      <el-sub-menu v-else :index="item.index">
        <template #title>{{ item.label }}</template>
        <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index">
          {{ child.label }}
        </el-menu-item>
      </el-sub-menu>
    </template>
  </el-menu>
</template>

<script setup>
import { ref, computed } from 'vue';
import { usestore } from 'vuex';

const store = usestore();

const menudata = ref([
  { index: '/home', label: '首页', meta: { requiresauth: false } },
  { index: '/users', label: '用户管理', meta: { requiresauth: true } },
  {
    index: '/dashboard',
    label: '仪表盘',
    children: [
      { index: '/dashboard/profile', label: '个人资料', meta: { requiresauth: true } },
      { index: '/dashboard/settings', label: '设置', meta: { requiresauth: true } },
    ],
  },
]);

const filteredmenudata = computed(() => {
  return menudata.value.filter((item) => {
    if (!item.children) {
      return !item.meta.requiresauth || store.state.isauthenticated;
    } else {
      item.children = item.children.filter((child) => {
        return !child.meta.requiresauth || store.state.isauthenticated;
      });
      return item.children.length > 0;
    }
  });
});
</script>

在这个例子中,filteredmenudata 是一个计算属性,根据用户的认证状态(store.state.isauthenticated)动态过滤菜单项。

2. 菜单的动态加载

在某些情况下,菜单数据可能需要从后端动态加载。可以通过异步请求获取菜单数据,并在获取完成后渲染菜单。例如:

<template>
  <el-menu :default-active="$route.path" router v-if="menudata.length > 0">
    <template v-for="item in menudata" :key="item.index">
      <el-menu-item v-if="!item.children" :index="item.index">
        {{ item.label }}
      </el-menu-item>
      <el-sub-menu v-else :index="item.index">
        <template #title>{{ item.label }}</template>
        <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index">
          {{ child.label }}
        </el-menu-item>
      </el-sub-menu>
    </template>
  </el-menu>
</template>

<script setup>
import { ref, onmounted } from 'vue';
import axios from 'axios';

const menudata = ref([]);

onmounted(async () => {
  try {
    const response = await axios.get('/api/menu');
    menudata.value = response.data;
  } catch (error) {
    console.error('failed to load menu data:', error);
  }
});
</script>

在这个例子中,onmounted 生命周期钩子用于在组件挂载时从后端加载菜单数据。

3. 菜单的国际化

在国际化应用中,菜单项的标题可能需要根据用户的语言偏好动态显示。可以通过 vue i18n 来实现菜单的国际化。例如:

<template>
  <el-menu :default-active="$route.path" router>
    <template v-for="item in menudata" :key="item.index">
      <el-menu-item v-if="!item.children" :index="item.index">
        {{ $t(item.label) }}
      </el-menu-item>
      <el-sub-menu v-else :index="item.index">
        <template #title>{{ $t(item.label) }}</template>
        <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index">
          {{ $t(child.label) }}
        </el-menu-item>
      </el-sub-menu>
    </template>
  </el-menu>
</template>

<script setup>
import { ref } from 'vue';
import { usei18n } from 'vue-i18n';

const { t } = usei18n();

const menudata = ref([
  { index: '/home', label: 'menu.home' },
  { index: '/users', label: 'menu.users' },
  {
    index: '/dashboard',
    label: 'menu.dashboard',
    children: [
      { index: '/dashboard/profile', label: 'menu.profile' },
      { index: '/dashboard/settings', label: 'menu.settings' },
    ],
  },
]);
</script>

<i18n>
{
  "en": {
    "menu": {
      "home": "home",
      "users": "users",
      "dashboard": "dashboard",
      "profile": "profile",
      "settings": "settings"
    }
  },
  "zh": {
    "menu": {
      "home": "首页",
      "users": "用户管理",
      "dashboard": "仪表盘",
      "profile": "个人资料",
      "settings": "设置"
    }
  }
}
</i18n>

在这个例子中,$t 方法用于动态翻译菜单项的标题。

4. 菜单的折叠与展开

element plus 的 menu 组件支持折叠和展开功能。可以通过设置 collapse 属性来控制菜单的折叠状态。例如:

<template>
  <div>
    <el-button @click="togglecollapse">切换菜单</el-button>
    <el-menu :default-active="$route.path" router :collapse="iscollapsed">
      <el-menu-item index="/home">首页</el-menu-item>
      <el-menu-item index="/users">用户管理</el-menu-item>
      <el-sub-menu index="/dashboard">
        <template #title>仪表盘</template>
        <el-menu-item index="/dashboard/profile">个人资料</el-menu-item>
        <el-menu-item index="/dashboard/settings">设置</el-menu-item>
      </el-sub-menu>
    </el-menu>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const iscollapsed = ref(false);

const togglecollapse = () => {
  iscollapsed.value = !iscollapsed.value;
};
</script>

在这个例子中,iscollapsed 是一个响应式变量,用于控制菜单的折叠状态。点击按钮时,togglecollapse 方法会切换菜单的折叠状态。

5. 菜单的自定义样式

可以通过自定义 css 来调整菜单的样式。例如:

.el-menu {
  background-color: #f5f7fa;
  border-right: none;
}

.el-menu-item {
  color: #333;
}

.el-menu-item.is-active {
  background-color: #409eff;
  color: #fff;
}

.el-sub-menu__title {
  color: #333;
}

.el-sub-menu__title:hover {
  background-color: #e6f7ff;
}

在这个例子中,自定义了菜单的背景颜色、字体颜色和激活状态的样式。

五、完整示例

以下是一个完整的示例,结合了嵌套路由、动态菜单、权限控制、国际化和折叠功能:

  • 路由配置
import { createrouter, createwebhistory } from 'vue-router';

const routes = [
  {
    path: '/',
    component: () => import('./views/home.vue'),
    meta: { requiresauth: false },
  },
  {
    path: '/users',
    component: () => import('./views/users.vue'),
    meta: { requiresauth: true },
  },
  {
    path: '/dashboard',
    component: () => import('./views/dashboard.vue'),
    children: [
      {
        path: 'profile',
        component: () => import('./views/profile.vue'),
        meta: { requiresauth: true },
      },
      {
        path: 'settings',
        component: () => import('./views/settings.vue'),
        meta: { requiresauth: true },
      },
    ],
    meta: { requiresauth: true },
  },
];

const router = createrouter({
  history: createwebhistory(),
  routes,
});

export default router;
  • 菜单组件
<template>
  <div>
    <el-button @click="togglecollapse">切换菜单</el-button>
    <el-menu :default-active="$route.path" router :collapse="iscollapsed">
      <template v-for="item in filteredmenudata" :key="item.index">
        <el-menu-item v-if="!item.children" :index="item.index">
          {{ $t(item.label) }}
        </el-menu-item>
        <el-sub-menu v-else :index="item.index">
          <template #title>{{ $t(item.label) }}</template>
          <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index">
            {{ $t(child.label) }}
          </el-menu-item>
        </el-sub-menu>
      </template>
    </el-menu>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { usestore } from 'vuex';
import { usei18n } from 'vue-i18n';

const { t } = usei18n();
const store = usestore();

const menudata = ref([
  { index: '/home', label: 'menu.home', meta: { requiresauth: false } },
  { index: '/users', label: 'menu.users', meta: { requiresauth: true } },
  {
    index: '/dashboard',
    label: 'menu.dashboard',
    children: [
      { index: '/dashboard/profile', label: 'menu.profile', meta: { requiresauth: true } },
      { index: '/dashboard/settings', label: 'menu.settings', meta: { requiresauth: true } },
    ],
    meta: { requiresauth: true },
  },
]);

const iscollapsed = ref(false);

const togglecollapse = () => {
  iscollapsed.value = !iscollapsed.value;
};

const filteredmenudata = computed(() => {
  return menudata.value.filter((item) => {
    if (!item.children) {
      return !item.meta.requiresauth || store.state.isauthenticated;
    } else {
      item.children = item.children.filter((child) => {
        return !child.meta.requiresauth || store.state.isauthenticated;
      });
      return item.children.length > 0;
    }
  });
});
</script>

<i18n>
{
  "en": {
    "menu": {
      "home": "home",
      "users": "users",
      "dashboard": "dashboard",
      "profile": "profile",
      "settings": "settings"
    }
  },
  "zh": {
    "menu": {
      "home": "首页",
      "users": "用户管理",
      "dashboard": "仪表盘",
      "profile": "个人资料",
      "settings": "设置"
    }
  }
}
</i18n>
  • 样式
.el-menu {
  background-color: #f5f7fa;
  border-right: none;
}

.el-menu-item {
  color: #333;
}

.el-menu-item.is-active {
  background-color: #409eff;
  color: #fff;
}

.el-sub-menu__title {
  color: #333;
}

.el-sub-menu__title:hover {
  background-color: #e6f7ff;
}

六、总结

通过结合 vue 嵌套路由和 element plus 的 menu 组件,可以实现功能丰富且灵活的导航菜单。本文介绍了从基础用法到高级功能的多种场景,包括动态菜单、权限控制、国际化、折叠功能和自定义样式。这些功能可以根据实际需求灵活组合,以满足复杂应用的需求。

以上就是vue嵌套路由的各种用法详解的详细内容,更多关于vue嵌套路由用法的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com