ElementUI

  1. ElementUI
    1. 安装
    2. 引入组件
      1. EL布局基本样式
      2. 用EL制作表格
      3. EL分页组件
      4. 模糊查询
    3. Cascader级联选择器
    4. 菜单选项

ElementUI

ElementUI是一个网页组件库,使用组件库大大提高了前端页面的制作效率,同时和Vue框架也很适配

官网

Element - 网站快速成型工具

安装

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,会传入两个参数:rowcolumn,可以根据自己的需求进行处理
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);
            }
            
        }

菜单选项

官网样式

组件-菜单 | Element

支持的图标库

组件-图标 | Element

  <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

文章标题:ElementUI

字数:2.8k

本文作者:Os467

发布时间:2022-10-18, 21:17:36

最后更新:2022-10-19, 22:52:50

原始链接:https://os467.github.io/2022/10/18/ElementUI/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏