ElementUI

一、前置准备 ⚓

二、引入ElementUI 📄

三、使用ElementUI ⚙️

四、总结element组件(可复制直接使用)🌈

下拉选择框 🐔

文件、图片上传展示 🌟

日期时间 🔥

单选 🎯

表单校验 🍉

只能输入整数 🍓

审核 🎁

表格显示高亮信息 🌅

表格里显示图片 🌐

表格里显示视频 🍃

评分 ⚽

树形下拉菜单 🍊

Switch切换按钮 📢

轮播图 🐾

时间线 🥫

下拉多选 ✉️

创建属性 tags 🎁

在编辑的时候 注意把保存的JSON字符串转成JSON数组 🌸

在保存的时候把JSON数组转成JSON字符串存到数据库 🍘

富文本 🎹

一、前置准备 ⚓

1、安装相关环境,使用VsCode或者webstrom初始化Vue 项目

软件环境下载地址:软件 - 坚果云 - |同步|备份|无限空间

vue-cli安装:

npm install -g @vue/cli

npm设置淘宝镜像加速:

​npm config set registry https://registry.npm.taobao.org

创建vue项目:

vue create vue

当然,如果不使用yarn 就选npm

vue create vue--packageManager npm

这将告诉 Vue CLI 在初始化项目时使用 npm 作为软件包管理器。这样,你就不需要后续手动更改依赖管理器了。(请注意,这个标志只在 Vue CLI 版本 4.5.0 或更高版本上可用。如果你的 Vue CLI 版本较旧,请先升级到最新版本)

运行vue项目:

cd vue

​npm run serve

Vue项目的初始化文件结构通常如下所示:

App.vue是根组件,是项目的入口组件,可以在其中定义整个应用的布局和结构。main.js是项目的主入口文件,在这里创建Vue实例,并进行其他的配置和初始化操作。 public目录用于存放不需要经过打包处理的静态资源。 其中vue.config.js是Vue项目的配置文件,可以对构建过程进行自定义配置,如更改输出路径、配置代理、压缩等。如将初始项目端口号修改为 7000。

const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({

transpileDependencies: true,

devServer:{

port:7000

},

chainWebpack: config => {

config.plugin('html')

.tap(args => {

args[0].title = "firstVue"

return args;

})

}

})

可以发现现在修改了title的名字,如果不加这段代码,默认展示的就是新建项目时起的名子。

2、安装组件 | Element

3、修改初始化文件

HomeView.vue 删除之后为:

<template>

<div>

主页

</div>

</template>

<script>

export default {

name: 'HomeView',

}

</script>

App.vue 修改删除内容之后为:

<template>

<div id="app">

<router-view/>

</div>

</template>

增加全局样式 global.css:

*{

box-sizing:border-box;

}

body {

color: #333;

font-size: 14px;

/* 外和内边框都为0 */

margin: 0;

padding:0;

}

import '@/assets/css/global.css

router.js删除后为:

import Vue from 'vue'

import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [

{

path: '/',

name: 'home',

component: () => import('../views/HomeView.vue')

}

]

const router = new VueRouter({

mode: 'history',

base: process.env.BASE_URL,

routes

})

export default router

至此,项目初始化完成!

二、引入ElementUI 📄

安装成功后,即可引入

在 main.js 中

import Vue from 'vue'

import App from './App.vue'

import router from './router'

import ElementUI from 'element-ui';

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

Vue.config.productionTip = false

Vue.use(ElementUI, { size: "small" });

new Vue({

router,

render: h => h(App)

}).$mount('#app')

三、使用ElementUI ⚙️

Element - The world's most popular Vue UI framework

学习两种布局

在 HomeView.vue 文件中

<template>

<div>

主页

<el-row>

<el-col :span="6">

<div style="width: 100%; height: 30px; background-color: deeppink"></div></el-col>

<el-col :span="6">

<div style="width: 100%; height: 30px; background-color: orange"></div></el-col>

</el-row>

<el-row :gutter="20">

<el-col :span="1">

<div style="width: 100%; height: 300px; background-color: dodgerblue"></div></el-col>

<el-col :span="23">

<div style="width: 100%; height: 300px; background-color: red"></div></el-col>

</el-row>

</div>

</template>

<script>

export default {

name: 'HomeView',

}

</script>

<template>

<div>

主页

<el-row>

<el-col :span="6">

<div style="width: 100%; height: 30px; background-color: deeppink"></div></el-col>

<el-col :span="6">

<div style="width: 100%; height: 30px; background-color: orange"></div></el-col>

</el-row>

<el-row :gutter="20">

<el-col :span="1">

<div style="width: 100%; height: 300px; background-color: dodgerblue"></div></el-col>

<el-col :span="23">

<div style="width: 100%; height: 300px; background-color: red"></div></el-col>

</el-row>

<el-row>

<el-col :span="6">

<div style="padding: 10px; border: 1px solid #ccc;text-align:center">

<img style="width: 100%" src="@/assets/logo.png" alt="">

<div style="text-align: center"> 商品 1 </div>

<div style= "color: red">价格 $99.00</div>

</div>

</el-col>

<el-col :span="6">

<div style="padding: 10px; border: 1px solid #ccc;text-align:center">

<img style="width: 100%" src="@/assets/logo.png" alt="">

<div style="text-align: center"> 商品 2 </div>

<div style="color: red">价格 $99.00</div>

</div>

</el-col>

<el-col :span="6">

<div style="padding: 10px; border: 1px solid #ccc;text-align:center">

<img style="width: 100%" src="@/assets/logo.png" alt="">

<div style="text-align: center"> 商品 3 </div>

<div style="color: red">价格 $99.00</div>

</div>

</el-col>

<el-col :span="6">

<div style="padding: 10px; border: 1px solid #ccc;text-align:center">

<img style="width: 100%" src="@/assets/logo.png" alt="">

<div style="text-align: center"> 商品 4 </div>

<div style="color: red">价格 $99.00</div>

</div>

</el-col>

</el-row>

</div>

</template>

<script>

export default {

name: 'HomeView',

}

</script>

再学习第二种方式,使用Container 布局容器,创建一个导航栏

<el-menu>:外层容器。管理定义内容的子元素

:default-openeds 设置el-menu列表默认打开。

<el-submenu>:定义一个可点击的点击菜单。

<template>:el-menu的子元素用来定义el-menu点击列表的列表名字。

<el-menu-item>:按钮元素,菜单列表的单位元素。

<el-menu-item-group>:el-men-item的分组元素。

<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>

<template>

<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-submenu>

<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-submenu>

<el-submenu index="1-2">

<template slot="title">分组2</template>

<el-menu-item index="1-3">选项3</el-menu-item>

<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>

<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>

</template>

<script>

export default {

name: 'App',

data() {

const item = {

date: '2016-05-02',

name: '王小虎',

address: '上海市普陀区金沙江路 1518 弄'

};

return {

tableData: Array(20).fill(item)

}

}

}

</script>

<style>

.el-header {

background-color: #B3C0D1;

color: #333;

line-height: 60px;

}

.el-aside {

color: #333;

}

</style>

这段代码的层次结构如下:

App (根组件)

el-container (容器组件,设置高度和边框样式)

el-aside (侧边栏组件,设置宽度和背景颜色)

el-menu (菜单组件,设置默认展开项)

el-submenu (子菜单组件)

el-menu-item (菜单项组件)

el-menu-item (菜单项组件)

el-submenu (子菜单组件)

el-menu-item (菜单项组件)

el-submenu (子菜单组件)

el-menu-item (菜单项组件)

el-submenu (子菜单组件)

el-menu-item-group (菜单项分组组件)

el-menu-item (菜单项组件)

el-menu-item (菜单项组件)

el-menu-item-group (菜单项分组组件)

el-menu-item (菜单项组件)

el-submenu (子菜单组件)

el-menu-item (菜单项组件)

el-container (容器组件)

el-header (头部组件,右对齐)

el-dropdown (下拉菜单组件)

i (图标)

el-dropdown-menu (下拉菜单项组件)

el-dropdown-item (下拉菜单项组件)

el-dropdown-item (下拉菜单项组件)

el-dropdown-item (下拉菜单项组件)

span (文本)

el-main (内容主体组件)

el-table (表格组件)

el-table-column (表格列组件)

el-table-column (表格列组件)

el-table-column (表格列组件)

<el-menu>:外层容器。管理定义内容的子元素

:default-openeds 设置el-menu列表默认打开。

<el-submenu>:定义一个可点击的点击菜单。

<template>:el-menu的子元素用来定义el-menu点击列表的列表名字。

<el-menu-item>:按钮元素,菜单列表的单位元素。

<el-menu-item-group>:el-men-item的分组元素。

四、总结element组件(可复制直接使用)🌈

下拉选择框 🐔

<el-select style="width: 100%" v-model="form.xx">

<el-option v-for="item in list" :key="item.id" :value="item.id" :label="item.name"></el-option>

</el-select>

data() {

return {

list: [],

}

}

this.$request.get('/xxx/selectAll', {

params: {

}

}).then(res => {

this.list = res.data

})

文件、图片上传展示 🌟

<el-upload

:action="$baseUrl + '/files/upload'"

:headers="{ token: user.token }"

list-type="picture"

:on-success="handleImgSuccess"

>

<el-button type="primary">上传</el-button>

</el-upload>

handleImgSuccess(response, file, fileList) {

this.form.img = response.data

},

// 表格显示 图片

<template v-slot="scope">

<div style="display: flex; align-items: center">

<el-image style="width: 40px; height: 40px;" v-if="scope.row.img"

:src="scope.row.img" :preview-src-list="[scope.row.img]"></el-image>

</div>

</template>

// 表格显示 下载

<template v-slot="scope">

<el-link type="primary" :href='scope.row.file'>下载</el-link>

</template>

日期时间 🔥

<el-date-picker format="yyyy-MM-dd" value-format="yyyy-MM-dd"

v-model="form.date" style="width: 100%"></el-date-picker>

<el-date-picker type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"

v-model="form.time" style="width: 100%"></el-date-picker>

单选 🎯

<el-radio-group v-model="form.sex">

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

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

</el-radio-group>

表单校验 🍉

rules: {

username: [

{ required: true, message: '请输入账号', trigger: 'blur' },

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

],

confirmPass: [

{ validator: validateConfirmPass, trigger: 'blur' }

]

}

let validateConfirmPass = (rule, value, callback) => {

if (value === '') {

callback(new Error('请再次输入密码'));

} else if (value !== this.form.password) {

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

} else {

callback();

}

}

只能输入整数 🍓

num: [

{ required: true, message: '请输入整数', trigger: 'blur' },

{ pattern: /^[1-9]\d*$/, message: '只能输入正整数',}

]

'

运行运行

审核 🎁

<el-table-column label="审核" align="center" width="180" v-if="user.role === 'ADMIN'">

<template v-slot="scope">

<el-button v-if="scope.row.status === '待审核'" size="mini" type="success" plain @click="changeStatus(scope.row, '通过')">通过</el-button>

<el-button v-if="scope.row.status === '待审核'" size="mini" type="danger" plain @click="changeStatus(scope.row, '拒绝')">拒绝</el-button>

</template>

</el-table-column>

changeStatus(row, status) {

this.form = JSON.parse(JSON.stringify(row))

this.form.status = status

this.$confirm('您确定'+status+'吗?', '确认审核', {type: "warning"}).then(response => {

this.$request.put('/xxx/update', this.form).then(res => {

if (res.code === '200') {

this.$message.success('审核成功')

this.load(1)

} else {

this.$message.error(res.msg) // 弹出错误的信息

}

})

}).catch(e => {})

},

表格显示高亮信息 🌅

<template v-slot="scope">

<el-tag type="info" v-if="scope.row.status === '待审核'">待审核</el-tag>

<el-tag type="success" v-if="scope.row.status === '通过'">通过</el-tag>

<el-tag type="danger" v-if="scope.row.status === '拒绝'">拒绝</el-tag>

</template>

表格里显示图片 🌐

<template v-slot="scope">

<el-image v-if="scope.row.img" style="width: 50px" :src="scope.row.img" :preview-src-list="[scope.row.img]"></el-image>

</template>

表格里显示视频 🍃

<template v-slot="scope">

<video :src="scope.row.file" controls style="width: 300px"></video>

</template>

评分 ⚽

<el-rate v-model="star" />

data() {

return {

star: 5

}

}

树形下拉菜单 🍊

<el-select ref="selectTree" v-model="form.departmentId" clearable style="width: 100%;">

<el-option

v-for="item in departmentList"

:key="item.id"

:value="item.id"

:label="item.name"

style="display: none;"/>

<el-tree

:data="departmentTree"

:props="{children: 'children', label: 'name'}"

highlight-current

@node-click="handleNodeClick"

default-expand-all />

</el-select>

created() {

// 先查出扁平的部门数组

this.$request.get('/department/selectAll').then(res => {

this.departmentList = res.data

})

// 再查出树形的部门数组

this.$request.get('/department/selectTree').then(res => {

this.departmentTree = res.data

})

}

// node 就是department对象

handleNodeClick(node) {

this.$set(this.form, 'departmentId', node.id)

this.$refs.selectTree.blur()

},

Switch切换按钮 📢

<el-switch v-model="form.status" active-color="#13ce66" inactive-color="#ff4949"></el-switch>

轮播图 🐾

<el-carousel height="400px">

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

<img :src="item" alt="" style="width: 100%">

</el-carousel-item>

</el-carousel>

时间线 🥫

<el-timeline style="margin-top: 20px" reverse>

<el-timeline-item :color="'#0bbd87'" :timestamp="item.time" placement="top" v-for="item in noticeList" :key="item.id">

<el-card>

<p style="line-height: 24px">{{ item.content }}</p>

</el-card>

</el-timeline-item>

</el-timeline>

下拉多选 ✉️

<el-select allow-create filterable multiple v-model="tags" style="width: 100%">

<el-option v-for="(item, index) in []" :key="index" :value="item"></el-option>

</el-select>

创建属性 tags 🎁

tags: []

'

运行运行

在编辑的时候 注意把保存的JSON字符串转成JSON数组 🌸

this.tags = JSON.parse(this.form.tags || '[]')

在保存的时候把JSON数组转成JSON字符串存到数据库 🍘

this.form.tags = JSON.stringify(this.tags) // 把数组转成JSON字符串存储

富文本 🎹

安装:

npm i wangeditor --save

页面导入 :

import E from "wangeditor"

setRichText(html) {

this.$nextTick(() => {

this.editor = new E(`#editor`)

this.editor.config.uploadImgServer = this.$baseUrl + '/files/editor/upload'

this.editor.config.uploadFileName = 'file'

this.editor.config.uploadImgHeaders = {

token: this.user.token

}

this.editor.config.uploadImgParams = {

type: 'img',

}

this.editor.config.zIndex = 0

this.editor.create() // 创建

this.editor.txt.html(html)

})

},

新增和编辑设置富文本

handleAdd() { // 新增数据

this.form = {} // 新增数据的时候清空数据

this.fromVisible = true // 打开弹窗

this.setRichText('')

},

handleEdit(row) { // 编辑数据

this.form = JSON.parse(JSON.stringify(row)) // 给form对象赋值 注意要深拷贝数据

this.fromVisible = true // 打开弹窗

this.setRichText(this.form.content)

},

/**

* 富文本文件上传

*/

@PostMapping("/editor/upload")

public Dict editorUpload(MultipartFile file) {

String flag;

synchronized (FileController.class) {

flag = System.currentTimeMillis() + "";

ThreadUtil.sleep(1L);

}

String fileName = file.getOriginalFilename();

try {

if (!FileUtil.isDirectory(filePath)) {

FileUtil.mkdir(filePath);

}

// 文件存储形式:时间戳-文件名

FileUtil.writeBytes(file.getBytes(), filePath + flag + "-" + fileName); // ***/manager/files/1697438073596-avatar.png

System.out.println(fileName + "--上传成功");

} catch (Exception e) {

System.err.println(fileName + "--文件上传失败");

}

String http = "http://" + ip + ":" + port + "/files/";

return Dict.create().set("errno", 0).set("data", CollUtil.newArrayList(Dict.create().set("url", http + flag + "-" + fileName)));

}

注意:在save的时候设置变量值

this.form.content = this.editor.txt.html()

预览

<el-dialog title="文章内容" :visible.sync="fromVisible1" width="50%" :close-on-click-modal="false" destroy-on-close>

<div class="w-e-text">

<div v-html="content"></div>

</div>

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

<el-button @click="fromVisible1 = false">关 闭</el-button>

</div>

</el-dialog>

变量

editor: null,

content: '',

fromVisible1: false,

表格

<el-table-column label="查看内容">

<template v-slot="scope">

<el-button @click="preview(scope.row.content)">查看内容</el-button>

</template>

</el-table-column>

函数

preview(content) {

this.content = content

this.fromVisible1 = true

},

表单

<el-form-item label="内容" prop="content">

<div id="editor"></div>

</el-form-item>


ElementUI
http://localhost:8090//archives/elementui
作者
丘瑚珊
发布于
2024年12月09日
许可协议