热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

vue3.2后台管理系统搭建学习笔记

1、创建项目更改版本1-1、创建项目vuecreatevue3-admin1-2、更改vue版本更改前更改后2、开发项目1、按需引入element-plus1、安装np
1、创建项目更改版本

1-1、创建项目

vue create vue3-admin


1-2、更改vue版本

更改前

更改后

 

2、开发项目

1、按需引入element-plus


1、安装

npm install element-plus --save

2、按需导入(自动导入)

cnpm install -D unplugin-vue-components unplugin-auto-import

3、Webpack配置(vue.config.js)

const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')module.exports = {
intOnSave:false,devServer:{open:true,port:9000,},configureWebpack: {plugins: [AutoImport({resolvers: [ElementPlusResolver()],}),Components({resolvers: [ElementPlusResolver()],}),]},
}

4、使用

tips:在main.js中引入样式(避免弹出框等组件样式错乱)

import 'element-plus/dist/index.css'

2、使用element-plus Icon图标 


1、安装

cnpm install @element-plus/icons-vue

2、注册全局组件

//main.js
import * as ELIcons from '@element-plus/icons-vue'
for (const iconName in ELIcons) {app.component(iconName, ELIcons[iconName])
}

 3、使用(左侧菜单icon)


3、样式初始化,使用scss变量


1、导入初始样式,导出变量值


 2、在main.js中引入

import '@/styles/index.scss'

3、配置webpack

css: {loaderOptions: {sass: {// 8版本用prependData:prependData: `@import "@/styles/variables.scss"; // scss文件地址@import "@/styles/mixin.scss"; // scss文件地址`}}}

4、使用svg,全局注册


1、svg图标导入到项目

 2、在components文件夹下创建SvgIcon组件



4、在icons 文件夹下新建index.js

import SvgIcon from '@/components/SvgIcon'const svgRequired = require.context('./svg', false, /\.svg$/)
svgRequired.keys().forEach((item) => svgRequired(item))export default (app) => {app.component('svg-icon', SvgIcon)
}

5、在main.js中引入

import SvgIcon from '@/icons'
const app=createApp(App)
SvgIcon(app)

6、安装依赖

cnpm i --save-dev svg-sprite-loader@6.0.9

7、配置webpack

const path = require('path')
function resolve(dir) {return path.join(__dirname, dir)
}
const webpack = require('webpack')module.exports = {
chainWebpack(config) {// 设置 svg-sprite-loader// config 为 webpack 配置对象// config.module 表示创建一个具名规则,以后用来修改规则config.module// 规则.rule('svg')// 忽略.exclude.add(resolve('src/icons'))// 结束.end()// config.module 表示创建一个具名规则,以后用来修改规则config.module// 规则.rule('icons')// 正则,解析 .svg 格式文件.test(/\.svg$/)// 解析的文件.include.add(resolve('src/icons'))// 结束.end()// 新增了一个解析的loader.use('svg-sprite-loader')// 具体的loader.loader('svg-sprite-loader')// loader 的配置.options({symbolId: 'icon-[name]'})// 结束.end()config.plugin('ignore').use(new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/))config.module.rule('icons').test(/\.svg$/).include.add(resolve('src/icons')).end().use('svg-sprite-loader').loader('svg-sprite-loader').options({symbolId: 'icon-[name]'}).end()},
}

8、使用


5、请求封装


1、安装axios 

cnpm i axios --save

 2、新建utils文件夹,新建auth.js设置过期时间

const TOKEN_TIME = 'tokenTime'const TOKEN_TIME_VALUE = 2 * 60 * 60 * 1000// 登录时设置时间
export const setTokenTime = () => {localStorage.setItem(TOKEN_TIME, Date.now())
}// 获取
export const getTokenTime = () => {return localStorage.getItem(TOKEN_TIME)
}// 是否已经过期
export const diffTokenTime = () => {const currentTime = Date.now()const tokenTime = getTokenTime()return currentTime - tokenTime > TOKEN_TIME_VALUE
}

3、新建api文件夹,新建request.js文件

import axios from 'axios'
import { ElMessage } from 'element-plus'
import { diffTokenTime } from '@/utils/auth'
import store from '@/store'
const service = axios.create({baseURL: process.env.VUE_APP_BASE_API,timeout: 5000
})service.interceptors.request.use((config) => {if (localStorage.getItem('token')) {if (diffTokenTime()) {store.dispatch('app/logout')return Promise.reject(new Error('token 失效了'))}}config.headers.Authorization = localStorage.getItem('token')return config},(error) => {return Promise.reject(new Error(error))}
)service.interceptors.response.use((response) => {const { data, meta } = response.dataif (meta.status === 200 || meta.status === 201) {return data} else {ElMessage.error(meta.msg)return Promise.reject(new Error(meta.msg))}},(error) => {console.log(error.response)error.response && ElMessage.error(error.response.data)return Promise.reject(new Error(error.response.data))}
)
export default service

4、本地跨域配置

devServer: {https: false,hotOnly: false,open:true,port:9000,proxy: {'/api': {target: 'https://*******/api/private/v1/',changeOrigin: true,pathRewrite: {'^/api': ''}}}},

5、全局坏境变量定义

 新建 .env.development、.env.production文件

ENV = 'development'VUE_APP_BASE_API = '/api'

ENV = 'production'VUE_APP_BASE_API = '/prod-api'

6、全局导航守卫 

import { createRouter, createWebHashHistory } from 'vue-router'const routes = [{path: '/login',name: 'Login',component: () => import('../views/login/index.vue')},{path: '/',name: '/',component: () => import('../layout'),redirect: '/users',children: [{path: 'users',name: 'users',component: () => import('@/views/users/index.vue')},{path: 'categories',name: 'categories',component: () => import('@/views/categories/index.vue')},{path: 'goods',name: 'goods',component: () => import('@/views/goods/index.vue')},{path: 'orders',name: 'orders',component: () => import('@/views/orders/index.vue')},{path: 'params',name: 'params',component: () => import('@/views/params/index.vue')},{path: 'reports',name: 'reports',component: () => import('@/views/reports/index.vue')},{path: 'rights',name: 'rights',component: () => import('@/views/rights/index.vue')},{path: 'roles',name: 'roles',component: () => import('@/views/roles/index.vue')}]}
]const router = createRouter({history: createWebHashHistory(),routes
})export default router

1、新建router/permission.js

import router from './index'
import store from '@/store'const whiteList = ['/login']
router.beforeEach((to, from, next) => {if (store.getters.token) {if (to.path === '/login') {next('/')} else {next()}} else {if (whiteList.includes(to.path)) {next()} else {next('/login')}}
})

2、main.js引入 

import '@/router/permission'

5、登录 


1、新增登录界面login/index.vue



2、新建api/login.js

import request from './request'export const login = (data) => {return request({url: '/login',method: 'POST',data})
}

3、新建store/modules/app.js

import { login as loginApi } from '@/api/login'
import router from '@/router'
import { setTokenTime } from '@/utils/auth'
export default {namespaced: true,state: () => ({token: localStorage.getItem('token') || '',siderType: true,}),mutations: {setToken(state, token) {state.token = tokenlocalStorage.setItem('token', token)},changeSiderType(state) {state.siderType = !state.siderType},},actions: {login({ commit }, userInfo) {return new Promise((resolve, reject) => {loginApi(userInfo).then((res) => {console.log(res)commit('setToken', res.token)setTokenTime()router.replace('/')resolve()}).catch((err) => {reject(err)})})},// 退出logout({ commit }) {commit('setToken', '')localStorage.clear()router.replace('/login')}}
}

4、store/getters.js、store/index.js

export default {token: (state) => state.app.token,siderType: (state) => state.app.siderType,
}

import { createStore } from 'vuex'
import app from './modules/app'
import getters from './getters'
export default createStore({modules: {app},getters
})


3、Layout 布局




1、左侧菜单 新建layout/Menu/index.vue


menu数据 

{"data": [{"id": 125,"authName": "用户管理","path": "users","children": [{"id": 110,"authName": "用户列表","path": "users","children": [],"order": null}],"order": 1},{"id": 103,"authName": "权限管理","path": "rights","children": [{"id": 111,"authName": "角色列表","path": "roles","children": [],"order": null},{"id": 112,"authName": "权限列表","path": "rights","children": [],"order": null}],"order": 2},{"id": 101,"authName": "商品管理","path": "goods","children": [{"id": 104,"authName": "商品列表","path": "goods","children": [],"order": 1},{"id": 115,"authName": "分类参数","path": "params","children": [],"order": 2},{"id": 121,"authName": "商品分类","path": "categories","children": [],"order": 3}],"order": 3},{"id": 102,"authName": "订单管理","path": "orders","children": [{"id": 107,"authName": "订单列表","path": "orders","children": [],"order": null}],"order": 4},{"id": 145,"authName": "数据统计","path": "reports","children": [{"id": 146,"authName": "数据报表","path": "reports","children": [],"order": null}],"order": 5}],"meta": {"msg": "获取菜单列表成功","status": 200}
}

2、右侧头部



1、hamburger.vue 控制左侧菜单折叠展开



2、breadcrumb.vue 面包屑导航



3、screenFull.vue 全屏组件

1、安装

cnpm i screenfull --save

2、使用



4、driver引导组件

1、安装

cnpm i driver.js --save

2、使用


 5、头像下拉 退出



4、用户管理开发

1、搜索功能 、结果列表展示



2、新建components/dialog.vue 新增、编辑用户弹框组件





3、新建全局时间过滤器


1、安装dayjs

cnpm i dayjs --save

2、新建utils/filters.js


import dayjs from 'dayjs'const filterTimes = (val,format='YYYY-MM-DD') =>{if(!isNull(val)){val = parseInt(val)*1000return dayjs(val).format(format)}else{return '--'}
}export const isNull = (val)=>{if(!val) return trueif(JSON.stringify(val)==="{}") return trueif(JSON.stringify(val)==="[]") return true
}export default (app)=>{app.config.globalProperties.$filters={filterTimes}
}

3、main.js传入app

import filters from './utils/filters'
filters(app)

4、使用



推荐阅读
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文介绍如何解决在 IIS 环境下 PHP 页面无法找到的问题。主要步骤包括配置 Internet 信息服务管理器中的 ISAPI 扩展和 Active Server Pages 设置,确保 PHP 脚本能够正常运行。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • 本文介绍如何在QT框架中使用QWebSocket和QTcpSocket实现SSL加密通信,涵盖单向认证设置。单向认证常见于Web通信场景,其中客户端验证服务端证书,而服务端不验证客户端证书。 ... [详细]
  • 本文详细介绍了Java中的访问器(getter)和修改器(setter),探讨了它们在保护数据完整性、增强代码可维护性方面的重要作用。通过具体示例,展示了如何正确使用这些方法来控制类属性的访问和更新。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • PHP 5.5.0rc1 发布:深入解析 Zend OPcache
    2013年5月9日,PHP官方发布了PHP 5.5.0rc1和PHP 5.4.15正式版,这两个版本均支持64位环境。本文将详细介绍Zend OPcache的功能及其在Windows环境下的配置与测试。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
author-avatar
奇奇丶承诺
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有