Vue2 与 Element UI 组件库实战

Element UI 是 Vue 2 生态中最流行的桌面端组件库。本章将系统讲解 Element UI 的核心组件使用、主题定制、表单封装以及常见业务场景的最佳实践。


一、前言

Element UI 提供了 50+ 高质量组件,覆盖后台管理系统开发中的常见需求:

Element UI

基础组件

表单组件

数据展示

导航组件

反馈组件

Button/Icon

Layout

Input/Select

Form/Table

DatePicker

Table

Pagination

Tree

Menu/Tabs

Breadcrumb

Dialog/Drawer

Message/Loading


二、安装与配置

2.1 安装

# 完整引入
npm install element-ui -S

# 按需引入(推荐)
npm install element-ui -S
npm install babel-plugin-component -D

2.2 完整引入

// main.js
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI, { size: 'small', zIndex: 3000 });

2.3 按需引入

// babel.config.js
module.exports = {
    plugins: [
        [
            'component',
            {
                libraryName: 'element-ui',
                styleLibraryName: 'theme-chalk'
            }
        ]
    ]
};

// main.js
import { Button, Input, Form } from 'element-ui';
Vue.use(Button);
Vue.use(Input);
Vue.use(Form);

三、核心组件实战

3.1 表单封装

<template>
    <el-form
        ref="form"
        :model="formData"
        :rules="rules"
        label-width="100px"
    >
        <el-form-item label="用户名" prop="username">
            <el-input v-model="formData.username" placeholder="请输入用户名" />
        </el-form-item>

        <el-form-item label="邮箱" prop="email">
            <el-input v-model="formData.email" type="email" />
        </el-form-item>

        <el-form-item label="角色" prop="role">
            <el-select v-model="formData.role" placeholder="请选择">
                <el-option label="管理员" value="admin" />
                <el-option label="用户" value="user" />
            </el-select>
        </el-form-item>

        <el-form-item label="状态">
            <el-switch
                v-model="formData.status"
                active-value="active"
                inactive-value="inactive"
            />
        </el-form-item>

        <el-form-item>
            <el-button type="primary" @click="submit">提交</el-button>
            <el-button @click="reset">重置</el-button>
        </el-form-item>
    </el-form>
</template>

<script>
export default {
    data() {
        return {
            formData: {
                username: '',
                email: '',
                role: '',
                status: 'active'
            },
            rules: {
                username: [
                    { required: true, message: '请输入用户名', trigger: 'blur' },
                    { min: 3, max: 20, message: '长度 3-20', trigger: 'blur' }
                ],
                email: [
                    { required: true, message: '请输入邮箱', trigger: 'blur' },
                    { type: 'email', message: '邮箱格式错误', trigger: 'blur' }
                ]
            }
        };
    },
    methods: {
        submit() {
            this.$refs.form.validate(valid => {
                if (valid) {
                    this.$emit('submit', this.formData);
                }
            });
        },
        reset() {
            this.$refs.form.resetFields();
        }
    }
};
</script>

3.2 表格封装

<template>
    <div>
        <el-table
            v-loading="loading"
            :data="tableData"
            border
            stripe
            @selection-change="handleSelectionChange"
        >
            <el-table-column type="selection" width="55" />
            <el-table-column prop="name" label="名称" min-width="150" />
            <el-table-column prop="status" label="状态" width="100">
                <template slot-scope="{ row }">
                    <el-tag :type="row.status === 'active' ? 'success' : 'danger'">
                        {{ row.status }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="操作" width="180" fixed="right">
                <template slot-scope="{ row }">
                    <el-button size="mini" @click="edit(row)">编辑</el-button>
                    <el-button size="mini" type="danger" @click="remove(row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>

        <el-pagination
            :current-page="page"
            :page-sizes="[10, 20, 50]"
            :page-size="pageSize"
            :total="total"
            layout="total, sizes, prev, pager, next"
            @size-change="handleSizeChange"
            @current-change="handlePageChange"
        />
    </div>
</template>

3.3 Dialog 弹窗封装

<template>
    <el-dialog
        :title="title"
        :visible.sync="visible"
        :before-close="handleClose"
        width="600px"
    >
        <slot />
        <template #footer>
            <el-button @click="visible = false">取消</el-button>
            <el-button type="primary" :loading="loading" @click="confirm">确定</el-button>
        </template>
    </el-dialog>
</template>

<script>
export default {
    props: {
        title: String,
        loading: Boolean
    },
    data() {
        return { visible: false };
    },
    methods: {
        open() { this.visible = true; },
        close() { this.visible = false; },
        confirm() { this.$emit('confirm'); },
        handleClose(done) {
            this.$confirm('确认关闭?').then(() => done());
        }
    }
};
</script>

四、主题定制

4.1 在线主题工具

# 安装主题工具
npm install element-theme -g
npm install element-theme-chalk -D

# 初始化变量文件
et -i

# 修改变量 element-variables.scss
$--color-primary: #42b983;
$--color-success: #67c23a;

# 编译主题
et

4.2 局部覆盖样式

// styles/element-variables.scss
/* 改变主题色 */
$--color-primary: #42b983;

/* 按需引入 */
@import '~element-ui/packages/theme-chalk/src/button';

五、常见业务场景

5.1 可搜索下拉表格

<template>
    <el-select
        v-model="selected"
        filterable
        remote
        :remote-method="fetchData"
        :loading="loading"
    >
        <el-option
            v-for="item in options"
            :key="item.id"
            :label="item.name"
            :value="item.id"
        />
    </el-select>
</template>

5.2 图片上传

<template>
    <el-upload
        action="/api/upload"
        :headers="{ Authorization: token }"
        :before-upload="beforeUpload"
        :on-success="handleSuccess"
        :file-list="fileList"
        list-type="picture-card"
    >
        <i class="el-icon-plus" />
    </el-upload>
</template>

六、总结

组件 关键属性 注意事项
Form rules, model 每个表单项必须有 prop
Table data, column 大数据使用虚拟滚动
Dialog visible, before-close 使用 .sync 或 v-model
Select filterable, remote 远程搜索需防抖
Upload action, before-upload 注意跨域和权限

七、练习

  1. 封装一个通用搜索表单组件,支持动态配置表单项
  2. 封装一个可配置列的表格组件
  3. 使用 Element UI 搭建一个完整的后台管理页面
  4. 自定义主题色并应用到项目中

更多推荐