本文将介绍使用Vue 3创建多重布局系统的3种方法。
微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩
布局是中大型网站或应用程序的基础。
假设你正在创建一个包含主页、营销页面和应用程序页面的Web应用程序。
-
你希望主页具有独特的布局
-
你希望营销页面具有侧边栏或其他内容
-
你希望应用程序页面具有提示消息、错误消息、特定的页眉、导航等常见元素
并且不想为每个页面都重复所有的工作。
与Nuxt不同,Vue 3没有原生的布局系统,但不用担心,本文将向你展示3种简单的方法来实现这一目标。
⚠️ 如果想知道本文认为最好的方法,请跳到第三种方法,但如果想成为一个更好的开发者,请阅读所有的方法。
1.将布局作为常规组件导入以创建布局系统
这是创建布局系统最简单的方法,但灵活性较低。
为了简化解释,本文将按照上面的例子继续。
计划有5个页面:
-
主页(将具有特定的布局)
-
关于和联系方式(将具有营销布局)
-
Inside1和Inside2(将具有应用程序布局)
本文将创建一个“layouts”
文件夹,并在其中创建3个包含插槽的布局组件。
布局文件夹
布局组件示例
然后,只需像这样在每个页面组件中导入所需要的布局:
主页组件
该方法存在两个主要问题:
-
需要在每个页面中导入布局。
当然,也可以将这些组件设置为全局组件,但仍然需要手动封装每个页面的内容。
-
即使下一个路由使用的是相同的布局,布局也会在每次路由变化时被卸载和销毁。
这会产生一些性能影响,但真正的问题是,即使它们使用相同的布局,也无法在一个路由与另一个路由之间保持状态。
但在某些情况下,这可能正是你想要的。
下一种方法将利用Vue Router和动态组件。
2.使用Vue Router、路由的meta
属性和动态组件创建布局系统
为了避免在每个页面中都导入布局,本文可以在路由器中一次性导入布局,并为每个路由设置关联的布局。
【meta属性】:https://router.vuejs.org/guide/advanced/meta.html#route-meta-fields
路由器和路由文件
如图所示,直接将每个布局组件对象与每个路由的meta
属性关联起来。本文只导入了所有的布局一次。
为了避免布局被卸载和销毁,本文将把布局放在页面之上,而不是页面内部。
App.vue文件
为了将布局放在页面之上,本文在App.vue组件中创建了一个动态组件。
【动态组件】:https://vuejs.org/guide/essentials/component-basics.html#dynamic-components
动态组件可以使用以下任一选项:
-
组件定义
-
一个HTML标签的字符串或一个本地/全局组件名称。
在模板中,本文可以使用$route
访问当前路由,并在每个路由上都可以访问其meta
属性,这意味着我们可以访问先前设置的布局组件对象。
如果某个路由的meta
对象上没有layout
属性,就会回退到使用一个字符串来使用DIV
标签。
这样就完成了。
本文只导入了布局一次,不需要在每个页面中都导入布局,甚至不需要对布局进行包装。现在,当从具有相同布局的两个路由之间导航时,不会遇到性能问题,并且可以保持状态。
因此,主页组件现在看起来是这样的:
使用第二种方法时的主页组件
不再需要包装任何内容;一切问题都在App.vue中的<router-view>
周围处理,它代表了每个页面在路由变化时的情况。
这种方法适用于大多数情况,但有一个问题:
布局只有在路由变化时才会改变。
如果需要在不更改路由的情况下动态更改布局,这种方法将不起作用。
只有在少数情况下,可能想动态更改布局,但这种情况也可能会发生。
示例:
-
可能是在一定时间后显示锁定的页面
-
可能是显示离线页面
-
可能是显示错误页面
这些示例可以通过全屏模式系统来实现,但模式可以通过控制台轻松从DOM
中删除。
下一种方法将利用Vue的响应性和提供/注入系统。
3.使用ShallowRef、Provide、Inject和Vue Router的afterEach
钩子创建布局系统
为了能够在任何地方而不仅仅在路由发生变化时改变布局,需要在整个应用程序中共享布局的状态。
可以使用Vuex或Pinia来实现这一点,但在这里本文将保持简单。
本文将使用Vue的本机响应性系统与组合API。
以下是具体步骤:
-
在App.vue中,本文将创建一个布局常量,其中包含一个
shallowRef
来保存当前布局组件。 -
在另一个单独的文件中,本文将创建一个包含键/值对的对象,其中包含每个布局的名称和它的组件。
-
在App.vue或其他地方,我们将使用路由器的
afterEach
钩子监听每次路由变化,以动态更改当前布局。 -
在App.vue中,我们将提供布局常量给其后代,以便App.vue树中的任何组件都可以通过注入布局常量来更改其值。
-
在路由中,我们将把
meta
上的每个布局属性更改为仅包含要选择的布局名称的字符串。
这就是第二步,一个包含所有布局并以对象形式展示的文件:
layouts.js是唯一导入布局的文件
现在还可以将路由中的meta
更改为字符串,因为它们将被映射到上面的对象中:
路由器和路由文件
现在,让我们把所有这些粘合在一起。
App.vue使用动态组件并将布局提供给其后代
为什么本文要使用shallowRef
而不是ref
?
ref
会使基本值和所有嵌套值都具有响应性,但shallowRef
仅使基本值具有响应性。
因为存储的是一个组件,它是一个具有许多嵌套值的复杂对象,所以使用ref
会导致性能问题。
使用ref
也是不必要的,因为我们只需要知道整个组件何时发生了变化,而不是嵌套值何时发生了变化。
现在,在任何地方都可以在路由器之外动态更改布局了。
下面是一个“主页”的例子,点击一下就能改变布局。
Home.vue使用inject来访问布局的响应式状态
由此可见,现在可以注入和访问布局的状态,并将其更改为想要的任何组件。得益于反应性,它将在App.vue中动态更改组件。
如前所述,也可以使用Vuex或Pinia来实现共享状态实现相同的效果,但对于大多数场景来说,这已经足够了。
推荐书单
IT BOOK 多得(点击查看5折活动书单)https://u.jd.com/psx2y1M
《Vue.js 3企业级项目开发实战(微课视频版)》
本书是一本实用性很强的Vue.js 3实战项目书。书中结合实际项目场景,构建了一个完整的企业级应用。全书共分13章,内容包含项目概述、Vue3项目管理、登录管理、后台主框架、图库管理、管理员管理、用户管理、商品管理、订单管理、优惠券管理、商品评论管理、分销管理和公告管理,并且讲解了这些模块的实际应用方法。同时,本书还介绍了如何使用Vite、Axios、Vue Router、Vuex等流行工具和库,以提高开发效率、提升用户体验。
《Vue.js 3企业级项目开发实战(微课视频版)》https://item.jd.com/14140678.html
精彩回顾
微信搜索关注《Python学研大本营》,加入读者群
访问【IT今日热榜】,发现每日技术热点