Vue2项目练手——通用后台管理项目第一节
Vue2项目练手——通用后台管理项目
- 知识补充
- yarn和npm区别
- npm的缺点:
- yarn的优点
- npm查看镜像和设置镜像
- 项目介绍
- 项目的技术栈
- 项目搭建
- 文件目录
- 创建路由,引入element-ui
- router/index.js
- main.js
- pages/Users.vue
- pages/Main.vue
- pages/Home.vue
- pages/Login.vue
- App.vue
- 使用element-ui搭建主页样式
- main页面布局使用这个
- Main.vue
- 导航栏使用
- 导航栏适配
- Main.vue
- App.vue
- CommonAside
- 导航栏跳转
- 文件目录
- src/router/index.js
- src/pages/Mall.vue
- src/pages/pageOne.vue
- src/pages/PageTwo.vue
- src/components/CommonAside.vue
知识补充
yarn和npm区别
npm的缺点:
- npm install时候巨慢
- 同一个项目,安装的时候无法保持一致性。 由于package.json文件中版本号的特点。
“5.0.3” 安装指定的5.0.3版本
“~5.0.3” 表示安装5.0.X中最新的版本
“^5.0.3” 表示安装5.X.X中最新的版本
有时候会出现版本不一致不能运行的情况。
yarn的优点
- 速度快
并行安装:同步执行所有任务,不像npm按照队列执行每个package,package安装不完成,后面也无法执行。
离线模式:安装过得软件包,直接从缓存中获取,不用像npm从网络中获取。 - 安装版本统一
- 更简洁的输出:
npm输出所有被安装上的依赖,但是yarn只打印必要的信息 - 多注册来源处理:安装某个包,只会从一个注册来源去安装,
- 更好的语义化,yarn安装和卸载是yarn add/remove,npm是npm install/uninstall
npm查看镜像和设置镜像
npm config get registry
npm config set registry https://registry.npmmirror.com/
项目介绍
项目的技术栈

- 使用yarn安装vue-cli
yarn global add @vue/cli
项目搭建
先vue create创建一个项目,然后安装element-ui组件和vue-router,less等组件
文件目录

创建路由,引入element-ui
router/index.js
import VueRouter from "vue-router";
import Login from "@/pages/Login.vue";
import Users from "@/pages/Users.vue";
import Main from '@/pages/Main.vue'
import Home from "@/pages/Home.vue";const router= new VueRouter({// 浏览器模式设置,设置为history模式mode:'history',routes:[{path:"/login",component:Login,meta:{title:"登录"},},{// 主路由name:"main",path:'/',component:Main,children:[ //子路由{name:"users",path:"users",component:Users,meta:{title:"用户"}},{name:"home",path:"home",component:Home,meta:{title:"主页"}}]}]
})// 后置路由守卫
router.afterEach((to,from)=>{document.title=to.meta.title||"通用后台管理系统"
})
export default router
main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from "vue-router";
import router from "@/router";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false
Vue.use(VueRouter)
Vue.use(ElementUI)
new Vue({router,render: h => h(App),
}).$mount('#app')
pages/Users.vue
<template><div>我是Users组件</div></template><script>
export default {name: "Users",
}
</script><style scoped></style>
pages/Main.vue
<template><div><h1>main</h1><router-view></router-view></div></template><script>
export default {name: "Main",
}
</script><style scoped></style>
pages/Home.vue
<template><div>home内容</div></template><script>
export default {name: "Home",
}
</script><style scoped></style>
pages/Login.vue
<template><div id="app"><div class="main-content"><div class="title">系统登录</div><div class="content"><el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"><el-form-item label="用户名" prop="name"><el-input v-model="ruleForm.name" ></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input v-model="ruleForm.password" type="password" autocomplete="off"></el-input></el-form-item><el-form-item><el-row :gutter="20"><el-col :span="12" :offset="4"><router-link to="/login"><el-button type="primary" @click="submitForm('ruleForm')">登录</el-button></router-link></el-col></el-row></el-form-item></el-form></div></div></div></template><script>
export default {name: "login",data(){return{ruleForm: {name: '',password:""},rules: {name: [{required: true, message: '请输入用户名', trigger: 'blur'},{min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur'}],password: [{required:true,message:"请输入密码",trigger:"blur"}]}}},methods:{submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {// alert('submit!');} else {console.log('error submit!!');return false;}});},}
}
</script><style lang="less" scoped>
*{padding: 0;margin: 0;
}
#app {display: flex;background-color: #333;height: 800px;.main-content{height: 300px;width: 400px;background-color: #fff;margin: 200px auto;border-radius: 10px;padding: 30px;box-sizing: border-box;box-shadow: 5px 5px 10px rgba(0,0,0,0.5),-5px -5px 10px rgba(0,0,0,0.5);.title{font-size: 20px;text-align: center;//margin-top: 30px;font-weight: 300;}.content{margin-top: 30px;}}
}
</style>
App.vue
<template><div id="app"><router-view></router-view></div>
</template><script>export default {name: 'App',
}
</script><style lang="less">
*{padding: 0;margin: 0;
}
</style>

使用element-ui搭建主页样式
main页面布局使用这个


Main.vue
<template><div><el-container><el-aside width="200px">Aside</el-aside><el-container><el-header>Header</el-header><el-main><router-view></router-view></el-main></el-container></el-container></div></template><script>
export default {name: "Main",
}
</script><style scoped></style>

导航栏使用

导航栏适配
Main.vue
<template><div><el-container><el-aside width="200px"><CommonAside></CommonAside></el-aside><el-container><el-header>Header</el-header><el-main>
<!-- 路由出口,路由匹配到的组件将渲染在这里 --><router-view></router-view></el-main></el-container></el-container></div></template><script>
import CommonAside from "@/components/CommonAside.vue";
export default {name: "Main",components:{CommonAside}
}
</script><style scoped></style>
App.vue
<template><div id="app"><router-view></router-view></div>
</template><script>export default {name: 'App',
}
</script><style lang="less">
html,body,h3{padding: 0;margin: 0;
}
</style>
CommonAside
<template><el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose":collapse="isCollapse" background-color="#545c64" text-color="#fff"active-text-color="#ffd04b"><h3>通用后台管理系统</h3><el-menu-item index="2" v-for="item in noChildren" :key="item.name" :index="item.name"><i :class="`el-icon-${item.icon}`"></i><span slot="title">{{item.label}}</span></el-menu-item><el-submenu :index="item.label" v-for="item in hasChildren" :key="item.label"><template slot="title"><i :class="`el-icon-${item.icon}`"></i><span slot="title">{{item.label}}</span></template><el-menu-item-group><el-menu-item :index="subItem.path" :key="subItem.path" v-for="subItem in item.children">{{subItem.label}}</el-menu-item></el-menu-item-group></el-submenu></el-menu></template><style lang="less" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {width: 200px;min-height: 400px;
}
.el-menu{height: 100vh; //占据页面高度100%h3{color: #fff;text-align: center;line-height: 48px;font-size: 16px;font-weight: 400;}
}
</style><script>
export default {data() {return {isCollapse: false,menuData:[{path:'/',name:"home",label:"首页",icon:"s-home",url:'Home/Home'},{path:'/mail',name:"mall",label:"商品管理",icon:"video-play",url:'MallManage/MallManage'},{path:'/user',name:"user",label:"用户管理",icon:"user",url:'userManage/userManage'},{label:"其他",icon:"location",children:[{path:'/page1',name:"page1",label:"页面1",icon:"setting",url:'Other/PageOne'},{path:'/page2',name:"page2",label:"页面2",icon:"setting",url:'Other/PageTwo'},]},]};},methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);}},computed:{//没有子菜单的数据noChildren(){return this.menuData.filter(item=>!item.children)},hasChildren(){return this.menuData.filter(item=>item.children)}//有子菜单数组}
}
</script>

导航栏跳转
文件目录

src/router/index.js
import VueRouter from "vue-router";
import Login from "@/pages/Login.vue";
import Users from "@/pages/Users.vue";
import Main from '@/pages/Main.vue'
import Home from "@/pages/Home.vue";
import Mall from "@/pages/Mall.vue";
import PageOne from "@/pages/PageOne.vue";
import PageTwo from "@/pages/PageTwo.vue";const router= new VueRouter({// 浏览器模式设置,设置为history模式// mode:'history',routes:[{path:"/login",component:Login,meta:{title:"登录"},},{// 子路由name:"main",path:'/',redirect:"/home", //重定向 当路径为/,则重定向homecomponent:Main,children:[{name:"user",path:"user",component:Users,meta:{title:"用户管理"}},{name:"home",path:"home",component:Home,meta:{title:"首页"}},{name:"mall",path:"mall",component:Mall,meta:{title:"商品管理"}},{name:"page1",path:"page1",component:PageOne,meta:{title:"页面1"}},{name:"page2",path:"page2",component:PageTwo,meta:{title:"页面2"}}]}]
})// 后置路由守卫
router.afterEach((to,from)=>{document.title=to.meta.title||"通用后台管理系统"
})
export default router
src/pages/Mall.vue
<template><div>我是mall</div></template><script>
export default {name: "Mall",
}
</script><style scoped></style>
src/pages/pageOne.vue
<template><div>我是PageOne</div></template><script>
export default {name: "PageOne",
}
</script><style scoped></style>
src/pages/PageTwo.vue
<template><div>我是PageTwo</div></template><script>
export default {name: "PageTwo",
}
</script><style scoped></style>
src/components/CommonAside.vue
<template><el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose":collapse="isCollapse" background-color="#545c64" text-color="#fff"active-text-color="#ffd04b"><h3>通用后台管理系统</h3><el-menu-item @click="clickMenu(item)" v-for="item in noChildren" :key="item.name" :index="item.name"><i :class="`el-icon-${item.icon}`"></i><span slot="title">{{item.label}}</span></el-menu-item><el-submenu :index="item.label" v-for="item in hasChildren" :key="item.label"><template slot="title"><i :class="`el-icon-${item.icon}`"></i><span slot="title">{{item.label}}</span></template><el-menu-item-group><el-menu-item @click="clickMenu(subItem)" :index="subItem.path" :key="subItem.path" v-for="subItem in item.children">{{subItem.label}}</el-menu-item></el-menu-item-group></el-submenu></el-menu></template><style lang="less" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {width: 200px;min-height: 400px;
}
.el-menu{height: 100vh; //占据页面高度100%h3{color: #fff;text-align: center;line-height: 48px;font-size: 16px;font-weight: 400;}
}
</style><script>
export default {data() {return {isCollapse: false,menuData:[{path:'/',name:"home",label:"首页",icon:"s-home",url:'Home/Home'},{path:'/mall',name:"mall",label:"商品管理",icon:"video-play",url:'MallManage/MallManage'},{path:'/user',name:"user",label:"用户管理",icon:"user",url:'userManage/userManage'},{label:"其他",icon:"location",children:[{path:'/page1',name:"page1",label:"页面1",icon:"setting",url:'Other/PageOne'},{path:'/page2',name:"page2",label:"页面2",icon:"setting",url:'Other/PageTwo'},]},]};},methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);},clickMenu(item){// console.log(item)this.$router.push(item.path)}},computed:{//没有子菜单的数据noChildren(){return this.menuData.filter(item=>!item.children)},//有子菜单数组hasChildren(){return this.menuData.filter(item=>item.children)}}
}
</script>

相关文章:
Vue2项目练手——通用后台管理项目第一节
Vue2项目练手——通用后台管理项目 知识补充yarn和npm区别npm的缺点:yarn的优点 npm查看镜像和设置镜像 项目介绍项目的技术栈 项目搭建文件目录 创建路由,引入element-uirouter/index.jsmain.jspages/Users.vuepages/Main.vuepages/Home.vuepages/Login…...
「Vue|网页开发|前端开发」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转
本文主要介绍如何使用路由控制来实现将一个单页面网站扩展成多页面网站,包括页面扩展的逻辑,vue的官方路由vue-router的基本用法以及扩展用法 文章目录 本系列前文传送门一、场景说明二、基本的页面扩展页面扩展是在扩什么创建新页面的代码,…...
【Nginx20】Nginx学习:FastCGI模块(二)缓存配置
Nginx学习:FastCGI模块(二)缓存配置 通过上篇文章的学习,普通的 PHP 与 Nginx 的连接就已经没啥大问题了。一般的网站直接那套配置就够了,这也是 Nginx 非常友好的一面。很多在默认的配置文件中注释掉的内容࿰…...
苹果支付外包开发流程
苹果支付的实现流程主要涉及集成苹果的支付系统——Apple Pay,以及在你的应用中处理支付交易。以下是一个简要的实现流程概述,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.开发者账号…...
银河麒麟V10(Tercel)服务器版安装 Docker
一、服务器环境 ## 查看系统版本,确认版本 cat /etc/kylin-release Kylin Linux Advanced Server release V10 (Tercel)## 操作系统 uname -p aarch64## 内核版本(≥ 3.10) uname -r 4.19.90-21.2.ky10.aarch64## iptables 版本(…...
web、HTTP协议
目录 一、Web基础 1.1 HTML概述 1.1.1 HTML的文件结构 1.2 HTML中的部分基本标签 1.3 URI 和 URL 二.HTTP协议 2.1.HTTP概念 2.2.HTTP协议版本 2.3.HTTP请求方法 2.4.HTTP请求访问的完整过程 2.5.HTTP状态码 2.6.HTTP请求报文和响应报文 2.7.HTTP连接优化 三.HTT…...
达梦SQL书写注意事项
模糊查询 模糊查询like后面的字段要求用单引号引用,不能使用双引号 select * from user where name like %小组 分组查询 select查询的列字段必须在分组中的字段存在 正确: select name,age from user group by name,age 错误: select * f…...
博途1200脉冲输出控制速度轴(轴工艺对象基本配置)
这里的1200脉冲轴,主要用来完成线缆包材绕包时的重叠率控制。关于重叠率的具体概念,这里不再阐述,大家可以看下面的文章链接, 重叠率控制 重叠率控制(算法详细介绍含SCL和梯形图源代码)_RXXW_Dor的博客-CSDN博客产品包装和线缆保护材料的包覆都需要进行材料包装重叠率的控…...
微信小程序 通过setData 给两个变量设置同一个数组时,为什么修改一个变量,另一个会也被修改?
在微信小程序中,使用 setData 方法更新数据时,如果给两个变量设置同一个数组,修改其中一个变量的值会导致另一个变量也被修改的原因是,数组是引用类型的数据,在内存中的存储方式是按引用地址存储。 当你将一个数组赋值…...
保障Web安全:构建可靠的网络防御体系
在当今数字化时代,Web安全已成为互联网世界中至关重要的议题。随着网络攻击手段的不断演进和网络犯罪的增加,保护用户数据和确保系统安全性已成为任何Web应用程序的首要任务。本文将深入探讨Web安全的重要性以及构建可靠的网络防御体系的关键要素。我们将…...
LeetCode--HOT100题(44)
目录 题目描述:230. 二叉搜索树中第K小的元素(中等)题目接口解题思路代码 PS: 题目描述:230. 二叉搜索树中第K小的元素(中等) 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你…...
大模型调试debug记录
环境:Linux , cuda 11.7 RuntimeError: Distributed package doesnt have NCCL built in 原因:pytorch安装的是cpu版本,需要安装支持gpu版本的 RuntimeError: Distributed package doesnt have NCCL built in - #3 by bdabykov - distrib…...
对话谷歌首席技术官肖恩,搜索引擎的里程碑,来看看搜索引擎界的大哥Algolia的“快、准、狠”突围关键
原创 | 文 BFT机器人 人物背景 Character Background Sean Mullaney是Algolia(端到端人工智能搜索和发现平台)的首席技术官,也是前 Stripe和谷歌高管,拥有扩展工程组织、开发人工智能驱动的搜索和发现工具以及在全球范围内发展A…...
DP读书:鲲鹏处理器 架构与编程(十二)鲲鹏软件实战案例
10min速通了解鲲鹏软件实战案例 云服务器源码移植与编译配置云服务器Porting Advisor代码移植搭建交叉编译环境x86云服务器交叉编译 OpenSSL鲲鹏云服务器上编译 OpenSSL Docker的安装与应用安装DockerDocker运行与验证Docker常用命令卸载Docker安装适配鲲鹏架构的Docker镜像 KV…...
前端 -- 基础 VSCode 工具生成骨架标签新增代码 解释详解
目录 文档类型声明标签 Lang 语言种类 字符集 文档类型声明标签 <!DOCTYPE> 文档类型声明,作用就是告诉浏览器 当前的页面是 使用哪种 HTML 版本 来显示的网页 HTML 版本也很多呀 ,比如 : HTML5 ,HTML4,XHTML 等…...
爬虫逆向实战(二十三)--某准网数据
一、数据接口分析 主页地址:某准网 1、抓包 通过抓包可以发现数据接口是api_to/search/company_v2.json 2、判断是否有加密参数 请求参数是否加密? 通过查看“载荷”模块可以发现b参数和kiv参数是加密参数 请求头是否加密? 无响应是否加…...
ruoyi--数据权限
这篇文章我先和大家分析一下 RuoYi-Vue 脚手架中 DataScope 注解的实现原理,在 TienChin 项目视频中到时候还会有深入讲解。 1. 思路分析 首先我们先来捋一捋这里的权限实现的思路。 DataScope 注解处理的内容叫做数据权限,就是说你这个用户登录后能够…...
快速开发平台是什么?和传统开发平台相比有哪些区别?
本文可以从【快速开发平台的价值、和传统平台的区别、使用感受】三个方面来说明。 首先,我们要清楚快速开发平台是什么: 快速开发平台也称为低代码或无代码平台,旨在通过可视化工具、拖放式界面和预构建组件,使应用程序的开发过…...
Android基于JNI的Java与C++互调
java调用C++: #include <jni.h> //导出c函数格式 extern "C" JNIEXPORT //供JNI调用 JNICALL 函数名格式 Java_包名_类名_函数名(包名.替换为_) Java_com_example_getapplist_MainActivity_stringFromJNI 包名:com_example_getapplist 类名:MainActi…...
【算法与数据结构】513、LeetCode找树左下角的值
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:这道题用层序遍历来做比较简单,最底层最左边节点就是层序遍历当中最底层元素容器的第一个值…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
