超详细!快速熟悉一个Vue3的后台管理系统及本地化部署等知识点。

2,109 阅读6分钟

在现代 Web 应用开发中,后台管理系统扮演着至关重要的角色。然而,传统的构建方式往往面临着配置繁琐、启动缓慢等问题。为了解决这些痛点,并充分利用最新的前端技术,本文将深入探讨如何使用 Vite 和 Vue 3 这一强大的组合来构建高效、易维护的后台管理系统。Vite 凭借其极速的冷启动和热更新,极大地提升了开发效率,而 Vue 3 的 Composition API 和增强的性能,则为构建复杂应用提供了坚实的基础。我们将从项目初始化开始,逐步讲解核心功能的实现,包括路由管理(使用 Vue Router)、状态管理(使用 Pinia)、UI 组件库(例如 Element Plus)的应用、以及常见的权限控制和数据表格的处理等。通过本文的学习,你将掌握使用 Vite 和 Vue 3 构建后台管理系统的基本方法和最佳实践,并能够将其应用于实际项目中,构建出高效、现代化的后台管理系统。

1.项目展示

1.登录页

登录.gif 2.用户管理页

用户管理.gif

2.技术栈

"vite": "^6.0.5"
"axios": "^1.7.9"
"element-plus": "^2.9.2"
"pinia": "^2.3.0"
"vue": "^3.5.13"
"vue-router": "^4.5.0
"less": "^4.2.1"

2.项目搭建

本次项目我们使用 vite 进行构建。
官方文档地址:cn.vitejs.dev/

image.png 前提:安装 node 环境

image.png

使用 vite 创建 vue3 脚手架项目:

image.png 1.用脚手架创建项目

npm create vite@latest

01.png 2.安装依赖

npm install

项目中没有less、axios。elementUI-plus 需要单独安装

npm install axios
npm install less
npm install element-plus --save

axios文档:www.axios-http.cn/docs/intro
less文档:lesscss.cn/ 或者 less.js.cn/usage/
element-plus文档: element-plus.org/zh-CN/
4.启动项
这里可以先看一下项目是否可以启动成功。

npm run dev

image.png 5.修改 App.vue,删除默认的 HelloWorld 组件

image.png

4.配置 Element Plus

由于刚才已经安装过elementUI组件库了,所以现在只需要配置入口文件就可以了。

image.png

5.配置路由

image.png

import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
  {
    path: '/',
    redirect: '/login',
  },
  {
    path: '/login',
    name: 'login',
    meta: {
      title: '登录',
    },
    component: () => import('../view/Login.vue'),
  },
  {
    path: '/home',
    name: '主页',
    meta: {
      title: '主页',
    },
    component: () => import('../view/Home.vue'),
    redirect: '/index',
    children: [
      {
        path: '/index',
        meta: {
          title: '首页',
        },
        component: () => import('../view/Welcome.vue'),
      },
      {
        path: '/user/list',
        meta: {
          title: '用户管理',
        },
        component: () => import('../view/user/Index.vue'),
      },
    ],
  },
]
const router = createRouter({
  history: createWebHashHistory(),
  routes,
})
// 挂载路由导航守卫:to表示将要访问的路径,from表示从哪里来,next是下一个要做的操作
router.beforeEach((to, from, next) => {
  // 修改页面 title
  if (to.meta.title) {
    document.title = '后台管理系统 - ' + to.meta.title
  }
  // 放行登录页面
  if (to.path === '/login') {
    return next()
  }
  // 获取token
  const token = sessionStorage.getItem('token')
  if (!token) return next('/login')
  return next()
})

// 导出路由
export default router

6.配置axios

首先配置axios的请求拦截与响应拦截

image.png

import axios from 'axios'
import { ElMessage } from 'element-plus'
// 1. 创建axios实例
const instance = axios.create({
  // 接口
  baseURL: '/api',
  // 超时时间
  timeout: 50000,
})
// 2.请求拦截
instance.interceptors.request.use(
  (config) => {
    let token = sessionStorage.getItem('token')
    if (token) {
      config.headers['token'] = token
    }
    return config
  },
  (error) => {
    //  请求发生错误,抛出异常
    Promise.reject(error)
  },
)

// 3.响应拦截
instance.interceptors.response.use(
  (res) => {
    return res
  },
  (error) => {
    if (error && error.response) {
      const status = error.response.status
      switch (status) {
        case 400:
          ElMessage.error('请求错误')
          break
        case 401:
          ElMessage.error('未授权,请重新登录')
          break
        case 403:
          ElMessage.error('拒绝访问')
          break
        case 404:
          ElMessage.error('请求错误,未找到相应的资源')
          break
        case 408:
          ElMessage.error('请求超时')
          break
        case 500:
          ElMessage.error('服务器内部错误')
          break
        case 501:
          ElMessage.error('网络未实现')
          break
        case 502:
          ElMessage.error('网络错误')
          break
        case 503:
          ElMessage.error('服务不可用')
          break
        case 504:
          ElMessage.error('网络超时')
          break
        case 505:
          ElMessage.error('HTTP版本不支持该请求')
          break
        default:
          ElMessage.error('请求失败')
      }
    } else {
      if (JSON.stringify(error).includes('timeout')) {
        ElMessage.error('服务器响应超时,请刷新页面')
      }
      ElMessage.error('连接服务器失败')
    }
    return Promise.reject(error)
  },
)
// 4.导出 axios 实例
export default instance

封装请求组件

image.png

import instance from './axios'

const post = (url, data) => {
  return new Promise((resolve, reject) => {
    instance
      .post(url, data)
      .then((res) => {
        resolve(res)
      })
      .catch((err) => {
        reject(err)
      })
  })
}
const get = (url, data) => {
  return new Promise((resolve, reject) => {
    instance
      .get(url, { params: data })
      .then((res) => {
        resolve(res)
      })
      .catch((err) => {
        reject(err)
      })
  })
}
const put = (url, data) => {
  return new Promise((resolve, reject) => {
    instance
      .put(url, data)
      .then((res) => {
        resolve(res)
      })
      .catch((err) => {
        reject(err)
      })
  })
}

const del = (url, data) => {
  return new Promise((resolve, reject) => {
    instance
      .delete(url, { data })
      .then((res) => {
        resolve(res)
      })
      .catch((err) => {
        reject(err)
      })
  })
}

export default {
  post,
  get,
  put,
  del,
}

封装接口文件

image.png

import http from '../utils/http/http.js'

const login = (data) => {
    return http.post("/user/login", data);
};
const getUserList = (data) => {
    return http.get("/user/list", data);
};
const saveUser = (data) => {
    return http.post("/user/save", data);
};
const delUser = (data) => {
    return http.del("/user/delete", data);
};
const getUserDetail = (data) => {
    return http.get("/user/detail", data);
};
export default {
    login, getUserList, saveUser, delUser, getUserDetail
}

7.接口服务

手搓接口服务方便开发测试。 使用方法还是老样子。

npm install
// 需要注意的是此服务我是放在webscoketData文件夹内的,所以需要在webscoketData内运行npm install
//然后就是启动服务
node app.js

image.png

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

// 使用 bodyParser 解析 JSON 数据
app.use(bodyParser.json());

// 模拟的数据库
let users = [
  { id: 1, username: 'john', email: 'john@example.com' },
  { id: 2, username: 'jane', email: 'jane@example.com' },
];

// 登录接口
const login = (data) => {
  // 简单的登录模拟,检查用户名和密码
  if (data.username === 'admin' && data.password === '1234') {
    return { success: true, message: 'Login successful!' };
  }
  return { success: false, message: 'Invalid username or password' };
};

// 获取用户列表接口
const getUserList = () => {
  return users;
};

// 获取单个用户详情接口
const getUserDetail = (id) => {
  return users.find((user) => user.id === id);
};

// 保存用户接口
const saveUser = (data) => {
  const newUser = { id: users.length + 1, ...data };
  users.push(newUser);
  return newUser;
};

// 删除用户接口
const delUser = (id) => {
  users = users.filter((user) => user.id !== id);
  return { success: true, message: 'User deleted successfully!' };
};

// POST 请求:登录接口
app.post('/user/login', (req, res) => {
  const response = login(req.body);
  res.json(response);
});

// GET 请求:获取用户列表
app.get('/user/list', (req, res) => {
  const response = getUserList();
  res.json(response);
});

// POST 请求:保存用户
app.post('/user/save', (req, res) => {
  const response = saveUser(req.body);
  res.json(response);
});

// DELETE 请求:删除用户
app.delete('/user/delete', (req, res) => {
  const { id } = req.body;
  const response = delUser(id);
  res.json(response);
});

// GET 请求:获取用户详情
app.get('/user/detail', (req, res) => {
  const { id } = req.query;
  const response = getUserDetail(Number(id));
  if (response) {
    res.json(response);
  } else {
    res.status(404).json({ message: 'User not found' });
  }
});

// 启动服务器
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

8.配置vite的代理及less打包插件(配置完成后重启项目)

image.png

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'

// https://vite.dev/config/
export default defineConfig({
  plugins: [vue(), vueDevTools()],
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true, //使用表达式的话必须开启
      },
    },
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
  server: {
    proxy: {
      '/api': {
        // 匹配以 /api 开头的请求路径
        target: 'http://localhost:3000', // 目标服务器地址
        changeOrigin: true, // 必须设置,用于欺骗浏览器,修改 Origin
        rewrite: (path) => path.replace(/^\/api/, ''), // 可选,重写路径
      },
    },
  },
})

9.登录页的

从这里还是细讲一下用到的知识点,这个页面主要用到的是Layout 布局form表单路由的跳转等。

image.png

10.后台主页

主页父组件

image.png aside区代码

image.png header区代码

image.png Main区代码

image.png

11.本地打包及部署

本地化部署跳不过nginx的配置及启动,先手搓一个快速启动脚本

image.png image.png nginx的配置文件及打包文件 打包命令

image.png

npm run build

打包后的文件位置

image.png

image.png

image.png

12.总结

通过完成这个项目,你将对 Vue 3 的 Composition API、路由、API 交互等关键概念有更深入的理解,并提升你的前端开发能力。同时,你也可以将这个项目作为你作品集的一部分,展示你的技术水平。

项目地址 https://gitee.com/yilag/vite-vue3-project.git