前端学不好 不妨来学一下Element UI 让你的网站快速成型

1,271 阅读9分钟

什么是Element UI

  1. Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库
    1. Element UI是基于Vue 2.0的
    2. Element UI 提供一组组件
    3. Element UI 提供组件的参考实例, 直接复制
  2. 官方网站:

element.eleme.cn/#/zh-CN/com…

搭建环境

创建项目

步骤一: 通过 vue-cli创建项目

vue create eui01

步骤二:运行项目

整合1:插件

安装好vue项目后,进入到项目目录,执行命令

vue add element

整合步骤1:确定引入方式(全部引入、按需引入)

整合

整合2:安装element-ui插件

npm i element-ui --save

整合:element-ui引入

  1. 官方提供了2种引入方式:完整引入、按需引入

    1. 完整引入:引入了eui所有的组件,学习时/开发时常用
    2. 按需引入:引入需要的组件,生产环境下使用。
  2. 完整引入

    1. 1. 导入 element ui 组件库
    2. 2. 导入 element ui css样式
    3. 3. 并将element ui 注册给vue

 

import 'element-ui/lib/theme-chalk/index.css'

import App from './App.vue'

import router from './router'

import store from './store'

import ElementUI from 'element-ui'

Vue.config.productionTip = false

3.布局容器

布局容器

  1. 使用element-ui的布局容器(Container) 进行页面布局。对页面进行划分(上、下、左、中)
  2. 官方文档 : element.eleme.cn/#/zh-CN/com…

用于布局的容器组件,方便快速搭建页面的基本结构:

<el-container>:外层容器。当子元素中包含 <el-header> 或 <el-footer> 时,全部子元素会垂直上下排列,否则会水平左右排列。

<el-header>:顶栏容器。

<el-aside>:侧边栏容器。

<el-main>:主要区域容器。

<el-footer>:底栏容器。

以上组件采用了 flex 布局,使用前请确定目标浏览器是否兼容。此外,<el-container> 的子元素只能是后四者,后四者的父元素也只能是 <el-container>

步骤一: 修改src/main.js 导入 element-ui 样式和组件

import 'element-ui/lib/theme-chalk/index.css'

import App from './App.vue'

import router from './router'

import store from './store'

import ElementUI from 'element-ui'

Vue.config.productionTip = false

步骤二: 删除 src/App.vue所有内容, 拷贝布局模板和样式

      <el-header>Header</el-header>

      <el-main>Main</el-main>

      <el-footer>Footer</el-footer>

  .el-header, .el-footer {

    background-color: #B3C0D1;

reset.css

布局页面完成后, 整个body会存在一圈空白, 开发中一般选择重新设置页面样式

步骤一: 百度搜索”reset.css” , 并创建 assets/app.css ,拷贝样式 (复制下面样式即可)

 

body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,th,td {

    border-collapse: collapse;

address,caption,cite,code,dfn,em,strong,th,var {

满屏填充

在App.vue中,添加样式

  html, body, .el-container {

4.导航条

需求

导航条

使用导航菜单(NavMenu) 完成导航条效果

官方文档 : element.eleme.cn/#/zh-CN/com…

          :default-active="$route.path"

          class="el-menu-demo"

          mode="horizontal"

          background-color="#545c64"

          text-color="#fff"

          active-text-color="#ffd04b"

          <el-menu-item index="/">首页</el-menu-item>

          <el-submenu index="2">

            <template slot="title">学生管理</template>

            <el-menu-item index="/studentList">学生列表</el-menu-item>

          <el-submenu index="3">

            <template slot="title">个人中心</template>

            <el-menu-item index="/login">登录</el-menu-item>

            <el-menu-item index="/register">注册</el-menu-item>

          <el-menu-item index="/cart">

          </el-menu-item>

        <router-view></router-view>

         版权所有 2006 - 2022 传智专修学院

  .el-header, .el-footer {

    background-color: #B3C0D1;

路由

点击”首页” 和 “购物车” 可以调整页面

步骤一: 修改 src/App.vue 设置路由视图

 

          class="el-menu-demo"

          mode="horizontal"

          background-color="#545c64"

          text-color="#fff"

          active-text-color="#ffd04b"

          <el-menu-item index="/">首页</el-menu-item>

          <el-submenu index="2">

            <template slot="title">学生管理</template>

            <el-menu-item index="/studentList">学生列表</el-menu-item>

          <el-submenu index="3">

            <template slot="title">个人中心</template>

            <el-menu-item index="/login">登录</el-menu-item>

            <el-menu-item index="/register">注册</el-menu-item>

          <el-menu-item index="/cart">

          </el-menu-item>

        <router-view></router-view>

         版权所有 2006 - 2020 传智专修学院

  .el-header, .el-footer {

    background-color: #B3C0D1;

步骤二: 编写测试组件(Home.vue和Cart.vue)

页面刷新导航选择问题

默认情况:点击后的默认效果

刷新页面, 导航条的选中状态消失

 修复: 修改 App.vue页面

          :default-active="$route.path"

          class="el-menu-demo"

          mode="horizontal"

          background-color="#545c64"

          text-color="#fff"

          active-text-color="#ffd04b"

页眉

        版权所有 2006 - 2022 传智专修学院

5.表格:查询列表

测试页面

基本表格

    <el-table :data="studentList" >

      <el-table-column prop="sid" label="编号" width="150"></el-table-column>

      <el-table-column prop="sname" label="姓名" width="150"></el-table-column>

      <el-table-column prop="gender" label="性别" width="150"></el-table-column>

      <el-table-column prop="age" label="年龄" width="150"></el-table-column>

表格修饰

    <el-table :data="studentList" stripe border >

      <el-table-column prop="sid" label="编号" width="150"></el-table-column>

多选

    <el-table :data="studentList" stripe border @selection-change="handleSelectionChange">

      <el-table-column type="selection" width="55"></el-table-column>

      <el-table-column prop="sid" label="编号" width="150"></el-table-column>

      <el-table-column prop="sname" label="姓名" width="150"></el-table-column>

      <el-table-column prop="gender" label="性别" width="150"></el-table-column>

      <el-table-column prop="age" label="年龄" width="150"></el-table-column>

    handleSelectionChange(val) {

      this.multipleSelection = val;  //保存选中的数据

      multipleSelection: [],  //多选,选中的数据

自定义模板

 

    <el-table :data="studentList" stripe border @selection-change="handleSelectionChange">

      <el-table-column type="selection" width="55"></el-table-column>

      <el-table-column prop="sid" label="编号" width="150"></el-table-column>

      <el-table-column prop="sname" label="姓名" width="150"></el-table-column>

      <el-table-column prop="gender" label="性别" width="150"></el-table-column>

      <el-table-column prop="age" label="年龄" width="150"></el-table-column>

      <el-table-column label="操作">

        <template slot-scope="scope">

          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>

          <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>

    handleSelectionChange(val) {

      this.multipleSelection = val;  //保存选中的数据

    handleEdit(index, row) {

      console.log(index, row);

    handleDelete(index, row) {

      console.log(index, row);

      multipleSelection: [],  //多选,选中的数据
  1. 练习:展示“爱好”信息
          hobbies: ['抽烟','喝酒','烫头']

          hobbies: ['抽烟','烫头']

    <el-table :data="studentList" stripe border @selection-change="handleSelectionChange">

      <el-table-column type="selection" width="55"></el-table-column>

      <el-table-column prop="sid" label="编号" width="150"></el-table-column>

      <el-table-column prop="sname" label="姓名" width="150"></el-table-column>

      <el-table-column prop="gender" label="性别" width="150"></el-table-column>

      <el-table-column prop="age" label="年龄" width="150"></el-table-column>

      <el-table-column label="爱好" >

        <template slot-scope="scope">

          <el-tag type="warning" v-for="(hobby,index) in scope.row.hobbies" :key="index">{{hobby}}</el-tag>

      <el-table-column label="操作">

        <template slot-scope="scope">

          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>

          <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>

    handleSelectionChange(val) {

      this.multipleSelection = val;  //保存选中的数据

    handleEdit(index, row) {

      console.log(index, row);

    handleDelete(index, row) {

      console.log(index, row);

      multipleSelection: [],  //多选,选中的数据

          hobbies: ['抽烟','喝酒','烫头']

          hobbies: ['抽烟','烫头']

总结

标签

描述

属性

描述

<el-table>

用于绘制表格

data

需要显示的数据

stripe

创建带斑马纹的表格

border

带边框表格

<el-table-column>

用于设置表格的列

label

列名

prop

对应对象中的键名

width

列宽

type

selection 多选框

<template slot-scope="scope">

内容嵌入,scope

条件查询

    <el-form :inline="true" :model="studentVo" size="mini" class="demo-form-inline">

      <el-form-item label="班级">

        <el-select v-model="studentVo.cid" placeholder="请选择班级">

          <el-option label="Java12班" value="c001"></el-option>

          <el-option label="Java34班" value="c002"></el-option>

      <el-form-item label="姓名">

        <el-input v-model="studentVo.name" placeholder="请输入姓名"></el-input>

      <el-form-item label="年龄">

        <el-col :span="11">

          <el-input v-model="studentVo.startAge" placeholder="请输入开始年龄"></el-input>

        <el-col class="line" :span="2">-</el-col>

        <el-col :span="11">

          <el-input v-model="studentVo.endAge" placeholder="请输入结束年龄"></el-input>

        <el-button type="primary" @click="onSubmit">查询</el-button>

分页条

      @size-change="handleSizeChange"

      @current-change="handleCurrentChange"

      :current-page="pageInfo.pageNum"

      :page-sizes="[1, 2, 5, 10]"

      :page-size="pageInfo.pageSize"

      layout="total, sizes, prev, pager, next, jumper"

      :total="pageInfo.total">

 6.表单

简单表单:登录

显示登录页面:Login.vue

登录表单效果

  <el-card class="box-card">

    <el-form :model="user" label-width="80px" ref="loginFormRef">

      <el-form-item label="用户名">

        <el-input v-model="user.username" prefix-icon="el-icon-user" placeholder="请输入用户名"></el-input>

      <el-form-item label="密码">

        <el-input v-model="user.password" prefix-icon="el-icon-lock" type="password" placeholder="请输入密码"></el-input>

        <el-button type="primary" @click="login">登录</el-button>

        <el-button type="info" @click="$refs.loginFormRef.resetFields()" >重置</el-button>

复杂表单:注册

 

  <el-card class="box-card">

    <el-form :model="user" label-width="80px" ref="loginFormRef">

      <el-form-item label="用户名">

        <el-input v-model="user.username" prefix-icon="el-icon-user" placeholder="请输入用户名"></el-input>

      <el-form-item label="密码">

        <el-input v-model="user.password" prefix-icon="el-icon-lock" type="password" placeholder="请输入密码"></el-input>

      <el-form-item label="确认密码">

        <el-input v-model="user.repassword" prefix-icon="el-icon-lock" type="password" placeholder="请再次输入密码"></el-input>

      <el-form-item label="生日">

        <el-date-picker v-model="user.birthday" type="date" placeholder="选择日期">

      <el-form-item label="学历">

        <el-select v-model="user.edu" placeholder="请选择你的学历">

          <el-option label="小班" value="xb"></el-option>

          <el-option label="中班" value="zb"></el-option>

          <el-option label="大班" value="db"></el-option>

          <el-option label="学前班" value="xqb"></el-option>

      <el-form-item label="性别">

        <el-radio-group v-model="user.gender">

          <el-radio label="男"></el-radio>

          <el-radio label="女"></el-radio>

        </el-radio-group>

      <el-form-item label="爱好">

        <el-checkbox-group v-model="user.hobbies">

          <el-checkbox label="抽烟" name="type"></el-checkbox>

          <el-checkbox label="喝酒" name="type"></el-checkbox>

          <el-checkbox label="烫头" name="type"></el-checkbox>

          <el-checkbox label="蹦迪" name="type"></el-checkbox>

        </el-checkbox-group>

      <el-form-item label="婚否">

        <el-switch v-model="user.marry"></el-switch>

      <el-form-item label="省市县">

          v-model="user.city"

          :options="cityList"

          ></el-cascader>

        <el-button type="primary" @click="login">登录</el-button>

        <el-button type="info" @click="$refs.loginFormRef.resetFields()" >重置</el-button>

        username: 'jack',

        password: '1234',

        repassword: '1234',

        birthday: '2020-10-07',

        hobbies: ['抽烟','烫头'],

        city: ['jiangsu', 'suqian', 'shuyang'],

          value: 'jiangsu',

              value: 'suqian',

              label: '宿迁',

              children: [

                  value: 'shuyang',

                  label: '沭阳',

                  value: 'siyang',

                  label: '泗阳',

              value: 'lianyungang',

              label: '连云港',

表单校验

 

设置校验规则、确定校验属性

编写校验规则

   校验属性: [  规则1,  规则2, .... ]

{ required: true, message: '请输入用户名', trigger: 'blur' },

{ min: 3, max: 5, message: 用户名长度必须3-5之间, trigger: 'blur' }


![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7c897791128c49a881ac858ff8dced8d~tplv-k3u1fbpfcp-zoom-1.image)
--------------------------------------------------------------------------------------------------------------------

提交表单时,校验

 ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bf3e3bfb63ed49ccb90ccc7a5e375dca~tplv-k3u1fbpfcp-zoom-1.image)

<el-form :model="user" :rules="rules" label-width="80px" ref="loginFormRef">

  <el-form-item label="用户名" prop="username">

    <el-input v-model="user.username" prefix-icon="el-icon-user" placeholder="请输入用户名"></el-input>

  <el-form-item label="密码" prop="password">

    <el-input v-model="user.password" prefix-icon="el-icon-lock" type="password" placeholder="请输入密码"></el-input>

    <el-button type="primary" @click="login">登录</el-button>

    <el-button type="info" @click="$refs.loginFormRef.resetFields()" >重置</el-button>

      { required: true, message: '请输入用户名', trigger: 'blur' },

      { min: 3, max: 5, message: `用户名长度必须3-5之间`, trigger: 'blur' }

      { required: true, message: '请输入密码', trigger: 'blur' },

      { min: 3, max: 5, message: `密码长度必须3-5之间`, trigger: 'blur' }

  this.$refs.loginFormRef.validate(valid => {

      console.info('通过')

       console.info('未通过')

自定义校验
-----

<el-card class="login-card">

  <el-form ref="loginForm" :model="user" :rules="rules" label-width="80px">

    <el-form-item label="用户名" prop="username">

      <el-input v-model="user.username" prefix-icon="el-icon-user" placeholder="请输入用户名" clearable></el-input>

    <el-form-item label="密码" prop="password">

      <el-input v-model="user.password" prefix-icon="el-icon-lock" placeholder="请输入密码" show-password clearable></el-input>

    <el-form-item label="确认密码" prop="repassword">

      <el-input v-model="user.repassword" prefix-icon="el-icon-lock" placeholder="请再次输入密码" show-password clearable></el-input>

      <el-button type="primary" @click="login()">登录</el-button>

      <el-button type="info">重置</el-button>

var validatePass2 = (rule, value, callback) => {

  if (value !== this.user.password) {

    callback(new Error('两次输入密码不一致!'));

      { required: true, message: '请输入用户名', trigger: 'blur' },

      { min: 3, max: 5, message: '用户名长度在 3 到 5 个字符', trigger: 'blur' }

      { required: true, message: '请输入密码', trigger: 'blur' },

      { min: 3, max: 5, message: '密码长度在 3 到 5 个字符', trigger: 'blur' }

      { required: true, message: '请再次输入密码', trigger: 'blur' },

      { validator: validatePass2, trigger: 'blur' }

  // js 对象调用有2种方式:this.user.username  或 this.user['username']

  this.$refs.loginForm.validate((valid) => {

      alert('submit!');

      console.log('error submit!!');

7.常见组件
======

按钮 Button
---------

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a88ac39d23cf4177b997f63d7221514b~tplv-k3u1fbpfcp-zoom-1.image)

<el-button>默认按钮</el-button>

<el-button type="primary">主要按钮</el-button>

<el-button type="success">成功按钮</el-button>

<el-button type="info">信息按钮</el-button>

<el-button type="warning">警告按钮</el-button>

<el-button type="danger">危险按钮</el-button>

消息提示 Message
------------

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5fa0ad6ca6a5436b9abde6dc3a7bf3eb~tplv-k3u1fbpfcp-zoom-1.image)

this.$message.success('这是一条成功消息')

this.$message.error('这是一条错误消息')

    <el-button type="info" @click="open1">消息</el-button>

    <el-button type="success" @click="open2">成功</el-button>

    <el-button type="warning" @click="open3">警告</el-button>

    <el-button type="danger" @click="open4">错误</el-button>

      this.$message.info('这是一条提示信息')

      this.$message.success('这是一条成功消息')

      this.$message.warning('这是一条警告消息')

      this.$message.error('这是一条错误消息')
```

弹出框 MessageBox 确认消息
-------------------

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a4cd82ecb4c245249c7d79a237c14e99~tplv-k3u1fbpfcp-zoom-1.image)

```
 this.$confirm('这是提示信息','这是标题',{confirmButtonText: '确定按钮',cancelButtonText: '取消按钮',type: 'warning'})

        this.$message.success('删除了')

        this.$message.error('取消了')
```

弹出框
---

编写弹出层

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0b9807c86fa946e8a584986262f7c636~tplv-k3u1fbpfcp-zoom-1.image)

```
    <el-button type="text" @click="dialogVisible = true">点击打开 Dialog</el-button>

    <el-dialog title="这是标题" :visible.sync="dialogVisible" >

      <span slot="footer" class="dialog-footer">

        <el-button @click="dialogVisible = false">取 消</el-button>

        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>

      dialogVisible: false,  //是否显示弹出层
```

抽屉
--

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bf4ab9f27e2e4acf9b06c7b59d6d0698~tplv-k3u1fbpfcp-zoom-1.image)

```
    <el-button type="primary" @click="drawerFormVisible = true">修改学生</el-button>

      :visible.sync="drawerFormVisible"

      :before-close="handleClose">

      <el-form :model="student" label-width="80px">

        <el-form-item label="姓名" >

          <el-input v-model="student.sname" autocomplete="off"></el-input>

        <el-form-item label="班级" >

          <el-select v-model="student.cid" placeholder="请选择班级">

            <el-option label="Java12班" value="c001"></el-option>

            <el-option label="Java34班" value="c002"></el-option>

          <el-button type="primary" @click="drawerFormVisible=false">确定</el-button>

          <el-button>取消</el-button>

      drawerFormVisible: false,

      this.$confirm('确认关闭?')

          done();   //结束回调
```

标签页
---

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3daec2740c2743d9aa3445194a897164~tplv-k3u1fbpfcp-zoom-1.image)

```
    <el-tabs v-model="activeName" >

      <el-tab-pane label="用户管理" name="first">

        <el-button type="primary" @click="activeName = 'second'">下一步</el-button>

      <el-tab-pane label="配置管理" name="second">

        <el-button type="primary" @click="activeName = 'third'">下一步</el-button>

      <el-tab-pane label="角色管理" name="third">

        <el-button type="primary" @click="activeName = 'fourth'">下一步</el-button>

      <el-tab-pane label="定时任务补偿" name="fourth">

        <el-button type="primary" @click="$message.success('成功了')">完成</el-button>

      activeName: 'first'
```

 8.Tree组件
=========

表结构
---

```
  tid VARCHAR(32) PRIMARY KEY COMMENT '分类ID',

  tname VARCHAR(50) COMMENT '分类名称',

  `status` INT DEFAULT '1' COMMENT '分类状态:0 禁用、1 启用',

  parent_id VARCHAR(32) COMMENT '父分类ID',

  priority INT COMMENT '优先级,越小,同级显示的时候越靠前',

  depth INT COMMENT '深度,从1递增'

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1000','男装/运动户外', NULL ,1,1);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2000','手机/数码', NULL ,2,1);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3000','零食/生鲜', NULL ,3,1);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1100','上装', 't1000' ,1,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1200','裤子', 't1000' ,2,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1300','流行趋势', 't1000' ,3,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1110','羽绒服', 't1100' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1120','棉衣', 't1100' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1130','卫衣', 't1100' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1210','休闲长裤', 't1200' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1220','牛仔长裤', 't1200' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1230','卫裤', 't1200' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1310','伞兵裤', 't1300' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1320','夜跑裤', 't1300' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t1330','冰感T恤', 't1300' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2100','手机', 't2000' ,1,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2200','手机配件', 't2000' ,2,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2300','数码配件', 't2000' ,3,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2110','华为手机', 't2100' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2120','苹果手机', 't2100' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2130','vivo手机', 't2100' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2210','手机壳', 't2200' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2220','手机耳机', 't2200' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2230','手机支架', 't2200' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2310','U盘', 't2300' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2320','硬盘', 't2300' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t2330','电池', 't2300' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3100','方便速食', 't3000' ,1,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3200','零食', 't3000' ,2,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3300','名酒', 't3000' ,3,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3400','乳饮冰', 't3000' ,4,2);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3110','方便面', 't3100' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3120','火腿肠', 't3100' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3130','甜品罐头', 't3100' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3140','煎饼冷面', 't3100' ,4,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3210','薯片', 't3200' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3220','饼干', 't3200' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3230','网红IP', 't3200' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3240','海味', 't3200' ,4,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3310','清爽啤酒', 't3300' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3320','微醺红酒', 't3300' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3330','养生黄酒', 't3300' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3340','名优白酒', 't3300' ,4,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3410','酸奶', 't3400' ,1,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3420','纯牛奶', 't3400' ,2,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3430','奶粉', 't3400' ,3,3);

INSERT INTO t_category(tid,tname,parent_id,priority,depth) VALUES('t3440','奶酪', 't3400' ,4,3);
```

后端实现
----

JavaBean

```
import com.baomidou.mybatisplus.annotation.TableField;

import com.baomidou.mybatisplus.annotation.TableId;

import com.baomidou.mybatisplus.annotation.TableName;

import com.baomidou.mybatisplus.extension.activerecord.Model;

import java.io.Serializable;

import java.util.ArrayList;

@SuppressWarnings("serial")

public class TCategory extends Model<TCategory> {

    private String tname;

    private Integer status;

    private String parentId;

    private Integer priority;

    private Integer depth;

    @TableField(exist = false)

    private List<TCategory> children = new ArrayList<>();
```

Controller

```
package com.czxy.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.api.ApiController;

import com.baomidou.mybatisplus.extension.api.R;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.czxy.entity.TCategory;

import com.czxy.service.TCategoryService;

import com.czxy.vo.BaseResult;

import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import java.io.Serializable;

import java.util.ArrayList;

import java.util.HashMap;

@RequestMapping("tCategory")

public class TCategoryController extends ApiController {

    private TCategoryService tCategoryService;

    public BaseResult<List<TCategory>> findAll() {

        // 1 查询所有,并按照parent_id排序

        QueryWrapper<TCategory> queryWrapper = new QueryWrapper<>();

        queryWrapper.orderByAsc("parent_id");

        List<TCategory> list = tCategoryService.list(queryWrapper);

        List<TCategory> resultList = new ArrayList<>();

        Map<String,TCategory> cacheMap = new HashMap<>();

        list.forEach( tCategory -> {

            TCategory parentCategory = cacheMap.get(tCategory.getParentId());

            // 3.2 如果没有父添加到resultList中,如果有父追加父内部

            if(parentCategory == null) {

                resultList.add(tCategory);

                parentCategory.getChildren().add(tCategory);

            cacheMap.put(tCategory.getTid() , tCategory);

        return BaseResult.ok("查询成功",resultList);
```

前端基本实现
------

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eb60fa9580474243a5641514fde968c6~tplv-k3u1fbpfcp-zoom-1.image)

```
      :data="categoryList"

      :props="defaultProps"

      @check-change="handleCheckChange">

        children: 'children',

        disabled: (data,node) => {

          return data.status == 0

    async findAllCategory() {

      let { data } = await this.$http.get('http://localhost:7777/tCategory')

      this.categoryList = data.data

    handleCheckChange( data, checked, indeterminate ) {

      console.log(data, checked, indeterminate);

    this.findAllCategory()
```

修改状态
----

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ed4998b1c2fd498babfaafa13977991c~tplv-k3u1fbpfcp-zoom-1.image)

后端实现

```
public BaseResult changeStatue(@RequestBody TCategory tCategory) {

        TCategory findCategory = tCategoryService.getById(tCategory.getTid());

        Integer currentStatus = findCategory.getStatus();

        Integer status = currentStatus == 1 ? 0 : 1;

        Queue<TCategory> queue = new LinkedList<>();

        queue.add(findCategory);

        while(!queue.isEmpty()) {

            TCategory currentCategory = queue.poll();

            currentCategory.setStatus(status);

            tCategoryService.updateById(currentCategory);

            // 3) 获得所有的子节点

            QueryWrapper<TCategory> queryWrapper = new QueryWrapper<>();

            queryWrapper.eq("parent_id", currentCategory.getTid());

            List<TCategory> list = tCategoryService.list(queryWrapper);

            queue.addAll(list);

        return BaseResult.ok("修改成功");

    } catch (Exception e) {

        e.printStackTrace();

        return BaseResult.error(e.getMessage());
```

前端实现

```
      :data="categoryList"

      :props="defaultProps"

      :expand-on-click-node="false"

      :default-expanded-keys="expandedArr"

      @check-change="handleCheckChange">

      <span class="custom-tree-node" slot-scope="{ node, data }">

        <span>{{ node.label }}</span>

          <el-button type="info" circle v-if="data.status == 1" size="mini" @click="() => changeCategoryStatus(data)">禁用</el-button>

          <el-button type="success" circle v-if="data.status == 0" size="mini" @click="() => changeCategoryStatus(data)">启用</el-button>

        children: 'children',

        disabled: (data,node) => {

          return data.status == 0

    async findAllCategory() {

      let { data } = await this.$http.get('http://localhost:7777/tCategory')

      this.categoryList = data.data

    handleCheckChange( data, checked, indeterminate ) {

      console.log(data, checked, indeterminate);

    async changeCategoryStatus( nodeData ) {

      let { data } = await this.$http.put(`http://localhost:7777/tCategory/change`, nodeData)

      if(data.code == 1){

        this.$message.success(data.message)

        this.findAllCategory()

        this.expandedArr = []

        this.expandedArr.push(nodeData.tid)

        this.$message.error(data.message)

    this.findAllCategory()

    justify-content: space-between;
```

9.综合案例
======

弹出层回显学生信息
---------

综合案例:点击学生“修改”按钮,显示弹出层

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4bb1dbe8be4243f8a965b61353b2927b~tplv-k3u1fbpfcp-zoom-1.image)

弹出层中编写表单

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/83d52036b4aa45b7940a0395c9273142~tplv-k3u1fbpfcp-zoom-1.image)

编写修改函数

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1d2b680a7d6c4e24a106009f5490f257~tplv-k3u1fbpfcp-zoom-1.image)

```
    <el-table :data="studentList" stripe border @selection-change="handleSelectionChange">

      <el-table-column type="selection" width="55"></el-table-column>

      <el-table-column prop="sid" label="编号" width="150"></el-table-column>

      <el-table-column prop="sname" label="姓名" width="150"></el-table-column>

      <el-table-column prop="gender" label="性别" width="150"></el-table-column>

      <el-table-column prop="age" label="年龄" width="150"></el-table-column>

      <el-table-column label="爱好" >

        <template slot-scope="scope">

          <el-tag type="warning" v-for="(hobby,index) in scope.row.hobbies" :key="index">{{hobby}}</el-tag>

      <el-table-column label="操作">

        <template slot-scope="scope">

          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>

          <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>

    <el-dialog title="修改学生" :visible.sync="dialogFormVisible">

      <el-form :model="student">

        <el-form-item label="姓名" label-width="80px">

          <el-input v-model="student.sname" ></el-input>

        <el-form-item label="性别" label-width="80px">

          <el-radio-group v-model="student.gender">

            <el-radio label="男">男生</el-radio>

            <el-radio label="女">女生</el-radio>

          </el-radio-group>

        <el-form-item label="年龄" label-width="80px">

          <el-input v-model="student.age" ></el-input>

        <el-form-item label="爱好" label-width="80px">

          <el-checkbox-group v-model="student.hobbies">

            <el-checkbox label="抽烟" name="type"></el-checkbox>

            <el-checkbox label="喝酒" name="type"></el-checkbox>

            <el-checkbox label="烫头" name="type"></el-checkbox>

          </el-checkbox-group>

      <div slot="footer" class="dialog-footer">

        <el-button @click="dialogFormVisible = false">取 消</el-button>

        <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>

    handleSelectionChange(val) {

      this.multipleSelection = val;  //保存选中的数据

    handleEdit(index, row) {

      this.dialogFormVisible = true

    handleDelete(index, row) {

      console.log(index, row);

      dialogFormVisible: false, // 表单弹出层是否显示

      multipleSelection: [],  //多选,选中的数据

          hobbies: ['抽烟','喝酒','烫头']

          hobbies: ['抽烟','烫头']
```

 10.轮播图
=======

轮播图
---

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9c9ab25eb278452f94ed75fb9da49a50~tplv-k3u1fbpfcp-zoom-1.image)

```
    <el-carousel :interval="4000" type="card" height="300px">

      <el-carousel-item v-for="item in 6" :key="item">

        <img src="@/assets/logo.png" alt="">

      </el-carousel-item>

  .el-carousel__item img {

  .el-carousel__item:nth-child(2n) {

    background-color: #99a9bf;

  .el-carousel__item:nth-child(2n+1) {

    background-color: #d3dce6;
```

 切换多张图片

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5e9a696e7e554c21b954571eaf08a98a~tplv-k3u1fbpfcp-zoom-1.image)

```
    <el-carousel :interval="1000" type="card" height="400px">

      <el-carousel-item v-for="item in 3" :key="item">

        <!-- <img src="@/assets/logo.png" alt="我是提示信息"> -->

        <!-- <img src="@/assets/img/1.jpg" alt="我是提示信息"> -->

        <img :src="require(`@/assets/img/${item}.jpg`)" alt="我是提示信息">

      </el-carousel-item>

  .el-carousel__item img {

  .el-carousel__item:nth-child(2n) {

    background-color: #99a9bf;

  .el-carousel__item:nth-child(2n+1) {

    background-color: #d3dce6;
```

复杂下拉列表
------

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4c2a3cfab1914d69a1bbf75660970a30~tplv-k3u1fbpfcp-zoom-1.image)

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/79ab7371c5e9420abecd2ecf4e052dfe~tplv-k3u1fbpfcp-zoom-1.image) 完整代码

```
    <el-form ref="form" :model="classes" label-width="80px">

      <el-form-item label="选择老师">

        <el-select v-model="classes.teacherIds" @change="changeTeacher" multiple placeholder="请选择老师">

            v-for="(teacher,index) in teacherList" :key="index"

            :label="teacher.tname"

            :value="teacher.id"

            :disabled="teacher.disabled"

            <span style="float: left">{{ teacher.tname }}</span>

            <span style="float: right;">{{ teacher.typeText }}</span>

          typeText: '授课老师',

          disabled: false

          typeText: '助理老师',

          disabled: false

          typeText: '辅导员老师',

          disabled: false

          tname: '韩小娇老师',

          typeText: '授课老师',

          disabled: false

          tname: '董洪超老师',

          typeText: '助理老师',

          disabled: false

          tname: '韩新园老师',

          typeText: '辅导员老师',

          disabled: false

    changeTeacher(selectIds) { // 选中的老师id

      let selectType = this.teacherList.map(teacher => {

        if(selectIds.includes(teacher.id)) {

          return teacher.type

      // 2 处理数据:相同类型,不是选中老师,的其他老师禁用

      this.teacherList.forEach(teacher => {

        if(selectType.includes(teacher.type) && !selectIds.includes(teacher.id)) {

          teacher.disabled = true

          teacher.disabled = false
```

> 本文使用 [文章同步助手](https://juejin.cn/post/6940875049587097631) 同步