Vue3+Vite+Ts 项目实战 04 搭建 Layout 布局

2024-08-23 01:08

本文主要是介绍Vue3+Vite+Ts 项目实战 04 搭建 Layout 布局,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Layout 布局容器

<!-- src\layout\AppLayout.vue -->
<template><el-container><el-aside width="200px">Aside</el-aside><el-container><el-header>Header</el-header><el-main><!-- 子路由出口 --><router-view /></el-main></el-container></el-container>
</template><script setup lang="ts"></script><style scoped lang="scss">
.el-container {height: 100vh;
}
.el-header {background-color: #B3C0D1;
}
.el-aside {width: auto;background-color: #304156;
}
.el-main {background-color: #E9EEF3;
}
</style>
// src\styles\common.scss
* {margin: 0;padding: 0;
}
// src\router\index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import AppLayout from '@/layout/AppLayout.vue'const routes:RouteRecordRaw[] = [{path: '/',component: AppLayout,children: [{path: '/',name: 'home',component: () => import('@/views/home/index.vue')}]},{path: '/login',name: 'login',component: () => import('@/views/login/index.vue')}
]const router = createRouter({// history: createWebHashHistory(), // hash 路由模式history: createWebHistory(), // history 路由模式routes // 路由规则
})export default router

配置页面路由导航

初始化路由目录

创建其他几个页面文件(后面可能还会增加):

└─ product # 商品相关├─ attr # 商品规格│   └─ index.vue├─ category # 商品分类│   └─ index.vue└─ list # 商品列表└─ index.vue

配置路由:

// src\router\modules\products.ts
import { RouteRecordRaw, RouterView } from 'vue-router'const routes:RouteRecordRaw = {path: 'product',component: RouterView,children: [{path: 'list',name: 'product_list',component: () => import('@/views/product/list/index.vue')},{path: 'category',name: 'product_category',component: () => import('@/views/product/category/index.vue')},{path: 'attr',name: 'product_attr',component: () => import('@/views/product/attr/index.vue')},{path: 'reply',name: 'product_reply',component: () => import('@/views/product/reply/index.vue')}]
}export default routes
// src\router\index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import AppLayout from '@/layout/AppLayout.vue'
import productRoutes from './modules/product'const routes:RouteRecordRaw[] = [{path: '/',component: AppLayout,children: [{path: '/',name: 'home',component: () => import('@/views/home/index.vue')},productRoutes]},{path: '/login',name: 'login',component: () => import('@/views/login/index.vue')}
]const router = createRouter({// history: createWebHashHistory(), // hash 路由模式history: createWebHistory(), // history 路由模式routes // 路由规则
})export default router

菜单导航

暂时静态编写几个菜单内容:

<!-- src\layout\components\AppMenu.vue -->
<template><el-menuactive-text-color="#ffd04b"background-color="#304156"class="el-menu-vertical-demo"default-active="2"text-color="#fff"router><el-menu-item index="/"><!-- <Menu> 首字母要大写,否则会和浏览器原生的 <menu> 冲突 --><el-icon><Menu /></el-icon><span>首页</span></el-menu-item><el-sub-menu index="1"><template #title><el-icon><location /></el-icon><span>商品</span></template><el-menu-item index="/product/list"><el-icon><Menu /></el-icon><span>商品列表</span></el-menu-item><el-menu-item index="/product/category"><el-icon><Menu /></el-icon><span>商品分类</span></el-menu-item><el-menu-item index="/product/attr"><el-icon><Menu /></el-icon><span>商品规格</span></el-menu-item></el-sub-menu></el-menu>
</template><script setup lang="ts"></script><style scoped></style>
<!-- src\layout\AppLayout.vue -->
<template><el-container><el-aside width="200px"><AppMenu /></el-aside><el-container><el-header>Header</el-header><el-main><!-- 子路由出口 --><router-view /></el-main></el-container></el-container>
</template><script setup lang="ts">
import AppMenu from './AppMenu/index.vue'
</script><style scoped lang="scss">...</style>

切换侧边栏展开收起

存储侧边栏展开状态:

// src\store\index.ts
import { defineStore } from 'pinia'const useStore = defineStore('main', {state: () => ({count: 0,isCollapse: false}),getters: {doubleCount(state) {return state.count * 2}},actions: {increment() {this.count++}}
})export default useStore

创建 Header 布局组件,编写侧边栏控制按钮:

<!-- src\layout\AppHeader\index.vue -->
<template><ToggleSidebar /><!-- 面包屑 -->
</template><script setup lang="ts">
import ToggleSidebar from './ToggleSidebar.vue'
</script><style scoped lang="scss" >
i {font-size: 19px;cursor: pointer;
}
</style>
<!-- src\layout\AppHeader\ToggleSidebar.vue -->
<template><el-icon><component:is="store.isCollapse ? 'expand' : 'fold'"@click="handleCollapse"/></el-icon>
</template><script setup lang="ts">
import useStore from '@/store'const store = useStore()// 因为没有其他地方可以修改侧边栏状态
// 所以这里直接修改
const handleCollapse = () => {store.isCollapse = !store.isCollapse
}
</script><style scoped></style>

绑定侧边栏状态,加载 Header 组件,修改 el-header 样式:

<!-- src\layout\AppLayout.vue -->
<template><el-container><el-aside width="200px"><AppMenu /></el-aside><el-container><el-header><AppHeader /></el-header><el-main><!-- 子路由出口 --><router-view /></el-main></el-container></el-container>
</template><script setup lang="ts">
import AppMenu from './AppMenu/index.vue'
import AppHeader from './AppHeader/index.vue'
</script><style scoped lang="scss">
.el-container {height: 100vh;
}
.el-header {background-color: #fff;color: #333;display: flex;justify-content: space-between;align-items: center;
}
.el-aside {width: auto;background-color: #304156;
}
.el-main {background-color: #E9EEF3;
}
</style>

面包屑导航

通过路由元信息配置路由标题

// src\router\modules\products.ts
import { RouteRecordRaw, RouterView } from 'vue-router'const routes:RouteRecordRaw = {path: 'product',component: RouterView,meta: {title: '商品'},children: [{path: 'list',name: 'product_list',component: () => import('@/views/product/list/index.vue'),meta: {title: '商品列表'}},{path: 'category',name: 'product_category',component: () => import('@/views/product/category/index.vue'),meta: {title: '商品分类'}},{path: 'attr',name: 'product_attr',component: () => import('@/views/product/attr/index.vue'),meta: {title: '商品规格'}}]
}export default routes
// src\router\index.ts
...const routes:RouteRecordRaw[] = [{path: '/',component: AppLayout,children: [{path: '/',name: 'home',component: () => import('@/views/home/index.vue'),meta: {title: '首页'}},...]},...
]...

面包屑组件

<!-- src\layout\AppHeader\Breadcrumb.vue -->
<template><el-breadcrumb separator-icon="arrow-right"><el-breadcrumb-itemv-for="item in routes":key="item.path">{{ item.meta.title }}</el-breadcrumb-item></el-breadcrumb>
</template><script setup lang="ts">
import { useRouter } from 'vue-router'
import { computed } from 'vue'// 获取路由,类似 Vue2 的 this.$router
const router = useRouter()// 获取当前路由的匹配记录
const routes = computed(() => {return router.currentRoute.value.matched.filter(item => item.meta.title)
})</script><style scoped></style>

加载面包屑组件

<!-- src\layout\AppHeader\index.vue -->
<template><el-space size="large"><ToggleSidebar /><Breadcrumb /></el-space>
</template><script setup lang="ts">
import ToggleSidebar from './ToggleSidebar.vue'
import Breadcrumb from './Breadcrumb.vue'
</script><style scoped lang="scss" >
i {font-size: 19px;cursor: pointer;
}
</style>

配置路由元信息 TypeScript 支持,为了方便将自定义创建的类型声明文件放到 src/types 目录下:

// src\types\vue-router.d.ts
import 'vue-router'declare module 'vue-router' {// eslint-disable-next-line no-unused-varsinterface RouteMeta {title?: string}
}

其他

可以使用 nuxt/vue-meta(next 分支) 设置页面标题。

全屏功能

全屏 API - Web API 接口参考 | MDN

创建全屏按钮组件:

<!-- src\layout\AppHeader\FullScreen.vue -->
<template><el-icon><full-screen @click="toggleFullScreen" /></el-icon>
</template><script setup lang="ts">
const toggleFullScreen = () => {if (!document.fullscreenElement) {document.documentElement.requestFullscreen()} else {if (document.exitFullscreen) {document.exitFullscreen()}}
}
</script><style scoped></style>

加载组件

<!-- src\layout\AppHeader\index.vue -->
<template><el-space size="large"><ToggleSidebar /><Breadcrumb /></el-space><el-space size="large"><FullScreen /></el-space>
</template><script setup lang="ts">
import ToggleSidebar from './ToggleSidebar.vue'
import Breadcrumb from './Breadcrumb.vue'
import FullScreen from './FullScreen.vue'
</script><style scoped lang="scss" >
i {font-size: 19px;cursor: pointer;
}
</style>

页面加载进度条

使用 nprogress 实现页面加载进度条效果。

npm i --save nprogress
# TS 类型补充模块
npm i --save-dev @types/nprogress
// src\router\index.ts
...
import nprogress from 'nprogress'
import 'nprogress/nprogress.css'// 关闭 loading 图标
nprogress.configure({ showSpinner: false })...router.beforeEach(() => {// 开始加载进度条nprogress.start()
})router.afterEach(() => {// 结束加载进度条nprogress.done()
})export default router

注意:Vue Router v4.x 开始不建议在导航守卫中使用 next()来调用下一个导航守卫,转而改用 return 来控制,返回 false 会取消当前导航;返回一个路由地址,则会跳转到这个路由;默认路由会调用。

这篇关于Vue3+Vite+Ts 项目实战 04 搭建 Layout 布局的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1097923

相关文章

vite搭建vue3项目的搭建步骤

《vite搭建vue3项目的搭建步骤》本文主要介绍了vite搭建vue3项目的搭建步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1.确保Nodejs环境2.使用vite-cli工具3.进入项目安装依赖1.确保Nodejs环境

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

Nginx搭建前端本地预览环境的完整步骤教学

《Nginx搭建前端本地预览环境的完整步骤教学》这篇文章主要为大家详细介绍了Nginx搭建前端本地预览环境的完整步骤教学,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录项目目录结构核心配置文件:nginx.conf脚本化操作:nginx.shnpm 脚本集成总结:对前端的意义很多

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter

Vue3视频播放组件 vue3-video-play使用方式

《Vue3视频播放组件vue3-video-play使用方式》vue3-video-play是Vue3的视频播放组件,基于原生video标签开发,支持MP4和HLS流,提供全局/局部引入方式,可监听... 目录一、安装二、全局引入三、局部引入四、基本使用五、事件监听六、播放 HLS 流七、更多功能总结在 v

idea+spring boot创建项目的搭建全过程

《idea+springboot创建项目的搭建全过程》SpringBoot是Spring社区发布的一个开源项目,旨在帮助开发者快速并且更简单的构建项目,:本文主要介绍idea+springb... 目录一.idea四种搭建方式1.Javaidea命名规范2JavaWebTomcat的安装一.明确tomcat

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②