赞
踩
elementplus官网:一个 Vue 3 UI 框架 | Element Plus (element-plus.org)
npm install element-plus --save
查看package.json中存在依赖表示成功安装
- import ElementPlus from 'element-plus'
- import 'element-plus/dist/index.css'
-
-
-
-
-
- const app = createApp(App)
- app.use(ElementPlus)
注意:vue3不支持elementUI,所以选择以下搭配其中之一(这里我选的是2)
(1)vue2+elementUI
(2)vue3+elementPlus
点击官网上方菜单栏的组件,点击
点击布局容器可以看到示例,我们选择使用最下面的侧边栏的示例代码
Container 布局容器 | Element Plus (element-plus.org)
查看示例的代码,这里选择手动引入(elementplus还支持自动按需引入)
代码主要分成四部分,第一部分我们需要放在template里面,第二部分是选择按需部分引入的方式,我们可以不管,第三部分是放在script里的data部分里面也就是提供页面的数据,具体填入形式如下
- <script >
- export default {
- name: "HomeView",
- data(){
- const item = {
- date: '2016-05-02',
- name: 'Tom',
- address: 'No. 189, Grove St, Los Angeles',
- };
- return {
- tableData : (Array.from({ length: 20 }).fill(item)),
- }
- }
- }
-
- </script>
第四部分是页面的样式,不重要,我们可以不使用
引入完成功编译运行后的结果:
//global.css
- html,body,div{
- margin: 0;
- padding: 0;
- }
- html,body{
- height: 100%;
- }
然后再main.js里引入 (不要忘了加 ./ )
将所有菜单的高度改成100% 这个时候滚动页面整个页面不会跟随滚动,菜单栏可以单独滚动
自行调整样式后:
- <el-menu :default-openeds="['1', '3']" style="height: 100%;overflow-x:hidden"
- background-color="rgb(48,65,86)" //菜单背景设为藏蓝
- text-color="#fff" //字体设为白色
- active-text-color="#ffd04b" //选中后字体变成黄色
- :collapse-transition="false"
- :collapse="isCollapse" //设置初始被展开的属性为false(初始为折叠)
- >
效果:
先安装elementPlus图标:
npm install --save @element-plus/icons
到elementPlus官网图标下赋值图标标签代码
Icon 图标 | Element Plus (element-plus.org)
- <span>Tom
- <el-icon style="margin-left: 5px">
- <ArrowDownBold></ArrowDownBold>
- </el-icon>
- </span>
效果:
编写收缩的方法
- methods: {
- collapse(){ //点击收缩按钮触发
- this.isCollapse=!this.isCollapse
- }
- }
此时收缩会出现问题,文字没有隐藏,宽度不对
所以需要将宽度设为动态的
然后再将导航的名称都放在span标签里,就会自动收缩进去
然后更改如果收缩了,图标就改变,这里我用v-if和v-else的组合
再结合前面设置的isCollapse状态
使得图标可以切换
效果:
------------------》
- <div style="height: 60px;line-height: 60px;text-align: center">
- <img src="../assets/logo.png" alt="" style="width: 20px;position: relative;top:5px;margin-right: 5px">
- <b v-show="!isCollapse" style="color: white">后台管理系统</b>
- </div>
效果:
----------------------》
linehight如果设置和垂直高度一致,就会居中,否则就会在上方或者下面
style="line-height: 60px"
效果:
----------》
首先去掉e-menu的边框的颜色
border-right-color: transparent
再在e-side里面添加阴影属性
box-shadow: 2px 0 6px rgb(0 21 41 / 35%)
效果:
进到官网页面,pagination
Pagination 分页 | Element Plus (element-plus.org)
copy“完整功能”代码
黏贴在e-mian标签下的e-table下
- <div style="padding: 10px 0">
- <el-pagination
- v-model:current-page="currentPage4"
- v-model:page-size="pageSize4"
- :page-sizes="[100, 200, 300, 400]"
- :small="small"
- :disabled="disabled"
- :background="background"
- layout="total, sizes, prev, pager, next, jumper"
- :total="400"
-
- />
- </div>
此时可以看到底部的效果,并且还没有生效
- <el-input style="width: 300px" type="text" placeholder="请输入名称">
- <template #prefix>
- <el-icon class="el-input__icon">
- <search></search>
- </el-icon>
- </template>
- </el-input>
-
- <el-button class="ml-5" type="" style="color: orangered">搜索</el-button>
效果:
扩展多个输入框:
<el-table :data="tableData" border stripe >
- <style >
- .el-table th{
- background-color: beige !important
- }
- </style>
效果:
增删导入导出
- <div style="margin: 10px 0;text-align: left">
- <el-button type="primary">新增
- <el-icon><CirclePlus></CirclePlus></el-icon>
- </el-button>
- <el-button type="danger">批量删除
- <el-icon><remove></remove></el-icon>
- </el-button>
- <el-button type="primary">导入
- <el-icon><bottom></bottom></el-icon>
- </el-button>
- <el-button type="primary">导出
- <el-icon><top></top></el-icon>
- </el-button>
- </div>
表格里的编辑、删除
- <el-table-column label="操作" >
- <el-table-column>
- <template>slot-scope="scope"</template>
- <el-button type="success">编辑
- <el-icon><edit></edit></el-icon>
- </el-button>
- <el-button type="danger">删除
- <el-icon><remove></remove></el-icon>
- </el-button>
- </el-table-column>
- </el-table-column>
最后的效果:
(108条消息) vue项目中table表格固定表头和首尾列_梨城毒妃的博客-CSDN博客_vue固定表头
<el-table :data="tableData" border stripe height="500px" max-height="400px" >
至此管理系统的前端雏形已经产生
在官网的面包屑模块下:
Breadcrumb 面包屑 | Element Plus (element-plus.org)
- <div style="margin-bottom: 30px">
- <el-breadcrumb separator="/">
- <el-breadcrumb-item :to="{ path: '/' }">主页</el-breadcrumb-item>
- <el-breadcrumb-item :to="{path: '/new'}">用户管理</el-breadcrumb-item>
- <el-breadcrumb-item>promotion list</el-breadcrumb-item>
- <el-breadcrumb-item>promotion detail</el-breadcrumb-item>
- </el-breadcrumb>
- </div>
效果:
1、创建项目,引入lombok,mybatisplus,mysql等等依赖
后两个依赖在项目勾选时候可以自动导入,所以只用关注前面的
-
- <dependencies>
- <!-- lombok-->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <scope>provided</scope>
- </dependency>
- <!-- mybatisplus-->
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- <version>3.4.1</version>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>1.1.16</version>
- </dependency>
- <dependency>
- <groupId>com.mysql</groupId>
- <artifactId>mysql-connector-j</artifactId>
- <scope>runtime</scope>
- <version>8.0.31</version>
- </dependency>
-
-
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-core</artifactId>
- <version>3.4.3.1</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
2、编写yml文件
- spring:
-
- datasource:
- type: com.alibaba.druid.pool.DruidDataSource
- driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC
- username: root
- password: 123456
-
- main:
- banner-mode: off
-
- mybatis-plus:
- global-config:
- banner: false
- server:
- port: 8081
效果:
项目结构:
测试springboot
建立表:sys_user
写入数据:
建立包和实体接口
使接口继承BaseMapper,并注解为Mapper
在写任何controller时候前面都要加一个注解:RestController
测试连接数据库
用lambdaquery来写查询
- @RequestMapping("/select") //访问路径
- public List<User> select(){
- LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
- // lqw.like(User::getUsername,'a');
- List<User> userList = userDao.selectList(lqw);
- return userList;
-
- }
结果:
先设置拦截器:(一定要把pom里面的所有关于mybatisplus的依赖的版本号改成一致的)
编写接口:
后来发现要加total,所以改成返回Map
- @GetMapping("/page")
- public List<User> fingPage(@RequestParam Integer pageNum,@RequestParam Integer pageSize){
- pageNum = (pageNum-1)*pageSize;
- IPage page = new Page(pageNum,pageSize);
- userDao.selectPage(page, null);
- return page.getRecords();
-
- }
用postman测试:(查出两条数据)
在vue页面查看要传输的数据:
编写传数据的方法:
- created() {
- //请求分页查询数据
- fetch("http://localhost:9090/user/page?pageNum=1&pageSize=2").then(res => res.json()).then(
- res =>{
- console.log(res)
- })
- },
查看,出现了跨域问题 (前端端口与后端端口不一致)
选择在后端处理跨域
最简单方法:在controller类名前加@CrossOrigin注解,这是最简单的处理方式
比较完善的方法:加入如下代码
(94条消息) SpringBoot解决跨域问题_程序员青戈的博客-CSDN博客_springboot解决跨域问题 青戈
这个时候我们再次启动后台:此时控制台显示我们的数据获取成功
返回改成map后:(就分成了两组)
封装渲染时加载数据的代码为load
- load(){
- fetch("http://localhost:8081/page?pageNum="+this.pageNum+"&pageSize="+this.pageSize).then(res => res.json()).then(res => {
- console.log(res)
- this.tableData=res.data
- this.total=res.total
- })
- }
在created函数内调用load
- created() {
- //请求分页查询数据
- this.load()
-
- }
created函数:在页面刷新时,重新加载数据,在vue3中有一个setup()注意里面不能用method里的方法也不能使用this
编写跟随页数更改跳转和重新渲染页面的两个方法:用于动态更改页码和显示数据数目
handleSizeChange(pageSize) handleCurrentChange
Pagination 分页 | Element Plus (element-plus.org)
- handleSizeChange(pageSize){
- this.pageSize = pageSize
- this.load()
- },
- handleCurrentChange(pageNum){
- this.pageNum=pageNum
- this.load()
- }
效果:
至此页码的所有功能都已激活
绑定搜索框,返回搜索数据
增加查询的名称username关键字
- @GetMapping("/page")
- public Map<String,Object> fingPage(@RequestParam Integer pageNum,
- @RequestParam Integer pageSize,
- @RequestParam String username){
- pageNum = (pageNum-1)*pageSize;
- Page page = new Page(pageNum,pageSize);
- LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
- lqw.like(User::getUsername,username);
- userDao.selectPage(page, lqw);
- Map<String,Object> hm = new HashMap<>();
- hm.put("data",page.getRecords());
- hm.put("total",page.getTotal());
-
- return hm;
- // return userService.findAll();
- }
我们可以看到我们写完QuerWrapper后可以直接填写到selectPage函数第二个参数里(原来为null)非常巧妙
我们用postman输入参数尝试查询结果成功,注意此时我们并没有更改任何前端
我们成功后即可用v-model绑定前端的搜索框
然后写入data()(默认为空),然后在fetch函数里添加username字段
绑定前端搜索按钮事件为重新渲染数据
第一个搜索框的功能已经激活成功
扩展多条件查询(将其它两个搜索框也激活)
总结上面一个框激活的流程:
1、在接口里增加查询的参数,并且增加querymapper对象的方法
2、用v-model绑定搜索框数据,并且绑定按钮渲染函数
3、在后端data增加参数,并且增加fectch渲染函数的参数
清楚了流程,我们做起来就事半功倍了
至此多条件查询已激活所有搜索框
激活新增,批量删除,导入,导出四个按钮
驼峰映射是自动的,它会把下划线去掉并把下划线原来后面的字母大写
如:user_name->userName
用postman测试如果觉得复杂,可以用swaggerUI(一个接口测试文档)
(94条消息) SpringBoot集成swagger-ui以及swagger分组显示_程序员青戈的博客-CSDN博客_swagger ui 分组 第一步:
导入swagger依赖:
创建swaggerConfig类:
更改包的地址:
我觉得还是postman好用
使用axios代替fetch (fetch太繁琐)
(94条消息) Vue项目搭建常用的配置文件,request.js和vue.config.js_程序员青戈的博客-CSDN博客_vue config.headers配置
安装axios
npm i axios -s
新建utils文件夹,并新建js文件
黏贴封装的request.js代码:
- import axios from 'axios'
-
- const request = axios.create({
- baseURL: '/api', // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
- timeout: 5000
- })
-
- // request 拦截器
- // 可以自请求发送前对请求做一些处理
- // 比如统一加token,对请求参数统一加密
- request.interceptors.request.use(config => {
- config.headers['Content-Type'] = 'application/json;charset=utf-8';
-
- // config.headers['token'] = user.token; // 设置请求头
- return config
- }, error => {
- return Promise.reject(error)
- });
-
- // response 拦截器
- // 可以在接口响应后统一处理结果
- request.interceptors.response.use(
- response => {
- let res = response.data;
- // 如果是返回的文件
- if (response.config.responseType === 'blob') {
- return res
- }
- // 兼容服务端返回的字符串数据
- if (typeof res === 'string') {
- res = res ? JSON.parse(res) : res
- }
- return res;
- },
- error => {
- console.log('err' + error) // for debug
- return Promise.reject(error)
- }
- )
-
-
- export default request
-
设置request为全局变量:
在vue2中用prototype设置,vue3中可以用app.config.globalProperties
来代替prototype
(94条消息) vue 3.0 prototype 替代用法_寻ing的博客-CSDN博客_vue3 prototype
我们使用axios后可以看到前后代码对比
使用前:
- fetch("http://localhost:8081/page?pageNum="+this.pageNum+"&pageSize="+this.pageSize+"&username="+this.username
- +"&email="+this.email+"&address="+this.address).then(res => res.json()).then(res => {
- console.log(res)
- this.tableData=res.data
- this.total=res.total
- })
使用后:
- request.get("http://localhost:8081/page",{
- params:{
- pageNum:this.pageNum,
- pageSize:this.pageSize,
- username:this.username,
- email:this.email,
- address:this.address
- }
- }).then(res => {
- console.log(res)
- this.tableData= res.data
- this.total = res.total
-
- })
变得更加简洁,而且达到相同的功能效果
在查询后为了回复原来的页面,增加一个重置按钮
编写reset方法,思路就是把表单清空,并重新渲染页面,超级简单
- reset(){
- this.username=""
- this.email=""
- this.address=""
- this.load()
- }
dialog对话框编写:
在elementplus官网黏贴代码
Dialog 对话框 | Element Plus (element-plus.org)
- <el-dialog
- v-model="dialogVisible"
- title="Tips"
- width="30%"
- :before-close="handleClose"
- >
- <span>This is a message</span>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogVisible = false">Cancel</el-button>
- <el-button type="primary" @click="dialogVisible = false">
- Confirm
- </el-button>
- </span>
- </template>
- </el-dialog>
选择下面的嵌套表单的代码
- <el-dialog v-model="dialogTableVisible" title="Shipping address">
- <el-table :data="gridData">
- <el-table-column property="date" label="Date" width="150" />
- <el-table-column property="name" label="Name" width="200" />
- <el-table-column property="address" label="Address" />
- </el-table>
- </el-dialog>
-
- <!-- Form -->
- <el-button text @click="dialogFormVisible = true">
- open a Form nested Dialog
- </el-button>
-
- <el-dialog v-model="dialogFormVisible" title="Shipping address">
- <el-form :model="form">
- <el-form-item label="Promotion name" :label-width="formLabelWidth">
- <el-input v-model="form.name" autocomplete="off" />
- </el-form-item>
- <el-form-item label="Zones" :label-width="formLabelWidth">
- <el-select v-model="form.region" placeholder="Please select a zone">
- <el-option label="Zone No.1" value="shanghai" />
- <el-option label="Zone No.2" value="beijing" />
- </el-select>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogFormVisible = false">Cancel</el-button>
- <el-button type="primary" @click="dialogFormVisible = false">
- Confirm
- </el-button>
- </span>
- </template>
- </el-dialog>
绑定新增按钮的事件handleAdd
编写确认按钮的事件save
在这之前要先把接口写好
这里写一个业务层的save接口,然后放在controller里调用即可
然后我们设置id为自增规则,并且表数据为倒叙排序,此时我们新增数据功能就完成了:
注意:若想让数据按id倒叙排序,不能并列式的写LambdaQuery,要单独起一行
我们输入数据即可在数据库中插入数据(id不是随机且自增)
接下来我们来实现编辑按钮:
在vue3中不能使用 slot-scope 在vue3中用#相当于vue2中的slot=
(94条消息) vue3的slot插槽用法,`slot-scope` are deprecated_浩星的博客-CSDN博客_`slot-scope` are deprecated
这个时候我们就可以打开这个数据的el-dialog 点击保存即可完成编辑
删除:
编写业务层接口:
这里写错了,应该用RemoveById方法
编写控制层的接口:
绑定删除按钮 注意要加id,血的教训
增加一个气泡弹出窗口用来确定是都真正删除
- <!-- 确认组件-->
- <el-popover :visible="visible" placement="top" :width="160" class="ml-5">
-
- <p>您确定删除吗?</p>
- <div style="text-align: right; margin: 0">
- <el-button size="small" text @click="visible = false">我再想想</el-button>
- <el-button size="small" type="primary" @click="handleDelete(scope.row.id)"
- >确认</el-button
- >
- </div>
-
- <template #reference>
- <el-button type="danger" >删除
- <el-icon><remove></remove></el-icon>
- </el-button>
- </template>
- </el-popover>
注意不要忘了在templete标签里写#reference 不然按钮会不显示
多选:
在e-table标签下加入一行代码,并且在e-table标签里写入
@selection-change="handleSelectionChange
之后编写批量删除的接口
- //批量删除的接口
- @DeleteMapping("/del/batch")
- public boolean deleteBatch(@RequestBody List<Integer> ids){
- return userService.removeByIds(ids);
- }
在vue里编写delBatch方法
- delBatch(){
- let ids = this.multipleSelection.map(v => v.id)
- console.log(ids)//[{}.{}.{}] => [1,2,3]
- request.delete("http://localhost:8081/del/batch",{data:ids}).then(res => {
- if(res){
- this.$message.success("批量删除成功")
-
- }else{
- this.$message.error(("批量删除失败"))
- }
- this.load();
- })
- }
设置批量删除气泡弹窗,并绑定事件
-
- <!-- 确认组件-->
- <el-popover :visible="visible" placement="top" :width="160" class="ml-5">
-
- <p>您确定批量删除数据吗?</p>
- <div style="text-align: right; margin: 0">
- <el-button size="small" text @click="visible = false">我再想想</el-button>
- <el-button size="small" type="primary" @click="delBatch"
- >确认</el-button
- >
- </div>
-
- <template #reference>
- <el-button type="danger" >批量删除
- <el-icon><remove></remove></el-icon>
- </el-button>
- </template>
- </el-popover>
效果:
优化:
发现:如果不把load()重新加载数据放在最后一行,在新增操作保存后多选数据气泡窗口可能不显示
新增多选按钮,点击出现多选框,再次点击隐藏
给多选框绑定v-if
<el-table-column v-if="letapear" type="selection" width="55" />
将letapear初始值默认为false
设置多选按钮 用双括号绑定名称
- <!-- 多选按钮-->
- <el-button type="info" @click="Apearselection">{{duoxuan}}
- <el-icon><CirclePlus></CirclePlus></el-icon>
- </el-button>
编写方法:
- Apearselection(){
- if(!this.letapear){
- this.letapear=true;
- this.duoxuan="取消多选"
- }else{
- this.letapear=false;
- this.duoxuan="多选"
- }
-
- }
效果:
---------------->
1、封装侧边栏
新建一个Aside.vue将以下代码(e-menu)从menage.vue移动到里面
- <el-menu :default-openeds="['1', '3']" style="height: 100%;overflow-x:hidden;border-right-color: transparent"
- background-color="rgb(48,65,86)"
- text-color="#fff"
- active-text-color="#ffd04b"
- :collapse-transition="false"
- :collapse="isCollapse"
- >
- <div style="height: 60px;line-height: 60px;text-align: center">
- <img src="../assets/logo.png" alt="" style="width: 20px;position: relative;top:5px;margin-right: 5px">
-
- <b v-show="!isCollapse" style="color: white">后台管理系统</b>
- </div>
- <el-sub-menu index="1">
- <template #title>
- <el-icon>
- <message></message>
- </el-icon>
- <span>导航一</span>
- </template>
- <el-menu-item-group>
- <template #title>Group 1</template>
- <el-menu-item index="1-1">Option 1</el-menu-item>
- <el-menu-item index="1-2">Option 2</el-menu-item>
- </el-menu-item-group>
- <el-menu-item-group title="Group 2">
- <el-menu-item index="1-3">Option 3</el-menu-item>
- </el-menu-item-group>
- <el-sub-menu index="1-4">
- <template #title>Option4</template>
- <el-menu-item index="1-4-1">Option 4-1</el-menu-item>
- </el-sub-menu>
- </el-sub-menu>
- <el-sub-menu index="2">
- <template #title>
- <el-icon>
- <Menu></Menu>
-
- </el-icon>
- <span>导航二</span>
- </template>
- <el-menu-item-group>
- <template #title>Group 1</template>
- <el-menu-item index="2-1">Option 1</el-menu-item>
- <el-menu-item index="2-2">Option 2</el-menu-item>
- </el-menu-item-group>
- <el-menu-item-group title="Group 2">
- <el-menu-item index="2-3">Option 3</el-menu-item>
- </el-menu-item-group>
- <el-sub-menu index="2-4">
- <template #title>Option 4</template>
- <el-menu-item index="2-4-1">Option 4-1</el-menu-item>
- </el-sub-menu>
- </el-sub-menu>
- <el-sub-menu index="3">
- <template #title>
- <el-icon>
- <Setting></Setting>
- </el-icon>
- <span>导航三</span>
- </template>
- <el-menu-item-group>
- <template #title>Group 1</template>
- <el-menu-item index="3-1">Option 1</el-menu-item>
- <el-menu-item index="3-2">Option 2</el-menu-item>
- </el-menu-item-group>
- <el-menu-item-group title="Group 2">
- <el-menu-item index="3-3">Option 3</el-menu-item>
- </el-menu-item-group>
- <el-sub-menu index="3-4">
- <template #title>Option 4</template>
- <el-menu-item index="3-4-1">Option 4-1</el-menu-item>
- </el-sub-menu>
- </el-sub-menu>
- </el-menu>
然后再AsideView里面编写props将用到的原来组件的参数传入进来,并且编写components将原来用到的组件传递过来
然后在原来的界面引入AsideView组件,并且使用该组件
e-side我们就转移完毕了
然后我们转移e-header
将e-header代码转移到HeaderView里面,然后将style样式做部分迁移,因为转移后,都放在外面不好使。
- <div style="text-align: left; font-size: 12px; line-height: 60px;
- display: flex">
-
- <div style="flex:1;font-size: 18px">
- <el-icon style="cursor: pointer" @click="collapse">
- <Fold v-if="isCollapse"></Fold>
- <Expand v-else></Expand>
- </el-icon>
- </div>
- <div class="toolbar">
-
- <el-dropdown style="width: 100px;cursor: pointer" >
- <span style="line-height: 60px">Tom
- <el-icon style="margin-left: 5px">
- <ArrowDownBold></ArrowDownBold>
- </el-icon>
- </span>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item>个人信息</el-dropdown-item>
- <el-dropdown-item>退出</el-dropdown-item>
- <el-dropdown-item>Delete</el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
-
- </div>
- </div>
然后本来collapse方法在原来的主vue里面,所以我们要定义一个方法,并且通过$emit
将本组件的请求发送过去:
然后再在主vue引入我们的header,并且在header里面连接方法
这样header就拆装完毕了
之后我们再把e-main拿出来单独封装
建立一个TableView.vue
之后将e-main里面的代码放在里面
- <template>
- <div style="margin-bottom: 30px">
- <el-breadcrumb separator="/">
- <el-breadcrumb-item :to="{ path: '/' }">主页</el-breadcrumb-item>
- <el-breadcrumb-item :to="{path: '/new'}">用户管理</el-breadcrumb-item>
- <el-breadcrumb-item>promotion list</el-breadcrumb-item>
- <el-breadcrumb-item>promotion detail</el-breadcrumb-item>
- </el-breadcrumb>
- </div>
-
- <div style="margin: 10px 0;text-align: left" >
- <!-- 名称搜索-->
- <el-input style="width: 200px" type="text" placeholder="请输入名称" v-model="username">
- <template #prefix>
- <el-icon class="el-input__icon">
- <search></search>
- </el-icon>
- </template>
- </el-input>
- <!-- 邮箱输入-->
- <el-input style="width: 200px" type="text" placeholder="请输入邮箱" class="ml-5" v-model="email">
- <template #prefix>
- <el-icon class="el-input__icon">
- <message></message>
- </el-icon>
- </template>
- </el-input>
- <!-- 地址搜索-->
- <el-input style="width: 200px" type="text" placeholder="请输入地址" class="ml-5" v-model="address">
- <template #prefix>
- <el-icon class="el-input__icon">
- <location></location>
- </el-icon>
- </template>
- </el-input>
- <!-- 搜索按钮-->
- <el-button class="ml-5" type="" style="color: orangered" @click="load">搜索</el-button>
- <el-button class="mr-5" type="warning" style="color: white" @click="reset">重置</el-button>
- </div>
-
- <div style="margin: 10px 0;text-align: left">
- <el-button type="primary" @click="handleAdd">新增
- <el-icon><CirclePlus></CirclePlus></el-icon>
- </el-button>
-
- <!-- 多选按钮-->
- <el-button type="info" @click="Apearselection">{{duoxuan}}
- <el-icon><CirclePlus></CirclePlus></el-icon>
- </el-button>
- <!-- 确认组件-->
- <el-popover :visible="visible" placement="top" :width="160" class="ml-5">
-
- <p>您确定批量删除数据吗?</p>
- <div style="text-align: right; margin: 0">
- <el-button size="small" text @click="visible = false">我再想想</el-button>
- <el-button size="small" type="primary" @click="delBatch"
- >确认</el-button
- >
- </div>
-
- <template #reference>
- <el-button type="danger" >批量删除
- <el-icon><remove></remove></el-icon>
- </el-button>
- </template>
- </el-popover>
-
- <el-button type="primary">导入
- <el-icon><bottom></bottom></el-icon>
- </el-button>
- <el-button type="primary">导出
- <el-icon><top></top></el-icon>
- </el-button>
- </div>
- <!-- <el-scrollbar>-->
-
- <el-table :data="tableData" border stripe height="500px" max-height="350px"
- @selection-change="handleSelectionChange">
- <!-- 多选框-->
- <el-table-column v-if="letapear" type="selection" width="55" />
-
- <el-table-column prop="id" label="ID" width="50" />
- <el-table-column prop="username" label="用户名" width="140" />
- <el-table-column prop="nickname" label="昵称" width="120" />
- <el-table-column prop="address" label="地址" />
- <el-table-column prop="email" label="邮箱" />
- <el-table-column prop="phone" label="电话" />
-
- <el-table-column label="操作" >
- <el-table-column>
- <template #default="scope">
- <el-button type="success" @click="handleEdit(scope.row)" >编辑
- <el-icon><edit></edit></el-icon>
- </el-button>
-
- <!-- 确认组件-->
- <el-popover :visible="visible" placement="top" :width="160" class="ml-5">
-
- <p>您确定删除吗?</p>
- <div style="text-align: right; margin: 0">
- <el-button size="small" text @click="visible = false">我再想想</el-button>
- <el-button size="small" type="primary" @click="handleDelete(scope.row.id)"
- >确认</el-button
- >
- </div>
-
- <template #reference>
- <el-button type="danger" >删除
- <el-icon><remove></remove></el-icon>
- </el-button>
- </template>
- </el-popover>
-
- </template>
- </el-table-column>
- </el-table-column>
-
- </el-table>
- <!-- 页尾-->
- <div style="padding: 10px 0">
- <el-pagination
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- :current-page="pageNum"
- :page-size="pageSize"
- :page-sizes="[2, 5, 10, 20]"
- :small="small"
- :disabled="disabled"
- :background="background"
- layout="total, sizes, prev, pager, next, jumper"
- :total="total">
-
- </el-pagination>
- </div>
- <!-- </el-scrollbar>-->
-
-
-
- <el-dialog title="用户信息" v-model="dialogFormVisible" width="30%">
- <el-form :model="form" label-width="80px" size="small">
- <el-form-item label="用户名" >
- <el-input v-model="form.username" autocomplete="off" />
- </el-form-item>
- <el-form-item label="昵称" >
- <el-input v-model="form.nickname" autocomplete="off" />
- </el-form-item>
- <el-form-item label="邮箱" >
- <el-input v-model="form.email" autocomplete="off" />
- </el-form-item>
- <el-form-item label="电话" >
- <el-input v-model="form.phone" autocomplete="off" />
- </el-form-item>
- <el-form-item label="地址" >
- <el-input v-model="form.address" autocomplete="off" />
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogFormVisible = false,this.load">取消</el-button>
- <el-button type="primary" @click="save">
- 确认
- </el-button>
- </span>
- </template>
- </el-dialog>
- </template>
-
- <script>
- import {Bottom, CirclePlus, Edit, Location, Message, Remove, Search, Top} from "@element-plus/icons";
-
-
- export default {
- name: "TableView",
- components: {
- Edit,
- Top,
- Bottom,
- Remove,
- CirclePlus,
- Location, Search,
- Message,
- },
- data(){
- // const item = {
- // date: '2016-05-02',
- // name: 'Tom',
- // address: 'No. 189, Grove St, Los Angeles',
- // };
-
- return {
- // tableData : (Array.from({ length: 20 }).fill(item)),
- tableData :[],
- pageNum:1,
- pageSize:2,
-
- total:0,
- username:"",
- email:"",
- address:"",
- isCollapse:true,
- sidewidth:200,
- dialogFormVisible:false,
- form:{},
- multipleSelection:[],
- letapear:false,
- duoxuan:"多选"
- }
- },
- created() {
- //请求分页查询数据
- this.load()
-
- },
- methods:{
- load(){
- this.request.get("http://localhost:8081/page",{
- params:{
- pageNum:this.pageNum,
- pageSize:this.pageSize,
- username:this.username,
- email:this.email,
- address:this.address
- }
- }).then(res => {
- console.log(res)
- this.tableData= res.data
- this.total = res.total
- })
- },
- save(){
- this.request.post("http://localhost:8081/save",this.form).then(res => {
- if(res){
- this.$message.success("保存成功")
-
- }else{
- this.$message.error(("保存失败"))
-
- }
- this.load();
- this.dialogFormVisible=false;
- })
- },
- handleSelectionChange(val){
- // console.log(val)
- this.multipleSelection = val;
-
- },
- handleAdd(){
- this.dialogFormVisible=true;
- this.form={}
- },
- handleEdit(row){
- this.dialogFormVisible=true;
- this.form = Object.assign({},row);
-
- },
- handleDelete(id){
- this.request.delete("http://localhost:8081/"+id).then(res => {
- if(res){
- this.$message.success("删除成功")
-
- }else{
- this.$message.error(("删除失败"))
- }
- this.load();
- })
- },
- delBatch(){
- let ids = this.multipleSelection.map(v => v.id)
- console.log(ids)//[{}.{}.{}] => [1,2,3]
- this.request.delete("http://localhost:8081/del/batch",{data:ids}).then(res => {
- if(res){
- this.$message.success("批量删除成功")
-
- }else{
- this.$message.error(("批量删除失败"))
- }
- this.load();
- })
- },
- Apearselection(){
- if(!this.letapear){
- this.letapear=true;
- this.duoxuan="取消多选"
- }else{
- this.letapear=false;
- this.duoxuan="多选"
- }
-
- },
- reset(){
- this.username=""
- this.email=""
- this.address=""
- this.load()
- },
- handleSizeChange(pageSize){
- this.pageSize = pageSize
- this.load()
- },
- handleCurrentChange(pageNum){
- this.pageNum=pageNum
- this.load()
- }
- }
- }
- </script>
-
- <style scoped>
-
- </style>
再把meanagor组件的大部分方法和属性和组件(除了折叠的方法,和用到的属性,其它都迁移到TableView里面)
然后把TableView放在路由里面:作为
它的子路由,这样就可以通过主路由加载子路由的方式拼装整个页面,这样侧边栏就会一直出现在页面里供我们操作
我们也定义一个home放在里面当子路由:
设置重定向:
之后我们就可以通过路由入口的方式把路由入口router-view放在父组件需要加载子组件的地方
这样我们就可以通过访问子路由的方式 让整个页面加载
至此我们就把整个menager组件的所有功能拆分开成不同的组件,这样方便管理,方便维护更改
然后我们设置侧边栏点击可以跳转我们之前设置的两个路由界面:home,table
这个很简单我们只需要更改el-menu-item标签里的 index即可
不过在此之前一定要记得把e-menu里面的router属性自己手动设为true ,它默认为false
这样我们就实现了点击侧边栏跳转到我们设置的路由
之后我们实现导入导出功能
这个功能要依赖于hutool,所以我们导入以下依赖
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- <version>5.7.20</version>
- </dependency>
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi-ooxml</artifactId>
- <version>4.1.2</version>
- </dependency>
hutool官网;https://www.wpsshop.cn/w/盐析白兔/article/detail/225805
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。