从零开始vue3+vite+ts+pinia+router4后台管理(2)-页面布局

博客围绕从零开始搭建vue3+vite+ts+pinia+router4后台管理项目的页面布局展开。介绍了常见的两种页面布局,还讲解了vue3中is的用法,可通过is实现动态组件来切换后台页面布局,在store文件夹下创建settings.ts控制全局设置。

从零开始vue3+vite+ts+pinia+router4后台管理(2)-页面布局

项目地址

项目git地址

页面布局

常见的页面布局有两种

image-20231007093219490

image-20231007093254005

第二中可以让表格铺满屏幕 展示更多的数据 ,但是两种到想要怎么办?今天我们就来实现

如下图

3a1fa454-7bdb-468d-a60a-45395516bdd3

vue3中is的用法

1.限制元素 ,下面是官网的解释

501988f9603f4c588a801f36d9cca939

  1. 用is来实现动态组件 来实现我们后台页面布局切换

    store/settings.ts 在store文件夹下面创造一个settings.ts来控制一些全局的设置,layoutMode就是控制布局变量的参数

    import {defineStore} from 'pinia'
    import {getToken,setToken} from "@/utils/storage.ts";
    export const useSettingsStore = defineStore('settings', {
        id: 'settings', // id必填,且需要唯一
        state: () => {
            return {
                menuCollapse: false,//// 是否水平折叠收起菜单
                // 布局方式 Classic 经典布局  Streamline 单行布局
                layoutMode: getToken('layoutMode')?getToken('layoutMode'):'Classic'
            }
        },
        actions: {
            changeSetting({ key, value }) {
                //改变全局变量的方法
                this[key] = value
                setToken(key, value)
            },
        }
    })
    

    页面布局用is实现动态组件

    <template>
      <div class="common-layout">
        <component :is="layoutMode" />
      </div>
    </template>
    <script setup lang="ts">
    import Classic from '@/layout/classic/index.vue'
    import Streamline from '@/layout/streamline/index.vue'
    import {useSettingsStore} from '@/store/settings'
    const settingsStore = useSettingsStore()
    import {computed} from 'vue'
    const layoutEnum = {
      Classic: Classic,//经典布局
      Streamline: Streamline//单栏布局
    }
    const layoutMode = computed(() => layoutEnum[settingsStore.layoutMode])
    </script>
    

    切换页面布局的时候改变settingsStore.layoutMode值就行

### Vue3 + Vite + Pinia 后台管理系统中 vue-router 的封装示例 在构建基于 Vue3Vite后台管理系统时,`vue-router` 的封装是一个关键步骤。通过封装路由,可以实现动态路由加载、权限校验、路由拦截等功能。以下是一个完整的 `vue-router` 封装示例。 #### 1. 路由配置文件结构 通常将路由配置文件存放在 `src/router` 目录下。以下是目录结构的示例: ``` src/ ├── router/ │ ├── index.js // 路由入口 │ ├── routes.js // 路由定义 │ ├── guards.js // 路由守卫 │ └── dynamicRoutes.js // 动态路由 ``` #### 2. 路由定义 (`routes.js`) 在 `routes.js` 中定义静态路由和动态路由的模板。 ```javascript // src/router/routes.js export const constantRoutes = [ { path: &#39;/login&#39;, name: &#39;Login&#39;, component: () => import(&#39;@/views/login/Login.vue&#39;), meta: { title: &#39;登录&#39;, hidden: true }, }, { path: &#39;/&#39;, redirect: &#39;/dashboard&#39;, component: () => import(&#39;@/layouts/index.vue&#39;), children: [ { path: &#39;dashboard&#39;, name: &#39;Dashboard&#39;, component: () => import(&#39;@/views/dashboard/index.vue&#39;), meta: { title: &#39;仪表盘&#39;, icon: &#39;dashboard&#39;, roles: [&#39;admin&#39;, &#39;editor&#39;] }, }, ], }, ]; export const asyncRoutes = [ { path: &#39;/system&#39;, name: &#39;System&#39;, component: () => import(&#39;@/layouts/index.vue&#39;), meta: { title: &#39;系统管理&#39;, icon: &#39;setting&#39;, roles: [&#39;admin&#39;] }, children: [ { path: &#39;user&#39;, name: &#39;User&#39;, component: () => import(&#39;@/views/system/user/index.vue&#39;), meta: { title: &#39;用户管理&#39;, icon: &#39;user&#39; }, }, { path: &#39;role&#39;, name: &#39;Role&#39;, component: () => import(&#39;@/views/system/role/index.vue&#39;), meta: { title: &#39;角色管理&#39;, icon: &#39;team&#39; }, }, ], }, ]; ``` #### 3. 路由初始化与动态加载 (`index.js`) 在 `index.js` 中初始化路由,并实现动态路由加载功能。 ```javascript // src/router/index.js import { createRouter, createWebHistory } from &#39;vue-router&#39;; import { constantRoutes, asyncRoutes } from &#39;./routes&#39;; import { filterAsyncRoutes } from &#39;./dynamicRoutes&#39;; const router = createRouter({ history: createWebHistory(), routes: constantRoutes, }); // 动态添加路由 export function setupRoutes(store) { return new Promise((resolve) => { if (store.getters.isAddRouters) { resolve(); } else { const accessedRoutes = filterAsyncRoutes(asyncRoutes, store.getters.roles); accessedRoutes.forEach((route) => { router.addRoute(route); }); store.commit(&#39;SET_IS_ADD_ROUTERS&#39;, true); resolve(); } }); } export default router; ``` #### 4. 动态路由过滤 (`dynamicRoutes.js`) 根据用户权限过滤动态路由。 ```javascript // src/router/dynamicRoutes.js export function filterAsyncRoutes(routes, roles) { const res = []; routes.forEach((route) => { const tmp = { ...route }; if (hasPermission(tmp.meta?.roles, roles)) { if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, roles); } res.push(tmp); } }); return res; function hasPermission(roles, userRoles) { if (!roles || roles.length === 0) return true; return roles.some((role) => userRoles.includes(role)); } } ``` #### 5. 路由守卫 (`guards.js`) 实现全局前置守卫,用于权限校验和页面跳转。 ```javascript // src/router/guards.js import router from &#39;./index&#39;; import store from &#39;@/store&#39;; router.beforeEach(async (to, from, next) => { const token = store.getters.token; if (to.path === &#39;/login&#39;) { if (!token) { next(); } else { next({ path: &#39;/&#39; }); } } else { if (token) { if (!store.getters.roles.length) { await store.dispatch(&#39;GetInfo&#39;); await setupRoutes(store); // 动态加载路由 } next(); } else { next({ path: &#39;/login&#39;, query: { redirect: to.fullPath } }); } } }); ``` #### 6. 在主应用中注册路由 在 `main.ts` 或 `main.js` 中引入并使用路由模块。 ```javascript // main.js import { createApp } from &#39;vue&#39;; import App from &#39;./App.vue&#39;; import router from &#39;./router&#39;; import store from &#39;./store&#39;; const app = createApp(App); app.use(router).use(store).mount(&#39;#app&#39;); ``` #### 7. 示例代码片段 以下是封装后的路由组件使用示例: ```vue <!-- src/App.vue --> <template> <div id="app"> <router-view /> </div> </template> <script> export default { name: &#39;App&#39;, }; </script> ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值