当前位置: 首页 > article >正文

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、页面展示效果

 

 


http://www.kler.cn/a/409437.html

相关文章:

  • ROS2 报错记录
  • SQL 分页查询详解
  • 解决Dcat Admin laravel框架登录报错问题,(blocked:mixed-content)
  • web——sqliabs靶场——第十三关——报错注入+布尔盲注
  • 【Django】测试
  • 【贪心算法】绿洲之旅:最少次数补给探索
  • 网络安全,文明上网(2)加强网络安全意识
  • 【LC】2529. 正整数和负整数的最大计数
  • 【人工智能】用Python和NLP工具构建文本摘要模型:使用NLTK和spaCy进行自然语言处理
  • Java爬虫的奇妙冒险:揭开1688商品详情的神秘面纱
  • 大连环保公益管理系统|Java|SSM|Vue| 前后端分离
  • (图解)TCP的三次握手,四次挥手
  • 前后端分离,解决vue+axios跨域和proxyTable不生效等问题
  • windows下轻量级虚拟化wsl 执行linux系统实践应用
  • 7天掌握SQL - 第三天:MySQL实践与索引优化
  • HarmonyOS应用开发中的页面路由与数据传输
  • C语言之为表达式计算器实现定义变量和使用变量功能
  • 大数据的数据整合
  • 【linux】插入新硬盘如何配置:格式化、分区、自动挂载(Ubuntu)
  • 表格数据处理中大语言模型的微调优化策略研究
  • Python 使用 OpenCV 将 MP4 转换为 GIF图
  • 新华三H3CNE网络工程师认证—子接口技术
  • 任子行网络安全审计系统 log_fw_ips_scan_jsondata SQL注入漏洞复现
  • java基础(一):JDK、JRE、JVM、类库等概念,java跨平台实现原理
  • On-Chip-Network之Topology
  • Pytorch自定义算子反向传播