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题解。 一、题目 二、解法 思路分析:这道题用层序遍历来做比较简单,最底层最左边节点就是层序遍历当中最底层元素容器的第一个值…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
Android屏幕刷新率与FPS(Frames Per Second) 120hz
Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数,单位是赫兹(Hz)。 60Hz 屏幕:每秒刷新 60 次,每次刷新间隔约 16.67ms 90Hz 屏幕:每秒刷新 90 次,…...

构建Docker镜像的Dockerfile文件详解
文章目录 前言Dockerfile 案例docker build1. 基本构建2. 指定 Dockerfile 路径3. 设置构建时变量4. 不使用缓存5. 删除中间容器6. 拉取最新基础镜像7. 静默输出完整示例 docker runDockerFile 入门syntax指定构造器FROM基础镜像RUN命令注释COPY复制ENV设置环境变量EXPOSE暴露端…...