《Vue 后台管理的优雅华章:小型实例鉴赏》

259 阅读9分钟

《Vue 后台管理的优雅华章:小型实例鉴赏》

在当今数字化的时代,高效、便捷且美观的后台管理系统成为了各类应用和业务的核心支撑。Vue 作为一款备受青睐的前端框架,以其灵活、高效和易于开发的特性,为构建出色的后台管理系统提供了强大的助力。

路由中涉及的技术

  1. Vue Router:用于管理应用的路由,实现页面之间的导航和切换。

    • createRouter 函数用于创建路由实例。
    • createWebHistory 用于创建基于 HTML5 历史模式的路由历史记录。
    • 路由配置对象 routes 定义了不同路径对应的组件和相关元信息。
    • beforeEach 路由导航守卫用于在路由切换前进行权限检查和其他预处理。
    • afterEach 用于在路由切换完成后执行一些操作,如停止进度条。
  2. NProgress:一个用于显示页面加载进度条的库。通过 NProgress.start() 在路由切换开始时启动进度条,NProgress.done() 在切换完成时结束进度条。

  3. LocalStorage:用于本地存储数据。在这段代码中,通过 localStorage.getItem("ms_name") 获取存储的用户角色信息。

  4. ES6 模块:使用 import 和 export 语句来导入和导出模块,实现代码的模块化组织和复用。

  5. 动态导入:通过 component: () => import("../views/dashboard.vue") 这种方式动态地按需加载组件,提高应用的初始加载性能。

  6. 元数据(Meta) :在路由配置中使用 meta 对象来存储每个路由的额外信息,如页面标题和权限要求。

接下来让我们开启router之旅

import { createRouter, createWebHistory } from "vue-router";//导入路由
import Home from "../views/home.vue";
import NProgress from "nprogress";//导入nprogress组件
import "nprogress/nprogress.css";//导入nprogress组件的css样式

createWebHistory

在后台管理中,使用createWebHistorycreateWebHashHistory更好,原因主要包括以下几点:

  • URL 美观性createWebHistory创建的路由模式路径不带#号,例如http://192.168.85.1:3000/page,而createWebHashHistory创建的路由模式路径带#号,例如http://192.168.85.1:3000/#/page。因此,createWebHistory可以使 URL 更加美观和直观。
  • SEO 优化createWebHistory更有利于搜索引擎优化,因为它使用的是标准的 URL 格式。而createWebHashHistory在 SEO 方面可能会有一些限制,因为搜索引擎可能不会索引#后面的内容。
  • 服务器配置createWebHistory需要在服务器端进行额外配置,以处理直接访问路由的情况。如果没有适当的服务器配置,用户在浏览器中直接访问特定路由时,可能会得到 404 错误。而createWebHashHistory则不需要服务器端的特殊配置,因为#后面的哈希值不会被发送到服务器。

然而,createWebHistory也有一些缺点,例如在刷新页面时,如果没有相应的路由或资源,就会刷出 404 来。因此,在选择使用哪种路由模式时,需要根据具体的项目需求进行权衡。

const routes = [
  {
    path: "/",
    redirect: "/dashboard",
  },
  {
    path: "/home",
    name: "home",
    component: Home,
    children: [
      {
        path: "/dashboard",
        name: "dashboard",
        meta: {
          title: "系统首页",
          permiss: "1",
        },
        component: () => import("../views/dashboard.vue"),
      },
      {
        path: "/system-user",
        name: "user",
        meta: {
          title: "用户管理",
          permiss: "11",
        },
        component: () => import("../views/system-user.vue"),
      },
      {
        path: "/system-role",
        name: "role",
        meta: {
          title: "角色管理",
          permiss: "12",
        },
        component: () => import("../views/system-role.vue"),
      },
    ],
  },
  {
    path: "/login",
    meta: {
      title: "登录",
      noAuth: true,
    },
    component: () => import("../views/login.vue"),
  },
  {
    path: "/403",
    meta: {
      title: "403",
      noAuth: true,
    },
    component: () => import("../views/403.vue"),
  },
  {
    path: "/404",
    meta: {
      title: "404",
      noAuth: true,
    },
    component: () => import("../views/404.vue"),
  },
  {
    path: "/:path(.*)",
    redirect: "/404",
  },
];
  1. 这是路由配置的数组,其中每个对象表示一个路由。

  2. 重定向路由:

    • { path: "/", redirect: "/dashboard" }:访问根路径/时,重定向到/dashboard路径。
  3. 嵌套路由:

    • { path: "/home", name: "home", component: Home, children: [...] }/home路径对应的组件是Home,并且它还有子路由。

      • { path: "/dashboard", name: "dashboard", meta: {...}, component: () => import("../views/dashboard.vue") }/home/dashboard路径,有页面标题和权限相关的元数据。
      • { path: "/system-user", name: "user", meta: {...}, component: () => import("../views/system-user.vue") }/home/system-user路径,有相应元数据。
      • { path: "/system-role", name: "role", meta: {...}, component: () => import("../views/system-role.vue") }/home/system-role路径,有对应元数据。
  4. 登录路由:

    • { path: "/login", meta: {...}, component: () => import("../views/login.vue") }/login路径,用于登录,有相关元数据。
  5. 错误页面路由:

    • { path: "/403", meta: {...}, component: () => import("../views/403.vue") }/403路径,用于没有权限访问的情况,有相关元数据。
    • { path: "/404", meta: {...}, component: () => import("../views/404.vue") }/404路径,用于页面未找到的情况,有相关元数据。
  6. 通配符路由:

    • { path: "/:path(.*)", redirect: "/404" }:匹配任意未定义的路径,重定向到/404页面。
const router = createRouter({ history: createWebHistory(), routes, });

使用 createRouter 函数创建了一个 Vue Router 的实例 routerrouter 实例就具备了处理应用路由跳转和页面切换的能力。

router.beforeEach((to, from, next) => {
  NProgress.start();
  document.title = to.meta.title;
  const role = localStorage.getItem("ms_name") || "user";
  const permiss = {
    admin: ["11", "1", "12"],
    user: ["11", "1"],
  };
  if (to.meta.noAuth !== true && !role) {
    next("/login");
  } else if (
    typeof to.meta.permiss === "string" &&
    !permiss[role].includes(to.meta.permiss)
  ) {
    next("/403");
  } else {
    next();
  }
});

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

这段代码是 Vue Router 的导航守卫配置。

router.beforeEach 是全局前置守卫:

  • NProgress.start() :在路由跳转前启动进度条。

  • document.title = to.meta.title :根据要跳转的路由(to)的元数据(meta)中的 title 来设置页面标题。

  • 然后获取本地存储中的角色信息 role ,如果没有则默认为 user 。

  • 根据不同条件进行路由跳转控制:

    • 如果要跳转的路由需要认证(to.meta.noAuth!== true)且没有角色信息(!role),则跳转到 /login 页面。

    • 如果要跳转的路由有特定权限要求(typeof to.meta.permiss === "string"),且当前角色不具备该权限(!permiss[role].includes(to.meta.permiss)),则跳转到 /403 页面。

    • 否则,正常进行路由跳转(next())。

router.afterEach 是全局后置守卫:在路由跳转完成后,结束进度条(NProgress.done())。

export default router;

这行代码的作用是将创建和配置好的 router 实例导出,以便在其他模块中能够引入和使用这个路由实例,从而实现整个应用的路由功能。

路由总结: 路由守卫来控制权限,首先有两个角色,用户和管理员,他们权限不同,能访问的页面也不同。先在路由中设置meta: { title: "角色管理", permiss: "12", } 再在前置守卫中设置了不用的角色所能访问的路由权限 const permiss = { admin: ["11", "1", "12"], user: ["11", "1"], };,如果角色是admin,路由中的meta.permiss在admin的数组中才可访问。

组件中所涉及的技术

npm i element-plus 安装element-plus组件库

  1. Vue 3 的组合式 API:使用 script setup 语法,更简洁地定义组件的逻辑和响应式数据。

    • reactive 用于创建响应式对象。
    • ref 用于创建响应式引用。
  2. Element Plus 组件库:使用了 el-formel-form-itemel-inputel-checkbox 和 el-link 等组件来构建表单和相关元素。

  3. 路由:引入了自定义的路由配置文件,并在登录成功时使用 router.push 进行页面跳转。

  4. 本地存储(LocalStorage) :通过 localStorage.setItem 存储用户登录信息。

  5. 表单验证:定义了表单的验证规则,并在提交时进行验证。

  6. CSS 样式:使用了 CSS 样式来美化登录页面的布局和外观。

<template>
    <div class="login-bg">
        <div class="login-container">
            <header class="login-header">
                <img class="logo mr10" src="../assets/images/logo.svg" alt="">
                <div class="login-title">后台管理系统</div>
            </header>
            <el-form size="large" :model="param" :rules="rules" ref="login">
                <el-form-item prop="username">
                    <el-input v-model="param.username" placeholder="请输入用户名">
                    </el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input v-model="param.password" type="password" placeholder="请输入密码">
                    </el-input>
                </el-form-item>
                <div class="pwd-tips">
                    <el-checkbox class="pwd-checkbox" v-model="checked" label="记住密码" />
                    <el-link type="primary">忘记密码</el-link>
                </div>
                <el-button class="login-btn" type="primary" size="large" @click="submitForm(login)">登录</el-button>
                <p class="login-tips">Tips: 用户名admin 密码123456</p>
                <p class="login-text">
                    没有账号?<el-link type="primary">立即注册</el-link>
                </p>
            </el-form>
        </div>
    </div>
</template>

这段模板代码是一个登录页面的布局结构:

  • 整个页面被包裹在一个具有 login-bg 类名的 div 中。
  • 内部有一个 login-container 容器,包含登录页面的主要内容。
  • 登录头部有一个包含 logo 图片和“后台管理系统”标题的区域。
  • 主体部分是一个 el-form 表单,包含用户名和密码的输入框,以及记住密码的复选框和忘记密码的链接。
  • 底部有登录按钮、登录提示信息和注册链接。 主要是Element Plus 组件库中的表单组件和链接组件来实现具体的功能,

其中username和password,用的是reactive响应式,表单用的是ref响应式

<script setup>
import { reactive, ref } from 'vue'
import router from '../router/index.js'
const login = ref(null) // 绑定form 元素
const param = reactive({
    username: '',
    password: ''
})

const rules = {
    username: [
        {
            required: true,
            message: '请输入用户名',
            trigger: 'blur'
        }
    ],
    password: [
        {
            required: true,
            message: '请输入密码',
            trigger: 'blur'
        },
        {
            min: 6,
            message: '密码长度不能小于6位',
            trigger: 'blur'
        }
    ]
}

const checked = ref(false)

const submitForm = (formEl) => {
    formEl.validate((valid) => {
        if (valid) {
            if (param.username === 'admin' && param.password === '123456') {
                localStorage.setItem('ms_name', 'admin')
                console.log('/////')
                // router.push({ name: 'role', params: {} })
                router.push('/system-role')
            }
        } else {
            console.log('??????')
        }
    })
}

</script>

在js部分制定了rules规则,将其响应式绑定在表单上,当按下提交按钮,如果规则都规则都实现if里面内容,跳转页面。

<style setup>
.login-bg {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100vh;
    background: url(../../assets/img/login-bg.jpg) center/cover no-repeat;
}

.login-header {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 40px;
}

.logo {
    width: 35px;
}

.login-title {
    font-size: 22px;
    color: #333;
    font-weight: bold;
}

.login-container {
    width: 450px;
    border-radius: 5px;
    background: #fff;
    padding: 40px 50px 50px;
    box-sizing: border-box;
}

.pwd-tips {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 14px;
    margin: -10px 0 10px;
    color: #787878;
}

.pwd-checkbox {
    height: auto;
}

.login-btn {
    display: block;
    width: 100%;
}

.login-tips {
    font-size: 12px;
    color: #999;
}

.login-text {
    display: flex;
    align-items: center;
    margin-top: 20px;
    font-size: 14px;
    color: #787878;
}
</style>

此为css样式

总结: 这是一个基于 Vue 框架开发的应用项目。

首先,在路由配置部分,通过 createRouter 创建了基于 HTML5 历史模式的路由实例,并定义了一系列路由规则,包括重定向、主页面及其子页面、登录页面、错误页面等。同时,设置了全局的前置和后置守卫,用于处理路由跳转时的页面标题设置、权限验证和进度条控制。

接着,在登录页面组件部分,使用 Vue 3 的组合式 API 进行开发。通过 reactive 和 ref 管理数据和表单引用,定义了表单的验证规则,并实现了登录表单的提交逻辑。同时,通过样式设置了登录页面的布局和外观。

最后,在应用入口部分,使用 createApp 创建应用实例,注册了来自 element-plus 组件库的多个组件以及之前配置好的路由,最后将应用挂载到指定的 DOM 元素上,从而启动整个应用。

总的来说,这个项目构建了一个具有完善路由系统和登录功能的 Vue 应用,同时使用了组件库进行页面组件的构建,并通过合理的布局和样式设置提供了良好的用户体验。