首页 > 其他分享 >【Vue 开发实战】实战篇 # 31:如何将菜单和路由结合

【Vue 开发实战】实战篇 # 31:如何将菜单和路由结合

时间:2022-10-13 22:34:31浏览次数:82  
标签:实战篇 Vue name form 31 component item import path


说明

【Vue 开发实战】学习笔记。

实现效果

【Vue 开发实战】实战篇 # 31:如何将菜单和路由结合_ico

BasicLayout.vue

<template>
<div :class="[`nav-theme-${navTheme}`, `nav-layout-${navLayout}`]">
<a-layout id="components-layout-demo-side" style="min-height:">
<a-layout-sider
v-if="navLayout === 'left'"
v-model="collapsed"
width="256px"
collapsible
:theme="navTheme"
:trigger="null"
>
<div class="logo">Ant Design Vue Pro</div>
<SiderMenu :theme="navTheme"/>
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding:">
<a-icon
class="trigger"
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="collapsed = !collapsed"
></a-icon>
<Header />
</a-layout-header>
<a-layout-content style="margin:">
<router-view></router-view>
</a-layout-content>
<a-layout-footer style="text-align:">
<Footer />
</a-layout-footer>
</a-layout>
</a-layout>
<SettingDrawer />
</div>
</template>

<script>import Header from "./Header";
import SiderMenu from "./SiderMenu";
import Footer from "./Footer";
import SettingDrawer from "../components/SettingDrawer";
export default {
data() {
return {
collapsed: false,
};
},
components: {
Header,
SiderMenu,
Footer,
SettingDrawer,
},
computed: {
navTheme() {
return this.$route.query.navTheme || "dark";
},
navLayout() {
return this.$route.query.navLayout || "left";
},
},
};</script>

<style lang="less" scoped>.trigger {
padding: 0 20px;
line-height: 64px;
font-size: 20px;
&:hover {
background-color: #eeeeee;
}
}
.logo {
height: 64px;
line-height: 64px;
text-align: center;
overflow: hidden;
}
.nav-theme-dark {
.logo {
color: #fff;
}
}</style>

SiderMenu.vue

<template>
<div style="width:">
<a-menu
:selectedKeys="selectedKeys"
:openKeys.sync="openKeys"
mode="inline"
:theme="theme"
>
<template v-for="item in menuData">
<a-menu-item v-if="!item.children"
:key="item.path"
@click="() => $router.push({path: item.path, query: $router.query})"
>
<a-icon v-if="item.meta.icon" :type="item.meta.icon" />
<span>{{ item.meta.title }}</span>
</a-menu-item>
<sub-menu v-else :key="item.path" :menu-info="item" />
</template>
</a-menu>
</div>
</template>

<script>import SubMenu from "./SubMenu.vue";
export default {
props: {
theme: {
type: String,
default: "dark"
}
},
components: {
"sub-menu": SubMenu
},
data() {
this.selectedKeysMap = {};
this.openKeysMap = {};
const menuData = this.getMenuData(this.$router.options.routes)
return {
collapsed: false,
menuData,
selectedKeys: this.selectedKeysMap[this.$route.path],
openKeys: this.collapsed ? [] : this.openKeysMap[this.$route.path]
};
},
watch: {
"$route.path": function(val) {
this.selectedKeys = this.selectedKeysMap[val];
this.openKeys = this.collapsed ? [] : this.openKeysMap[val];
}
},
methods: {
getMenuData(routes = [], parentKeys = [],) {
const menuData = [];
routes.forEach(item => {
if(item.name && !item.hideInMenu) {
this.openKeysMap[item.path] = parentKeys;
this.selectedKeysMap[item.path] = [selectedKeys || item.path];
const newItem = {...item};
delete newItem.children;
if(item.children && !item.hideChildrenInMenu) {
newItem.children = this.getMenuData(item.children, [...parentKeys, item.path]);
}else{
this.getMenuData(
item.children,
selectedKeys ? parentKeys : [...parentKeys, item.path],
selectedKeys || item.path
);
}
menuData.push(newItem);
}else if(
!item.hideInMenu &&
!item.hideChildrenInMenu &&
item.children
) {
menuData.push(...this.getMenuData(item.children, [...parentKeys, item.path]));
}
});
return menuData;
}
},
};</script>

SubMenu.vue

<template functional>
<a-sub-menu :key="props.menuInfo.path">
<span slot="title">
<a-icon v-if="props.menuInfo.meta.icon" :type="props.menuInfo.meta.icon" />
<span>{{ props.menuInfo.meta.title }}</span>
</span>
<template v-for="item in props.menuInfo.children">
<a-menu-item v-if="!item.children"
:key="item.path"
@click="() => parent.$router.push({path: item.path, query: parent.$router.query})"
>
<a-icon v-if="item.meta.icon" :type="item.meta.icon" />
<span>{{ item.meta.title }}</span>
</a-menu-item>
<sub-menu v-else :key="item.path" :menu-info="item" />
</template>
</a-sub-menu>
</template>
<script>export default {
props: ["menuInfo"],
};</script>

路由配置

import Vue from "vue";
import VueRouter from "vue-router";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import NotFound from "../views/404";

Vue.use(VueRouter);

const routes = [
{
path: "/user",
hideInMenu: true,
component: () =>
import(/* webpackChunkName: "layout" */ "../layouts/UserLayout"),
children: [
{
path: "/user",
redirect: "/user/login"
},
{
path: "/user/login",
name: "login",
component: () =>
import(/* webpackChunkName: "user" */ "../views/User/Login"),
},
{
path: "/user/register",
name: "register",
component: () =>
import(/* webpackChunkName: "user" */ "../views/User/Register"),
}
],
},
{
path: "/",
component: () =>
import(/* webpackChunkName: "layout" */ "../layouts/BasicLayout"),
children: [
{
path: "/",
redirect: "/dashboard"
},
{
path: "/dashboard",
redirect: "/dashboard/analysis"
},
{
path: "/dashboard",
name: "dashboard",
meta: { icon: "dashboard", title: "仪表盘" },
component: { render: h => h("router-view")},
children: [
{
path: "/dashboard/analysis",
name: "analysis",
meta: { title: "分析页" },
component: () =>
import(/* webpackChunkName: "dashboard" */ "../views/Dashboard/Analysis"),
},
]
},
{
path: "/form",
name: "form",
meta: { icon: "form", title: "表单" },
component: { render: h => h("router-view")},
children: [
{
path: "/form",
redirect: "/form/basic-form"
},
{
path: "/form/basic-form",
name: "basicform",
meta: { title: "基础表单" },
component: () =>
import(/* webpackChunkName: "form" */ "../views/Forms/BasicForm"),
},
{
path: "/form/step-form",
name: "stepform",
hideChildrenInMenu: true,
meta: { title: "分步表单" },
component: () =>
import(/* webpackChunkName: "form" */ "../views/Forms/StepForm"),
children: [
{
path: "/form/step-form",
redirect: "/form/step-form/info"
},
{
path: "/form/step-form/info",
name: "info",
component: () =>
import(/* webpackChunkName: "form" */ "../views/Forms/StepForm/Step1"),
},
{
path: "/form/step-form/confirm",
name: "confirm",
component: () =>
import(/* webpackChunkName: "form" */ "../views/Forms/StepForm/Step2"),
},
{
path: "/form/step-form/result",
name: "result",
component: () =>
import(/* webpackChunkName: "form" */ "../views/Forms/StepForm/Step3"),
},
]
},
]
}
],
},
{
path: "*",
name: "404",
hideInMenu: true,
component: NotFound
}
];

const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes
});

// 路由守卫
router.beforeEach((to, from,) => {
if(to.path !== from.path) {
NProgress.start();
}
next();
})

router.afterEach((to, from) => {
NProgress.done();
})

export default router;

参考

​https://github.com/vueComponent/ant-design-vue/blob/1.4.0/components/menu/demo/SubMenu.vue​


标签:实战篇,Vue,name,form,31,component,item,import,path
From: https://blog.51cto.com/kaimo313/5754841

相关文章

  • 使用 Vue-cli 脚手架创建项目
    本次以WIN10系统为例,其他系统略有差异。第一步,安装npm:进入Node.js官网下载左侧稳定版,因为node包含npm由于node包含npm,所以我们只需要安装node就好了。进入Node.js官网首......
  • 解决 vue 项目使用 swiper 遇到设置轮播图自动播放不生效问题
    前言项目使用到swiper插件实现轮播图的功能,引入插件放上数据后,设置自动播放,但是发现没起效果,手动拖动可以解决方法安装指定版本可以安装以下版本的,设置自动播放没有......
  • vue3 父子组件通信
    1.props父组件传参不变,子组件接收: <p>{{props.abc}}</p> <p>{{props.msg}}</p> constprops=defineProps({msg:{type:String,required:......
  • 【Vue】新建Vue项目
    前提条件熟悉命令行已安装16.0或更高版本的Node.js(附上node的安装教程)步骤主要步骤如下:确定已安装node环境。使用命令新建vue项目安装依赖并启动服务器接下......
  • vue3插槽变化
    1.默认插槽还是跟以前一样 2.使用具名插槽时,子组件不变以前的父组件掉用的时候<templateslot="example"></template>现在为<templatev-slot:exam......
  • vue拖拽排序功能
    实现效果(可以拖拽排序)  实现步骤一:安装依赖npminstallvuedraggable--save二:在页面中引入importdraggablefrom"vuedraggable";components:{draggab......
  • 前端Vue2-Day49
    Vue.set方法和vm.$set方法:参数(实例对象的某一属性名,属性名,属性值)用于给实例化Vue对象的某一个属性对象动态添加子属性。不允许直接给实例化对象添加属性。即参数第一项不......
  • vue项目搭建(vue2+elementUI+less)
    装node.js然后控制台输入node-v有版本号就是成功了  如是是windows系统建议装个git,我这边习惯用命令行了按照vue和vue-clivue-cli是一个vue的脚手架   ......
  • Vue组件上使用v-model之单选框
    子组件内容:<template><div><inputtype="radio":id="valueName":value="valueName":checked="picked===valueName":picked......
  • vue 项目引入 jquery
    一、引入jquery1.方式一默认会安装最新版本jquerynpminstalljquery 2.方式二指定版本[email protected] 3.方式三在package.json文件中 ......