红茶的个人站点

  • 首页
  • 专栏
  • 开发工具
  • 其它
  • 隐私政策
Awalon
Talk is cheap,show me the code.
  1. 首页
  2. JavaWeb 学习笔记
  3. 正文

JavaWeb 学习笔记 10:Element

2023年9月16日 935点热度 0人点赞 0条评论

Element 是一个基于 Vue 的前端组件框架,使用它可以快速构建美观的前端页面。

1.快速开始

创建一个简单的 JavaWeb 应用。

添加一个 Html 页面,并在<head>标签中加入 Element 和 Vue 的相关 js 引用:

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue@2.7.14_dist_vue.min.js"></script>
    <script src="js/element-ui/lib/index.js"></script>
    <link rel="stylesheet" href="js/element-ui/lib/theme-chalk/index.css">
</head>

需要注意的是,Element 使用的是 2.X 版本的 Vue。

在 Vue 的初始化代码中定义相关数据模型和生效的标签:

<script>
    new Vue({
        el: '#app',
        data: function() {
            return { visible: false }
        }
    })
</script>

这里初始化 Vue 的方式是 2.X 版本的方式,与 3.X 的写法有所不同。

在 Html 中添加 Element UI 的相关组件:

<body>
<div id="app">
    <el-button @click="visible = true">Button</el-button>
    <el-dialog :visible.sync="visible" title="Hello world">
        <p>Try Element</p>
    </el-dialog>
</div>
</body>

最终的效果是有一个 button 按钮,点击后会出现一个弹出框。

之所以会这样,是因为 Element UI 的按钮标签el-button上绑定了一个点击事件,该事件由 Vue 的内联事件处理代码visible = true执行,具体效果是点击后visible这个数据模型会变成true。而代表弹框的 Element 标签el-dialog是否显示由属性visible.sync决定,该属性绑定了 Vue 的数据模型visible,所以在visible变成true后会显示。相应的,关闭弹窗后visible会变成false。

2.布局

Element 的布局分为 Layout 和 Container 两种。

2.1.Layout

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue@2.7.14_dist_vue.min.js"></script>
    <script src="js/element-ui/lib/index.js"></script>
    <link rel="stylesheet" href="js/element-ui/lib/theme-chalk/index.css">
    <style>
        .el-row {
            margin-bottom: 20px;
        }
        .el-col {
            border-radius: 4px;
        }
        .bg-purple-dark {
            background: #99a9bf;
        }
        .bg-purple {
            background: #d3dce6;
        }
        .bg-purple-light {
            background: #e5e9f2;
        }
        .grid-content {
            border-radius: 4px;
            min-height: 36px;
        }
        .row-bg {
            padding: 10px 0;
            background-color: #f9fafc;
        }
    </style>
</head>
<body>
<div id="app">
    <el-row>
        <el-col :span="24"><div class="grid-content bg-purple-dark"></div></el-col>
    </el-row>
    <el-row>
        <el-col :span="12"><div class="grid-content bg-purple"></div></el-col>
        <el-col :span="12"><div class="grid-content bg-purple-light"></div></el-col>
    </el-row>
    <el-row>
        <el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
        <el-col :span="8"><div class="grid-content bg-purple-light"></div></el-col>
        <el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
    </el-row>
    <el-row>
        <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
        <el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
        <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
        <el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
    </el-row>
    <el-row>
        <el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
        <el-col :span="4"><div class="grid-content bg-purple-light"></div></el-col>
        <el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
        <el-col :span="4"><div class="grid-content bg-purple-light"></div></el-col>
        <el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
        <el-col :span="4"><div class="grid-content bg-purple-light"></div></el-col>
    </el-row>
</div>
</body>
<script>
    new Vue({
        el: '#app',
        data: function() {
            return { visible: false }
        }
    })
</script>
</html>

这种模式下将一行分为24列,每一行可以根据需要让每一列由1到多个列组合而成(span属性)。

更多关于 Layout 布局的说明可以阅读官方文档。

2.2.Container

Container 布局可以将页面划分成不同的区域,通常由头、尾、侧边栏和内容几个部分组成。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue@2.7.14_dist_vue.min.js"></script>
    <script src="js/element-ui/lib/index.js"></script>
    <link rel="stylesheet" href="js/element-ui/lib/theme-chalk/index.css">
    <style>
        .el-header {
            background-color: #B3C0D1;
            color: #333;
            line-height: 60px;
        }
​
        .el-aside {
            color: #333;
        }
    </style>
</head>
<body>
<div id="app">
    <el-container style="height: 500px; border: 1px solid #eee">
        <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
            <el-menu :default-openeds="['1', '3']">
                <el-submenu index="1">
                    <template slot="title"><i class="el-icon-message"></i>导航一</template>
                    <el-menu-item-group>
                        <template slot="title">分组一</template>
                        <el-menu-item index="1-1">选项1</el-menu-item>
                        <el-menu-item index="1-2">选项2</el-menu-item>
                    </el-menu-item-group>
                    <el-menu-item-group title="分组2">
                        <el-menu-item index="1-3">选项3</el-menu-item>
                    </el-menu-item-group>
                    <el-submenu index="1-4">
                        <template slot="title">选项4</template>
                        <el-menu-item index="1-4-1">选项4-1</el-menu-item>
                    </el-submenu>
                </el-submenu>
                <el-submenu index="2">
                    <template slot="title"><i class="el-icon-menu"></i>导航二</template>
                    <el-menu-item-group>
                        <template slot="title">分组一</template>
                        <el-menu-item index="2-1">选项1</el-menu-item>
                        <el-menu-item index="2-2">选项2</el-menu-item>
                    </el-menu-item-group>
                    <el-menu-item-group title="分组2">
                        <el-menu-item index="2-3">选项3</el-menu-item>
                    </el-menu-item-group>
                    <el-submenu index="2-4">
                        <template slot="title">选项4</template>
                        <el-menu-item index="2-4-1">选项4-1</el-menu-item>
                    </el-submenu>
                </el-submenu>
                <el-submenu index="3">
                    <template slot="title"><i class="el-icon-setting"></i>导航三</template>
                    <el-menu-item-group>
                        <template slot="title">分组一</template>
                        <el-menu-item index="3-1">选项1</el-menu-item>
                        <el-menu-item index="3-2">选项2</el-menu-item>
                    </el-menu-item-group>
                    <el-menu-item-group title="分组2">
                        <el-menu-item index="3-3">选项3</el-menu-item>
                    </el-menu-item-group>
                    <el-submenu index="3-4">
                        <template slot="title">选项4</template>
                        <el-menu-item index="3-4-1">选项4-1</el-menu-item>
                    </el-submenu>
                </el-submenu>
            </el-menu>
        </el-aside>
​
        <el-container>
            <el-header style="text-align: right; font-size: 12px">
                <el-dropdown>
                    <i class="el-icon-setting" style="margin-right: 15px"></i>
                    <el-dropdown-menu slot="dropdown">
                        <el-dropdown-item>查看</el-dropdown-item>
                        <el-dropdown-item>新增</el-dropdown-item>
                        <el-dropdown-item>删除</el-dropdown-item>
                    </el-dropdown-menu>
                </el-dropdown>
                <span>王小虎</span>
            </el-header>
​
            <el-main>
                <el-table :data="tableData">
                    <el-table-column prop="date" label="日期" width="140">
                    </el-table-column>
                    <el-table-column prop="name" label="姓名" width="120">
                    </el-table-column>
                    <el-table-column prop="address" label="地址">
                    </el-table-column>
                </el-table>
            </el-main>
        </el-container>
    </el-container>
</div>
</body>
<script>
    new Vue({
        el: '#app',
        data() {
            const item = {
                date: '2016-05-02',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1518 弄'
            };
            return {
                tableData: Array(20).fill(item)
            }
        }
    })
</script>
</html>

这个示例页面由头部、侧边栏和内容三部分组成。

3.组件

下面的演示将基于之前的示例项目 login-demo,将使用 Element 相关组件改造项目中的 Html 页面。

3.1.表格

品牌列表页的表格替换为 Element 的表格组件 el-table。

<template>
    <el-table
              :data="brands"
              style="width: 100%"
              :row-class-name="tableRowClassName"
              @selection-change="handleSelectionChange">
        <el-table-column
                         type="selection"
                         width="55">
        </el-table-column>
        <el-table-column
                         align="center"
                         type="index"
                         label="序号">
        </el-table-column>
        <el-table-column
                         align="center"
                         prop="brandName"
                         label="品牌名称">
        </el-table-column>
        <el-table-column
                         align="center"
                         prop="companyName"
                         label="企业名称">
        </el-table-column>
        <el-table-column
                         align="center"
                         prop="ordered"
                         label="排序">
        </el-table-column>
        <el-table-column
                         align="center"
                         prop="description"
                         label="品牌介绍">
        </el-table-column>
        <el-table-column
                         align="center"
                         prop="statusText"
                         label="状态">
        </el-table-column>
        <el-table-column
                         align="center"
                         label="操作">
            <el-button type="primary">修改</el-button>
            <el-button type="danger">删除</el-button>
        </el-table-column>
    </el-table>
</template>

el-table标签是 Element 的表格,这里使用到的属性有:

  • data,绑定 Vue 数据模型(数组)后可以用该模型中的数据遍历填充表格的每一行。

  • selection-change,对应表格复选框的change事件,需要绑定 Vue 的事件处理器(方法)。

el-table-column标签定义了表格的每一列,这里使用的属性有:

  • type,定义某些特殊的列,比如:

    • index,从1开始自增的序号

    • selection,带复选框(checkbox)的列

  • align,cell 中内容的对齐方式

  • label,表头的标题

  • prop,遍历绑定的数据模型填充每一行时,对应的属性名

Vue 初始化代码:

new Vue({
    el: "#app",
    methods: {
        tableRowClassName({row, rowIndex}) {
            if (rowIndex === 1) {
                return 'warning-row';
            } else if (rowIndex === 3) {
                return 'success-row';
            }
            return '';
        },
        handleSelectionChange(val) {
            this.multipleSelection = val;
            console.log(this.multipleSelection);
        }
    },
    data() {
        return {
            username: "",
            brands: [],
            multipleSelection: []
        }
    },
    mounted() {
        loadBrands(this);
    }
})
function loadBrands(_vue){
    axios({
        method: "POST",
        url: "/login-demo/brand/query",
        data: {}
    })
        .then((resp) => {
        _vue.brands = resp.data;
        _vue.brands.forEach((brand) => {
            brand.editUrl = "/login-demo/brand/edit?id=" + brand.id;
            brand.deleteUrl = "/login-demo/brand/delete?id=" + brand.id;
            brand.statusText = brand.status === 0 ? "启用" : "禁用";
        });
    });
}

定义了两个自定义方法:

  • tableRowClassName,决定每一行是否使用某种颜色作为背景色

  • handleSelectionChange,绑定到表格复选框的事件处理器,复选框改变后会将选中的数据模型更新到multipleSelection这个数据模型。

Vue 的 data 属性定义了所需的数据模型。mounted 事件中通过异步调用获取品牌数据并填充到数据模型 brands。

3.2.表单

通常需要在表格上便加上搜索条件进行搜索,在 Element 中这属于”行内表单“。

<el-form :inline="true" :model="query" class="demo-form-inline">
    <el-form-item label="状态">
        <el-select v-model="query.status" placeholder="状态">
            <el-option label="启用" value="0"></el-option>
            <el-option label="禁用" value="1"></el-option>
        </el-select>
    </el-form-item>
    <el-form-item label="品牌名称">
        <el-input v-model="query.brandName" placeholder="品牌名称"></el-input>
    </el-form-item>
    <el-form-item label="企业名称">
        <el-input v-model="query.companyName" placeholder="企业名称"></el-input>
    </el-form-item>
    <el-form-item>
        <el-button type="primary" @click="onSubmit">查询</el-button>
    </el-form-item>
</el-form>

el-form的model属性绑定作为表单查询条件的数据模型。在表单中的输入控件上,依次使用v-model属性绑定具体的数据模型属性。

使用一个 el-button 作为表单查询按钮,并绑定click事件到一个事件处理器onSubmit。

在 js 中定义数据模型和事件处理器:

new Vue({
    el: "#app",
    methods: {
        // ...
        onSubmit() {
            console.log('submit!');
            loadBrands(this);
        }
    },
    data() {
        return {
            // ...
            query: {
                status: null,
                brandName: '',
                companyName: ''
            }
        }
    },
    // ...
})

在具体加载品牌数据的方法中使用表单的查询条件:

function loadBrands(_vue){
    axios({
        method: "POST",
        url: "/login-demo/brand/query",
        data: _vue.query
    })
        .then((resp) => {
        // ...
    });
}

3.3.对话框

添加两个按钮,分别用于批量删除和新增:

<el-row>
    <el-button type="danger" plain>批量删除</el-button>
    <el-button type="primary" plain>新增</el-button>
</el-row>

添加一个对话框(Dialog),并用新增按钮可以打开:

<el-row>
    <el-button type="danger" plain>批量删除</el-button>
    <el-button type="primary" @click="dialogVisible=true" plain>新增</el-button>
</el-row>
<el-dialog
           title="提示"
           :visible.sync="dialogVisible"
           width="30%">
    <span>这是一段信息</span>
    <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
    </span>
</el-dialog>

需要添加一个用于控制对话框打开关闭的数据模型:

new Vue({
    el: "#app",
    // ...
    data() {
        return {
            // ...
            dialogVisible: false
        }
    },
    // ...
})

在对话框中嵌套一个表单用于填写新增数据:

<el-dialog
           title="新增品牌"
           :visible.sync="dialogVisible"
           width="30%">
    <el-form ref="form" :model="form" label-width="80px">
        <el-form-item label="品牌名称">
            <el-input v-model="form.brandName"></el-input>
        </el-form-item>
        <el-form-item label="企业名称">
            <el-input v-model="form.companyName"></el-input>
        </el-form-item>
        <el-form-item label="排序">
            <el-input v-model="form.ordered"></el-input>
        </el-form-item>
        <el-form-item label="品牌介绍">
            <el-input type="textarea" v-model="form.description"></el-input>
        </el-form-item>
        <el-form-item label="状态">
            <el-switch v-model="form.status"
                       active-value="0"
                       inactive-value="1"></el-switch>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="onFormSubmit">确认</el-button>
            <el-button @click="dialogVisible = false">取消</el-button>
        </el-form-item>
    </el-form>
</el-dialog>

js 的部分这里不再赘述,可以查看完整示例。

3.4.消息提示

通常我们希望成功修改数据后有一个弹出消息提醒用户,并在若干秒后自动消失。对应的 Element 组件是消息提示。

实现也很简单:

new Vue({
    el: "#app",
    methods: {
        // ...
        onFormSubmit() {
            // 新增品牌 dialog 提交
            let _vue = this;
            axios({
                // ...
            }).then((resp) => {
                // ...
                _vue.$message({
                    message: '添加品牌成功',
                    type: 'success'
                });
            });
        },
        // ...
    },
    // ...
})

3.5.弹框

批量删除很简单:

<el-button type="danger" @click="batchDeleteBrands" plain>批量删除</el-button>

对应的 js:

batchDeleteBrands(){
    let ids = [];
    this.multipleSelection.forEach((brand)=>{
        ids.push(brand.id);
    });
    let _vue = this;
    axios({
        method: "POST",
        url: "/login-demo/brand/batchDelete",
        data: ids
    }).then((resp)=>{
        loadBrands(_vue);
        _vue.$message({
            message: '批量删除成功',
            type: 'success'
        });
    });
}

不过一般为了避免误操作,需要给删除功能增加一个用于确认的弹框:

openBatchDeleteConfirm() {
    this.$confirm('此操作将永久删除品牌, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
    }).then(() => {
        this.batchDeleteBrands();
    }).catch(() => {
        this.$message({
            type: 'info',
            message: '已取消删除'
        });
    });
}

让批量删除按钮点击事件绑定到这个方法:

<el-button type="danger" @click="openBatchDeleteConfirm" plain>批量删除</el-button>

3.6.分页

添加分页相关组件:

<div class="block">
    <span class="demonstration">分页</span>
    <el-pagination
                   @size-change="handleSizeChange"
                   @current-change="handleCurrentChange"
                   :current-page="page.currentPage"
                   :page-sizes="[5, 10, 15, 20]"
                   :page-size="page.pageSize"
                   layout="total, sizes, prev, pager, next, jumper"
                   :total="page.total">
    </el-pagination>
</div>

size-change事件会在每页数据条数发生改变时调用。

current-change事件会在当前页码改变时调用。

current-page属性表示的是当前页码。

page-size属性表示的是当前每页展示的条数。

total属性表示的是总的数据条数。

为分页相关的信息添加数据模型:

data() {
    return {
        // ...
        page: {
            currentPage: 1,
            pageSize: 5,
            total: 5
        }
    }
},

修改数据加载方法,传入参数中添加分页相关参数:

function loadBrands(_vue) {
    axios({
        method: "POST",
        url: "/login-demo/brand/query",
        data: {
            query: _vue.query,
            page: {
                size: _vue.page.pageSize,
                currentPage: _vue.page.currentPage
            }
        }
    })
        .then((resp) => {
        _vue.brands = resp.data.list;
        _vue.brands.forEach((brand) => {
            brand.editUrl = "/login-demo/brand/edit?id=" + brand.id;
            brand.deleteUrl = "/login-demo/brand/delete?id=" + brand.id;
            brand.statusText = brand.status === 0 ? "启用" : "禁用";
        });
        _vue.page.total = resp.data.resultPage.total;
    });
}

返回的结果除了填充表格数据,也要设置分页数据中的总数据条数。

The End,谢谢阅读。

本文的完整示例可以从这里获取。

4.参考资料

  • 黑马程序员JavaWeb基础教程

  • JavaScript 教程 (w3school.com.cn)

  • JavaScript 对象入门 - 学习 Web 开发 | MDN (mozilla.org)

  • mybatis – MyBatis 3 | XML 映射器

  • Element - 网站快速成型工具

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: element
最后更新:2023年9月16日

魔芋红茶

加一点PHP,加一点Go,加一点Python......

点赞
< 上一篇
下一篇 >

文章评论

取消回复

*

code

COPYRIGHT © 2021 icexmoon.cn. ALL RIGHTS RESERVED.
本网站由提供CDN加速/云存储服务

Theme Kratos Made By Seaton Jiang

宁ICP备2021001508号

宁公网安备64040202000141号