前言
用Vue写页面时通常把一个页面作为一个组件, div
写完布局后,把模块放到相应位置。
然后用Vue Router创建路由指向这个页面组件。
除了这个方法,还能借助 Vue Router 编写页面布局,那么如何实现呢?
一、分析页面
以掘金几个页面为例,尝试命名视图控制页面布局
掘金首页
文章:别人怎样访问自己的localhost:8080?前端项目内网穿透
课程
直播
去掉信息干扰,用不同颜色表示模块,分析页面布局
从布局上看,页面是顶栏+内容的布局。根据不同URL,内容又分成了不同的列
首页:两列
文章页:三列
课程页:两列
直播页:一列
基本涵盖了博客类网站的布局类型
二、单视图布局
?以内容最多的文章页为例
主要内容分三个区域,左侧边栏、主要内容和右侧边栏
用一个router-view
布局时,代码是这样
主页面
// App.vue<template> <router-view /></template>
路由定义
// router/index.js{ path: '/post/:id', component: () => import('@/views/PostView.vue')},
页面
// views/PostView.vue<template> <div> <PostLeftSidebar /> <main>内容...</main> <PostRightSidebar /> </div></template><script setup> import PostLeftSidebar from '@/components/PostLeftSidebar' import PostRightSidebar from '@/components/PostRightSidebar'</script>
这样写没什么问题,完全可以实现效果。
但是页面始终与侧边栏始终耦合,下面通过 命名视图 把布局改到路由上,降低耦合。
三、命名视图布局
? Vue Router 命名视图 官方文档
router-view
允许定义名字,加上name
属性
<router-view name="left" />
页面中最多有3部分,所以把主页面改成三个router-view
// App.vue<template> <router-view name="LeftSidebar"/> <router-view /> <router-view name="RightSidebar"/> </template>
router-view 没有设置名字时,默认为 default
路由除了 component
属性外还有 components
属性
components 可以传对象,属性名与 router-view
的 name
一致时就能渲染到对应的 router-view
上
// router/index.js{ path: '/post/:id', components: { default: () => import('@/views/PostView.vue'), LeftSidebar: () => import('@/components/PostLeftSidebar.vue'), RightSidebar: () => import('@/components/PostRightSidebar.vue'), }},
两者关联图如下
页面上删除侧边栏的代码
// views/PostView.vue<template> <div> <main>内容...</main> </div></template>
这样就完成了页面和侧边栏解耦
修改路由后可以灵活组合页面
四、保证布局不错位
页面用 tailwindcss
编写
推荐一下 tailblocks,它提供一些完全由tailwindcss构成的模块,譬如页头、页脚、列表等等
支持多种颜色风格和响应式布局,暗黑模式,可以方便快速的实现页面
地址在这里 ? https://tailblocks.cc
尽管用了3个 router-view
,但不是所有页面都需要显示3部分,所以要保证布局不会错位
在App.vue上增加一些控制
横排:使用flex布局
最大宽度 1280px
始终居中
default
路由宽度100%
// App.vue<template> <TheHeader /> <div class="max-w-screen-xl mx-auto flex"> <RouterView name="LeftSidebar"/> <RouterView class="w-full"/> <RouterView name="RightSidebar"/> </div></template>
LeftSidebar
和 RightSidebar
的宽度让引用的组件 自身控制
比如首页的路由
default: () => import('@/views/HomeView')
RightSidebar: () => import('@/components/TheBanner')
// components/TheBanner.vue<template> <div class="w-1/4"> 宽度25% </div></template>
这样就实现了右边宽度固定,中间自适应布局,即使只有1个路由时不会偏移出错
五、页面截图
5.1 首页 /home
一共两个视图,默认和右侧边栏
{ path: '/', name: 'home', components: { default: () => import('@/views/HomeView'), RightSidebar: () => import('@/components/TheBanner') } }
5.2 文章 /post
一共三个视图,默认和左、右侧边栏
// router/index.js{ path: '/post/:id', component: () => import('@/views/PostView.vue')},0
5.3 课程 /course
一共两个视图,默认和右侧边栏
// router/index.js{ path: '/post/:id', component: () => import('@/views/PostView.vue')},1
5.4 直播 /live
只有一个视图,默认
// router/index.js{ path: '/post/:id', component: () => import('@/views/PostView.vue')},2
5.5 src目录
整体文件结构如下
// router/index.js{ path: '/post/:id', component: () => import('@/views/PostView.vue')},3
最后
? 使用命名视图能降低耦合度,但也不适用所有场景
具体项目具体分析,合适的才是最好的。
原文:https://juejin.cn/post/7099060100639227918