Vue3-后台管理系统

目录

一、完成项目历程

1、构建项目

2、项目的自定义选项

3、 封装组件

4、配置对应页面的路由

5、从后端调接口的方式

二、引入Element Plus、Echarts、国际化组件

1、Element Plus安装

2、Echarts安装

 3、国际化

 三、介绍项目以及展示

1、项目是基于Vue3、Element Plus、Ts、vite完成等完成

2、总共分10多个页面的一个后端管理系统

3、页面展示效果


一、完成项目历程

1、构建项目

npm create vite 项目名

2、项目的自定义选项

3、 封装组件

3.1主页面写在compoent文件里

3.2子页面写在view文件里

4、配置对应页面的路由

在router文件 index.ts文件里

import { createRouter, createWebHistory } from 'vue-router'
import LoginView from '../components/LoginView.vue'
import BackstageView from '@/components/BackstageView.vue'
import StageHomePage from '@/views/StageHomePage.vue'
import OrderManage from '@/views/OrderManage.vue'
import ProductList from '@/views/ProductList.vue'
import ProductAdd from '@/views/ProductAdd.vue'
import ProductClass from '@/views/ProductClass.vue'
import ShopManage from '@/views/ShopManage.vue'
import AccountList from '@/views/AccountList.vue'
import AccountAdd from '@/views/AccountAdd.vue'
import AccountCenter from '@/views/AccountCenter.vue'
import AccountUpdatePwd from '@/views/AccountUpdatePwd.vue'
import GoodsStats from '@/views/GoodsStats.vue'
import OrderStats from '@/views/OrderStats.vue'

const routes = [
  {
    path: '/',
    component: LoginView,
  },
  {
    path: '/login',
    component: LoginView,
    meta: { title: '登录页' },
  },
  {
    path: '/backstage',
    component: BackstageView,
    children: [
      //后端首页
      {
        path: '/home',
        component: StageHomePage,
        meta: { title: '后台首页' , role:['super','normal']},
      },
      //订单管理的路由
      {
        path: '/order',
        component: OrderManage,
        meta: { title: '后台首页' , role:['super','normal']},

      },
      //订单编辑
      {
        path: '/edit',
        name: 'edit',
        meta: { title: '后台首页' , role:['super']},
        component: () => import('@/views/OrderEdit.vue'),
      },
      //商品管理
      {
        path: '/product/list',
        component: ProductList,
        meta: { title: '后台首页' , role:['super','normal']},
      },
      {
        path: '/product/add',
        component: ProductAdd,
        meta: { title: '后台首页' , role:['super']},
      },
      {
        path: '/product/class',
        component: ProductClass,
        meta: { title: '后台首页' , role:['super','normal']},
      },
      //店铺管理
      {
        path: '/shop',
        component: ShopManage,
        meta: { title: '后台首页' , role:['super','normal']},
      },
      //账号管理
      {
        path: '/user/list',
        component: AccountList,
        meta: { title: '后台首页' , role:['super','normal']},
      },

      {
        path: '/user/add',
        component: AccountAdd,
        meta: { title: '后台首页' , role:['super','normal']},

      },
      {
        path: '/user/center',
        component: AccountCenter,
        meta: { title: '后台首页' , role:['super','normal']},

      },
      {
        path: '/user/updatepwd',
        component: AccountUpdatePwd,
        meta: { title: '后台首页' , role:['super','normal']},

      },
      //销售统计
      {
        path: '/goods/stats',
        component: GoodsStats,
        meta: { title: '后台首页' , role:['super']},
      },
      {
        path: '/order/stats',
        component: OrderStats,
        meta: { title: '后台首页' , role:['super']},
      },
    ],
  },
]

//递归控制权限路由
function AccessRoutes(routes: any[]) {
  return routes.filter((item: { meta: { role: string[] }; children: any[] }) => {
    if (item.meta?.role) {
      if (item.meta.role[0] === 'normal') {
        if (item.children) {
          console.log(item); //一级 把符合条件的返回出去
          item.children = item.children.filter(item1 => {
            if (child.meta?.role) {
              if (item1.meta.role[0] === 'normal') {
                // 递归调用处理三级路由
                if (item1.children) {
                  item1.children = AccessRoutes(item1.children);
                }
                console.log(item1);
                return true;
              } else {
                return false;
              }
            } else {
              return false;
            }
          })
        }
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  })
}

console.log(AccessRoutes(routes));

const router = createRouter({
  history: createWebHistory(),
  routes,
})

export default router

5、从后端调接口的方式

5.1使用封装axios

新建api/users/index.ts

import request from '@/utils/request'
import { ElMessage } from 'element-plus'
/**
 * 登录接口异步方法
 * @param data 请求参数
 * @returns
 */
export const fetchLogin = async (data: any) => {
  // 在这里可以写一些其它的逻辑,比如(对请求参数做一些特殊处理)
  const res = await request.post('/users/checkLogin', data)
  if (res.code === 0) {
    // 成功的提示
    ElMessage.success(res.msg)
  } else {
    // 失败的提示
    ElMessage.error('失败')
  }
  return res
}

//订单接口的方法
export const fetchOrderList = async (data: any) => {
  const res1 = await request.get('/order/list', data)
  return res1
}

//订单详情接口方法
export const fetchOrderdetail = async (data: any) => {
  const res5 = await request.get('/order/detail', data)
  return res5
}

//订单修改接口方法
export const fetchOrderdedit = async (data: any) => {
  const res6 = await request.post('/order/edit', data)
  return res6
}

//商品列表接口方法
export const fetchGoodList = async (data: any) => {
  const res2 = await request.get('/goods/list', data)
  return res2
}

//商品修改接口方法
export const fetchGoodedit = async (data: any) => {
  const res3 = await request.post('/goods/edit', data)
  return res3
}

//删除商品接口
export const fetchGooddel = async (data: any) => {
  const res3 = await request.get('/goods/del', data)
  return res3
}

//添加商品接口
export const fetchGoodadd = async (data: any) => {
  const res4 = await request.post('/goods/add', data)
  return res4
}

//商品分类接口
export const fetchGoodclass = async (data: any) => {
  const res7 = await request.get('/goods/catelist', data)
  return res7
}

//商品分类修改接口
export const fetchGoodeditcate = async (data: any) => {
  const res8 = await request.post('/goods/editcate', data)
  return res8
}

//商品分类删除接口

export const fetchGoodeddelcate = async (data: any) => {
  const res9 = await request.get('/goods/delcate', data)
  return res9
}

//商品分类添加接口
export const fetchGoodaddcate = async (data: any) => {
  const res9 = await request.post('/goods/addcate', data)
  return res9
}

//店铺详情接口 get
export const fetchShopinfo = async (data: any) => {
  const res9 = await request.get('/shop/info', data)
  return res9
}

//店铺修改接口
export const fetchShopedit = async (data: any) => {
  const res10 = await request.post('/shop/edit', data)
  return res10
}

//账号列表接口
export const fetchUserlist = async (data: any) => {
  const res11 = await request.get('/users/list', data)
  return res11
}

//账号添加接口 (account pwd userGroup)
export const fetchUseradd = async (data: any) => {
  const res10 = await request.post('/users/add', data)
  return res10
}

//账号批量删除 (ids)
export const fetchUsersdel = async (data: any) => {
  const res10 = await request.get('/users/batchdel', data)
  return res10
}

//账号删除 (id)
export const fetchUserdel = async (data: any) => {
  const res10 = await request.get('/users/del', data)
  return res10
}

//账号修改
export const fetchUseredit = async (data: any) => {
  const res11 = await request.post('/users/edit', data)
  return res11
}

//核对账号密码
export const fetchUsercheckoldpwd = async (data: any) => {
  const res11 = await request.get('/users/checkoldpwd', data)
  return res11
}

//导出账号
export const fetchUserexport = async (data: any) => {
  const res11 = await request.get('/users/export', data)
  return res11
}

//密码修改
export const fetchUsereditpwd = async (data: any) => {
  const res11 = await request.post('/users/editpwd', data)
  return res11
}

//首页报表接口
export const fetchOedertotaldata = async (data: any) => {
  const res12 = await request.get('/order/totaldata', data)
  return res12
}

//订单报表接口
//http://127.0.0.1:5000/order/ordertotal
export const fetchOrdertotal = async (data: any) => {
  const res13 = await request.get('/order/ordertotal', data)
  return res13
}

//商品报表接口
export const fetchGoodstotal = async (data: any) => {
  const res13 = await request.get('/goods/goodstotal', data)
  return res13
}

//账号信息  http://127.0.0.1:5000/users/info
export const fetchUsersinfo = async (data: any) => {
  const res13 = await request.get('/users/info', data)
  return res13
}

//修改头像
export const fetchUseravataredit = async (data: any) => {
  const res13 = await request.get('/users/avataredit', data)
  return res13
}


 新建utils/request.ts

import axios from 'axios'
import qs from 'qs'

// 创建axios的实例
const instance = axios.create({
  baseURL: 'http://127.0.0.1:5000', // 请求的基路径
  timeout: 5000, // 请求超时时间
})
// 拦截器,对请求和响应做统一处理
// 请求拦截器:对前端的所有请求做统一处理,比如统一给所有请求添加请求头
instance.interceptors.request.use(
  (config: any) => {
    // 对所有请求做统一处理(给鉴权接口添加鉴权字段)
    const token = JSON.parse(localStorage.getItem('t_k')!)
    // console.log(token);

    if (token) {
      config.headers.Authorization = token
    }
    return config
  },
  (err) => {
    console.error(err)
  },
)

// 响应拦截器:对后端的所有响应结果做统一处理,比如异常处理
instance.interceptors.response.use(
  (response: any) => {
    // TODO: 在这里判断接口异常处理逻辑(比如token失效后跳转到登录页)
    // console.log(response)
    return response.data
  },
  (err) => {
    // TODO: 在这里判断接口网络异常处理逻辑(比如网络超时、网络错误)
    console.error(err)
  },
)

// 创建基于restful接口规范的异步请求方法
const get = async (url: string, params: any = {}) => {
  return await instance.get(url, { params })
}
/**
 * post请求方法
 * @param url 请求地址,eg:/users/list
 * @param data 请求参数,eg:{ account: '', password: '' }
 * @returns
 */
const post = async (url: string, data: any): Promise<any> => {
  return await instance.post(url, qs.stringify(data))
}
const put = () => {}
const del = () => {}

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

5.2在组件中使用

//首先import引入调对应接口的方法

//登录的接口
import { fetchLogin } from '@/api/users';

async function login() {
  try {
    const res = await fetchLogin({
      account: username.value,
      password: password.value,
    });

    console.log('登录的信息', res);
  } catch (error) {
    console.log('报错', error);
  }
}

二、引入Element Plus、Echarts、国际化组件

Element Puls官网icon-default.png?t=O83Ahttps://element-plus-docs.bklab.cn/zh-CN/guide/quickstart.html

1、Element Plus安装

npm install element-plus --save

1.2、全局引入

import { createApp } from 'vue';
import App from './App.vue';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';

const app = createApp(App);
app.use(ElementPlus);
app.mount('#app');

1.3、vite配置

// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

 1.4、测试使用

//引入
import {
  Check,
  Delete,
  Edit,
  Message,
  Search,
  Star,
} from '@element-plus/icons-vue'


<el-button>Default</el-button>

2、Echarts安装

2.2.1、安装

npm install echarts --save

2.2.2、全局引入

import { createApp } from 'vue';
import App from './App.vue';
import * as echarts from 'echarts';

const app = createApp(App);
app.config.globalProperties.$echarts = echarts;
app.mount('#app');

2.2.3、组件中使用

<template>
  <div ref="chartDom" style="width: 600px; height: 400px;"></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import * as echarts from 'echarts';

const chartDom = ref(null);
let chartInstance = null;

onMounted(async () => {
  await nextTick();
  chartInstance = echarts.init(chartDom.value);
  const option = {
    title: { text: 'ECharts 示例图表' },
    tooltip: {},
    xAxis: { data: ["类别1", "类别2", "类别3", "类别4", "类别5"] },
    yAxis: {},
    series: [{ name: '数据系列', type: 'line', data: [120, 200, 150, 80, 70] }]
  };
  chartInstance.setOption(option);
});

onUnmounted(() => {
  if (chartInstance != null && chartInstance.dispose) {
    chartInstance.dispose();
  }
});
</script>

 3、国际化

i18n官方文档icon-default.png?t=O83Ahttps://kazupon.github.io/vue-i18n/zh/introduction.html

  1. 安装vue-i18n: 使用npm或yarn来安装vue-i18n。对于Vue 3项目,确保安装的是9.x版本。

    npm install vue-i18n@9 --save
    # 或者
    yarn add vue-i18n@9
  2. 定义语言包: 在项目中创建一个locales文件夹,用于存放不同语言的资源文件。例如,创建en.jszh.js分别存放英文和中文的语言资源。

    // locales/en.js
    export default {
      message: {
        hello: 'Hello World!'
      }
    };
    
    // locales/zh.js
    export default {
      message: {
        hello: '你好,世界!'
      }
    };
  3. 创建i18n实例: 在main.js或单独的配置文件中创建vue-i18n实例,并配置语言资源和默认语言。

    import { createApp } from 'vue';
    import App from './App.vue';
    import { createI18n } from 'vue-i18n';
    import enUS from './locales/en-US.json';
    import zhCN from './locales/zh-CN.json';
    
    const i18n = createI18n({
      locale: 'zh-CN', // 默认语言
      fallbackLocale: 'en-US', // 备用语言
      messages: {
        'zh-CN': zhCN,
        'en-US': enUS
      }
    });
    
    const app = createApp(App);
    app.use(i18n);
    app.mount('#app');
  4. 在组件中使用: 在组件中使用国际化文本非常简单,只需使用$t方法。

    <template>
      <div>
        <p>{{ $t('message.hello') }}</p>
      </div>
    </template>
  5. 动态切换语言: 你可以通过修改i18n.global.locale来动态切换语言。

    methods: {
      changeLanguage(newLocale) {
        this.$i18n.locale = newLocale;
      }
    }

 三、介绍项目以及展示

1、项目是基于Vue3、Element Plus、Ts、vite完成等完成

2、总共分10多个页面的一个后端管理系统

3、页面展示效果

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921700.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C0030.Clion中运行提示Process finished with exit code -1073741515 (0xC0000135)解决办法

1.错误提示 2.解决办法 添加环境变量完成之后&#xff0c;重启Clion软件&#xff0c;然后就可以正常调用由mingw编译的opencv库了。

【es6进阶】vue3中的数据劫持的最新实现方案的proxy的详解

vuejs中实现数据的劫持,v2中使用的是Object.defineProperty()来实现的&#xff0c;在大版本v3中彻底重写了这部分&#xff0c;使用了proxy这个数据代理的方式&#xff0c;来修复了v2中对数组和对象的劫持的遗留问题。 proxy是什么 Proxy 用于修改某些操作的默认行为&#xff0…

Python浪漫之画明亮的月亮

目录 1、效果展示 2、完整版代码 1、效果展示 2、完整版代码 import turtledef draw_moon():# 设置画布turtle.bgcolor("black") # 背景颜色为黑色turtle.speed(10) # 设置绘制速度# 绘制月亮的外圈turtle.penup()turtle.goto(0, -100) # 移动到起始…

《线性代数的本质》

之前收藏的一门课&#xff0c;刚好期末复习&#xff0c;顺便看一看哈哈 课程链接&#xff1a;【线性代数的本质】合集-转载于3Blue1Brown官方双语】 向量究竟是什么 线性代数中最基础、最根源的组成部分就是向量&#xff0c;需要先明白什么是向量 不同专业对向量的看法 物理专…

鸿蒙系统ubuntu开发环境搭建

在RISC-V等平台移植鸿蒙系统OpenHarmony&#xff0c;需要使用linux环境进行代码的编译&#xff0c;为兼顾日常办公需要&#xff0c;可采用WindowsUbuntu虚拟机的混合开发的环境&#xff0c;通过网络及文件夹共享&#xff0c;在主机和虚拟机之间共享文件数据。 工具准备&#x…

智能停车解决方案之停车场室内导航系统(二):核心技术与系统架构构建

hello~这里是维小帮&#xff0c;如有项目需求和技术交流欢迎大家私聊我们&#xff01;点击文章最下方获取智慧停车场方案~撒花&#xff01; 随着城市化进程的加速&#xff0c;停车难问题日益凸显。智能停车系统作为缓解停车压力的有效手段&#xff0c;其核心技术与架构的构建至…

(免费送源码)计算机毕业设计原创定制:Java+JSP+HTML+JQUERY+AJAX+MySQL springboot计算机类专业考研学习网站管理系统

摘 要 大数据时代下&#xff0c;数据呈爆炸式地增长。为了迎合信息化时代的潮流和信息化安全的要求&#xff0c;利用互联网服务于其他行业&#xff0c;促进生产&#xff0c;已经是成为一种势不可挡的趋势。在大学生在线计算机类专业考研学习网站管理的要求下&#xff0c;开发一…

IDEA2023版本中如何启动项目的多个实例

假设现在要启动多个服务&#xff0c;例如简单的客户端和服务端&#xff0c;默认的idea是只能启动一个的&#xff0c;那么我们需要进行配置允许多个项目的同时启动&#xff0c;现在进行多实例的配置。 第一步 点击Edit Configurations 第二步 点击Modify options 第三步 勾选…

图的邻接矩阵和邻接表存储

目录 邻接矩阵存储法 简介 ​编辑 邻接矩阵举例 无向图邻接矩阵 有向图邻接矩阵 当各条边带有权值时 邻接矩阵算法实现 结构体定义和函数声明 函数的实现 邻接表存储法 简介 邻接表的算法实现 结构体定义和函数声明 函数的实现 邻接矩阵和邻接表的差别 邻接矩阵存…

【Linux命令】grep

Linux命令-grep GREP命令&#xff1a;进行字符串数据的比对&#xff0c;并将符合指定模式的字符串行打印出来。1.命令介绍基础正则表达式原始文档如下&#xff1a; 2.练习题&#xff1a;2.1 练习&#xff08;一&#xff09;&#xff1a;2.1.1 读取加行号的文件内容&#xff1a;…

WMS 如何实现智能仓储与自动化物流的无缝对接

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。】 在当今高度竞争的商业环境中&#xff0c;企业对于物流效率和仓储管理的要求日益严苛。智能仓储和自动化物流作为现代物流领域的重要发展方向&#xff0c;能够显著提高物流运作的速度、准确性和成…

DevOps-Jenkins-新手入门级

1. Jenkins概述 1. Jenkins是一个开源持续集成的工具&#xff0c;是由JAVA开发而成 2. Jenkins是一个调度平台&#xff0c;本身不处理任何事情&#xff0c;调用插件来完成所有的工作 1.1 什么是代码部署 代码发布/部署>开发书写的程序代码---->部署测试/生产环境 web服务…

WEB APIS(DOM对象,操作元素内容,属性,表单属性,自定义属性,定时器)

js基础基本语法&#xff1a; 变量&#xff0c;数据类型&#xff0c;循环&#xff0c;函数&#xff0c;对象等(主要是控制台打印&#xff09; WEB APIS 操作DOM BOM &#xff1a; 控制网页元素&#xff0c;交互等各种网页交互效果 js高级 语法&#xff1a; js新增语法&#xff0…

cs144(一)

cs144(一) 1、osi 当应用程序有数据要发送时&#xff0c;应用层将数据交给传输层&#xff0c; 传输层负责将数据可靠或不可靠地传送到另外一端&#xff0c;传输层通过将数据交给网络层来发送数据 网络层负责将数据分成数据包&#xff0c;每个数据包都有正确的目的地址 最后…

IEC61850读服务器目录命令——GetServerDirectory介绍

IEC61850标准中的GetServerDirectory命令是变电站自动化系统中非常重要的一个功能&#xff0c;它主要用于读取服务器的目录信息&#xff0c;特别是服务器的逻辑设备节点&#xff08;LDevice&#xff09;信息。以下是对GetServerDirectory命令的详细介绍。 目录 一、命令功能 …

如何使用AWS Lambda构建一个云端工具(超详细)

首发地址&#xff08;欢迎大家访问&#xff09;&#xff1a;如何使用AWS Lambda构建一个云端工具&#xff08;超详细&#xff09; 1 前言 1.1 无服务器架构 无服务器架构&#xff08;Serverless Computing&#xff09;是一种云计算服务模型&#xff0c;它允许开发者构建和运行…

力扣-位运算-1【算法学习day.41】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&am…

MySQL数据库学习(持续更新ing)

1. 什么是数据库&#xff1f;什么是数据库管理系统&#xff1f;什么是SQL&#xff1f;他们之间的关系是什么&#xff1f; 数据库&#xff1a;Database&#xff0c; 简称DB。按照一定格式存储数据&#xff0c;一些文件的组合。 数据库管理系统&#xff1a;DataBaseManagement&…

【Python · PyTorch】循环神经网络 RNN(基础概念)

【Python PyTorch】循环神经网络 RNN&#xff08;基础概念&#xff09; 0. 生物学相似性1. 概念2. 延时神经网络&#xff08;TDNN&#xff09;3. 简单循环神经网络&#xff08;Simple RNN&#xff09;3.1 BiRNN 双向循环神经网络3.2 特点记忆性参数共享图灵完备 3.3 网络结构3…

【Isaac Sim】相关问题汇总

目录 一、安装点击Install时报错二、启动时报 Failed to create any GPU devices三、加载Isaac Sim自带模型或示例时报 Isaac Sim is not responding 一、安装点击Install时报错 报错&#xff1a; request to https://asset.launcher.omniverse.nvidia.com/… failed, reason:…