ElementUI
ElementUI是一个网页组件库,使用组件库大大提高了前端页面的制作效率,同时和Vue框架也很适配
官网
安装
npm安装
npm install element-ui -S
引入组件
在main.js中导入
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
//引入组件
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
//使用element-ui的组件
Vue.use(Element)
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
测试
<el-button>按钮</el-button>
EL布局基本样式
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-container>
<el-header>Header</el-header>
<el-main>Main</el-main>
<el-footer>Footer</el-footer>
</el-container>
</el-container>
<style>
.el-header, .el-footer {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
background-color: #E9EEF3;
color: #333;
text-align: center;
line-height: 160px;
}
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
.el-container:nth-child(7) .el-aside {
line-height: 320px;
}
</style>
用EL制作表格
子组件
在父组件中使用即可
<el-table></el-table>
表格标签
<el-table-column></el-table-column>
表格列标签
<template>
<div>
<el-table :data="res">
<!--定义表格列-->
<el-table-column label="编号" prop="eid"></el-table-column>
<el-table-column label="姓名" prop="empName"></el-table-column>
<el-table-column label="年龄" prop="age"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="薪水" prop="salary"></el-table-column>
<el-table-column label="生日" prop="birthday"></el-table-column>
<el-table-column label="部门" prop="deptno"></el-table-column>
</el-table>
</div>
</template>
<script>
import _axios from "@/utils/myaxios";
const options = {
async mounted(){
const resp = await _axios.post("/api/demo3",{
name:'os467',
password:'os4670'
});
this.res = resp.data;
},
data:() =>{
return {
res:[]
}
}
}
export default options;
</script>
这里的性别数据接收到的是1和2,需要重新规范,使用
<el-table-column label="性别" prop="sex" :formatter="sexRole">
绑定formatter的属性
formatter
属性,它用于格式化指定列的值,接受一个Function
,会传入两个参数:row
和column
,可以根据自己的需求进行处理
methods:{
sexRole(row){
return row.sex == '1'?'男':'女';
}
}
EL分页组件
total: 指定一共有多少条记录
page-size: 指定每页有多少条数据
current-page: 指定当前页是第几页
layout: 需要展示的部分
prev
:前一页,pager
:页码,next
:下一页,jumper
:页码输入框,->
:靠右,total
:总记录条数
sizes: 默认隐藏的属性,控制每页显示条数
page-sizes: 与size配合使用,可以自定义分页条数
<el-pagination
:total="4"
:page-size="2"
:current-page="1"
layout="prev,pager,next,sizes,jumper,->,total"
:page-sizes="[5,10,15,20]"
></el-pagination>
加
:
的属性,就是v-bind
,其实就是要去js中查找数据,没加:
的值其实右边的值就是最终想要的值如果无法找到绑定的值,那么就会将这个值当成表达式进行解析
分页查询实现
<template>
<div>
<el-table :data="res">
<!--定义表格列-->
<el-table-column label="编号" prop="eid"></el-table-column>
<el-table-column label="姓名" prop="empName"></el-table-column>
<el-table-column label="年龄" prop="age"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="薪水" prop="salary"></el-table-column>
<el-table-column label="生日" prop="birthday"></el-table-column>
<el-table-column label="部门" prop="deptno"></el-table-column>
</el-table>
<el-pagination
:total="total"
:page-size="pageSize"
:current-page="currentPage"
layout="prev,pager,next,sizes,jumper,->,total"
:page-sizes="[5,10,15,20]"
@current-change="currentChange"
@size-change="sizeChange"
></el-pagination>
</div>
</template>
<script>
import _axios from "@/utils/myaxios";
const options = {
mounted(){
this.query();
},
methods:{
currentChange(currentPage){
this.queryDto.currentPage = currentPage;
this.query();
},
sizeChange(pageSize){
this.queryDto.pageSize = pageSize;
this.query();
},
async query(){
const resp = await _axios.post("/api/demo4/page",{
name:'os467',
password:'os4670',
currentPage:this.queryDto.currentPage,
pageSize:this.queryDto.pageSize
});
this.res = resp.data.records;
this.total = resp.data.total;
}
},
data:() =>{
return {
res:[],
queryDto:{
currentPage:1,
pageSize:5
},
total:0
}
}
}
export default options;
</script>
后端逻辑
@Override
public PageVo getByPage(DemoDto demoDto) {
Long currentPage = demoDto.getCurrentPage();
Long pageSize = demoDto.getPageSize();
//分页工具
Page empPage = new Page<Emp>(currentPage,pageSize);
Page page = page(empPage);
return new PageVo(page.getRecords(),page.getTotal());
}
模糊查询
使用v-model实现表单数据绑定
<template>
<div>
<div>
<el-form>
<el-input v-model="queryDto.empName" placeholder="请输入员工姓名" size="mini"/>
<el-select v-model="queryDto.sex" placeholder="请选择性别" size="mini">
<el-option value="1" label="男"/>
<el-option value="0" label="女"/>
</el-select>
<el-date-picker v-model="queryDto.birthday" placeholder="请选出生日期" size="mini"/>
<el-button type="primary" size="mini">搜索</el-button>
</el-form>
</div>
</div>
</template>
<script>
import _axios from "@/utils/myaxios";
const options = {
//数据绑定
data:() =>{
return {
queryDto:{
currentPage:1,
pageSize:5,
empName:'',
sex:'',
birthday:''
}
}
}
}
export default options;
</script>
<style>
.el-select--mini,
.el-input--mini {
width: 190px;
margin: 10px 10px 0 0;
}
</style>
Cascader级联选择器
使用el-cascader标签
绑定ops数据
选择器对象属性
value
: 唯一表示值label
: 展示的内容children
: 子菜单选择器,子菜单也可以有此属性
<template>
<div>
<el-cascader :options="ops">
</el-cascader>
</div>
</template>
<script>
const options = {
data(){
return {
ops:[
/*value:唯一表示值,label:展示的内容*/
{
value:100,label:'主页',
children:[
{value:101,label:'子菜单1'},
{value:102,label:'子菜单2'},
{value:103,label:'子菜单3'}
]
}
]
}
}
}
export default options;
</script>
一般来说我们都是通过访问后端来获取数据,这里我们演示从后台获取数据
前端组件
<template>
<div>
<el-cascader :options="ops">
</el-cascader>
</div>
</template>
<script>
import _axios from "@/utils/myaxios";
const options = {
async mounted() {
let ops = await _axios.get('/api/getMenu');
this.ops = ops.data;
},
data(){
return {
ops:[]
}
}
}
export default options;
</script>
后端逻辑
常规数组遍历设置父子关系
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
/**
* 查询所有菜单
* @return
*/
@Override
public List<MenuVo> getMenu() {
//查询所有菜单列表
List<Menu> menuList = list();
//构建菜单树
List<MenuVo> menuVoTrees = menuList.stream().filter(menu -> menu.getPid() == null).map(
menu -> {
MenuVo menuVo = new MenuVo();
buildRootMenu(menuList,menu,menuVo);
return menuVo;
}
).collect(Collectors.toList());
return menuVoTrees;
}
/**
* 为根菜单设置信息,并且设置子菜单树
* @param menuList
* @param parent
* @param parentVo
*/
private void buildRootMenu(List<Menu> menuList, Menu parent, MenuVo parentVo) {
//为根菜单设置信息
parentVo.setValue(parent.getMid());
parentVo.setLabel(parent.getLabel());
//设置根菜单的子菜单信息
buildChildrenMenu(menuList,parent,parentVo);
}
/**
* 设置子菜单
* @param menuList
* @param parent
*/
private void buildChildrenMenu(List<Menu> menuList, Menu parent,MenuVo parentVo) {
Integer pid = parent.getMid();
ArrayList<MenuVo> children = new ArrayList<>();
for (Menu menu : menuList) {
//只添加当前父菜单的子菜单
if (menu.getPid() == pid){
//构建子菜单并且添加子属性
MenuVo childrenMenuVo = new MenuVo();
buildChildrenMenu(menuList,menu,childrenMenuVo);
//拷贝符合条件的menu数据到vo对象中
childrenMenuVo.setValue(menu.getMid());
childrenMenuVo.setLabel(menu.getLabel());
//添加vo数据到子菜单列表中
children.add(childrenMenuVo);
}
}
//存在数据则为父菜单添加子菜单
if (children.size() > 0){
parentVo.setChildren(children);
}
}
}
这种方法为递归设置子对象,需要多次循环菜单列表匹配需要设置的子对象
使用map集合的方法
由于map集合本身具有树状结构因此减少了遍历的次数,一次遍历即可,更加高效
List<Menu> menuList = menuService.list();
Iterator<Menu> menuIterator = menuList.iterator();
//用于存放菜单vo数据的集合,提高查找效率
Map<Integer, Menu> menuHashMap = new HashMap<>();
while (menuIterator.hasNext()){
Menu next = menuIterator.next();
//存入集合
menuHashMap.put(next.getMid(),next);
}
//遍历集合对象
for (Menu menu : menuHashMap.values()) {
//获取对应pid
Integer pid = menu.getPid();
//获取父对象
Menu parent = menuHashMap.get(pid);
if (parent != null){
//如果父对象是第一次设置子对象列表,则新创建一个子对象列表
if (parent.getChildren() == null){
parent.setChildren(new ArrayList<Menu>());
}
//向父对象中添加子对象数据
parent.getChildren().add(menu);
}
}
菜单选项
官网样式
支持的图标库
<el-menu
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<el-menu-item>
<span slot="title">
<i class="el-icon-partly-cloudy"/>菜单1
</span>
</el-menu-item>
<el-menu-item>
<span slot="title">
<i class="el-icon-place"/>菜单2
</span>
</el-menu-item>
<el-menu-item>
<span slot="title">
<i class="el-icon-pear"/>菜单3
</span>
</el-menu-item>
</el-menu>
设置二级菜单
- router:是否使用 vue-router 的模式,启用该模式会在激活导航时以 index 作为 path 进行路由跳转
<el-menu
router
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<el-submenu index="1">
<span slot="title">
<i class="el-icon-partly-cloudy"/>菜单1
</span>
<el-menu-item index="/p1">
子项1
</el-menu-item>
<el-menu-item index="/p2">
子项2
</el-menu-item>
<el-menu-item index="/p3">
子项3
</el-menu-item>
</el-submenu>
<el-submenu index="2">
<span slot="title">
<i class="el-icon-place"/>菜单2
</span>
<el-menu-item index="/p4">
子项1
</el-menu-item>
<el-menu-item index="/p5">
子项2
</el-menu-item>
<el-menu-item index="/p6">
子项3
</el-menu-item>
</el-submenu>
<el-submenu index="3">
<span slot="title">
<i class="el-icon-pear"/>菜单3
</span>
<el-menu-item index="/p7">
子项1
</el-menu-item>
<el-menu-item index="/p8">
子项2
</el-menu-item>
<el-menu-item index="/p9">
子项3
</el-menu-item>
</el-submenu>
</el-menu>
关于菜单展开问题:需要对父菜单的index进行设置,必须不同,这样才不会点开一个菜单,使得所有菜单展开
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com