Element UI
有的 ul 库在 style 上添加 scoped 后可能会导致自定义样式失效。element ui 可以支持 scoped
多用于管理系统
的开发,有明确设计稿的情况下一般不方便使用 ui 库。
官方文档
开始一个 element 项目
安装
基于@vue/cli 3+ 安装
一定要选择按需安装
。
命令行安装: vue add element
vue ui 安装:vue-cli-plugin-element
(在安装了插件后需要重启项目)
(强烈推荐使用 vue ui 安装,一定要选择按需安装
)
注意:在安装 element ui 时会修改项目文件,应该在项目开始前将所有插件安装好。
简单使用
- 在 element 中导入组件并全局注册
// 主要 class 名出现了 el-xxx 的字样,都可能需要引入,若出现了不知名的错误请注意查看是否缺少引入。
import { Button,Notification,Lodaing } from "element-ui";
//引入组件
Vue.use(Button);
//引入方法
Vue.prototype.$notify = Notification;
//引入指令
Vue.use(Loading)
-
通过 el 关键字使用组件
按钮 -
文档中有非常详细的样式设置,太过繁杂,不一一例举。
-
手动添加样式
按钮 -
事件绑定:element 组件如果文档没有提示的话,同使用
原生绑定事件一样
。style 也是一样的。
<el-button
@click="isLoading = true"
circle
type="success"
plain
:loading="isLoading"
icon="el-icon-delete"
></el-button>
- element ui 中的组件分为两种,第一种是上面的组件形式,第二种为方法类型。
Message 消息提示就是经典的方法类型组件
<el-button @click="showMessage">测试 message</el-button>
// 组件内导入
import { Message } from "element-ui"
// 全局导入
import {Message} from 'element-ui'
// $message 为自定义的方法名,可以任意命名
Vue.prototype.$message = Message
//直接使用
methods: {
showMessage() {
Message("nihao");
// 全局使用方法 this.$message("nihao")
},
}
组件里我们往往需要传递一些的参数
event 类型参数就是自定义事件,使用时通过给标签添加 @参数名=‘事件’ 来使用。
slot 类型的参数,插槽类型,多用来自定义组件内容。
常用组件
下面收录了一些常用的组件或者在使用期间比较容易出现错误的组件以及我本人的一些示例代码。
导航菜单
- el-menu 最外城的框体
- el-submenu 子导航的一个集合
- el-menu-item 子导航
- index 是导航里的唯一表示,它的值必须是个字符串
.toString()
树形控件
数组的子数组属性名默认是 children,展示值的属性名默认是 label 。但我们可以通过设置让任意数组适应树形控件的使用
defaultProps: {
//可以导入任意命名的数组属性名
children: 'children',
label: 'label'
}
若在一些其他的 UI 库中没有以上接口,可使用以下方法将数组里的对象名替换为需要的对象名。
console.log(JSON.parse(JSON.stringify(menu).replaceAll(/title/g, "label")));
// 通过正则表达式将符合正则的属性名替换为 label
数形控件自带许多的方法和事件函数以及参数可供使用。
借助作用域插槽自定义节点内容
<!-- :data="data" 为数据数组
:props="defaultProps" 为 匹配数据数组上面已经介绍了
default-expand-all是否默认展开全部节点 :filter-node-method="filterNode" 对节点进行筛选,返回 true
表示这个节点可以显示,返回 false 则表示这个节点会被隐藏 -->
<el-tree
class="filter-tree"
:data="data"
:props="defaultProps"
default-expand-all
:filter-node-method="filterNode"
ref="tree"
>
<!-- 通过插槽自定义节点内容 -->
<!-- 传递的插槽是匿名插槽 -->
<!-- v-slot:default="{ node }"是接收参数的,不是传递参数的 -->
<!-- node 是子组件内向外传递的数据的集合 -->
<template v-slot:default="{ node }">
<span class="custom-tree-node">
<span
v-html="$options.filters.filterNodeStr(node.label, filterText)"
></span>
<span>
<!-- 按钮类型为文字按钮 -->
<el-button type="text" size="mini">append</el-button>
<el-button type="text" size="mini">delete</el-button>
</span>
</span>
</template>
</el-tree>
对树形控件进行内容的筛选
//第一时间监听input 获取到的 filterText 的变化
watch: {
filterText(val) {
//element ui 内的一些组件自带一些方法,当使用对应的组件的时候可以调用他们有的方法。
//通过给 el-tree (最外层组件)设置ref可以通过 this.$refs.tree 获取到整个tree 组件。
//ref 使用在组件上是获取整个组件,写在非组件上是获取真实dom元素,所以在 vue 中需要获取真实 dom 元素请使用ref 尽量避开document。
this.$refs.tree.filter(val);
// filter 是 tree 自带的筛选节点的方法,传递的参数是需要筛选的字符串。
//filter 的作用是将获取的 val 参数传递给 filterNode 作为他的第一个参数。
},
},
methods: {
//这个函数需要传递给 tree 组件的 filter-node-method prop
//该函数接收两个参数,第一个是filter传递过来的参数,第二个是生成当前节点的数据对象。
//tree 组件的事件对象有多少个节点该方法执行多少次。每次都需要设置返回值,通过它返回的值来控制和判断节点的出现和消失。
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
//到这里关键字筛选已经结束,下面是进阶功能:高亮显示关键字
//关键字就是在 input 里获取的 filterText
//在html里直接截取字符串里关键词前的部分
{{node.label.slice(0,node.label.indexOf(filterText))}}
//node 是子组件内向上传递的数据的集合,并在接收是进行了结构赋值,故不需要通过 this 调用。
//indexOf(filterText) 获取关键词第一个字母在字符串中的位置
//有符合条件的关键字就执行筛选,没有的话直接显示label,跳过筛选
<span v-if="filterText !== '' && node.label.includes(filterText)">
// 截取前半段
<span>{{
node.label.slice(0, node.label.indexOf(filterText))
}}</span>
<span class="key-word">{{ filterText }}</span>
// 加字符串长度截取后半段
<span>{{
node.label.slice(
node.label.indexOf(filterText) + filterText.length
)
}}</span>
</span>
<span v-else>{{ node.label }}</span>
// 以上操作多半在 template 内完成,
//下面通过过滤器实现以上功能
filters: {
filterNodeStr: function (label, filterText) {
//判断是否包括关键字
const isHasKeyWord = label.includes(filterText);
// 不包含的话直接输出 label
if (filterText === "" || !isHasKeyWord) return label;
const starIndex = label.indexOf(filterText);
// 有的话输出经过分段处理的字符串,返回的字符串用 v-html 展现在页面中。
return `<span>${label.slice(
0,
starIndex
)}</span><span class="key-word">${filterText}</span><span>${label.slice(
starIndex + filterText.length
)}</span>`;
},
},
Table 表格
多用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
<!-- 表格的基础 -->
<h2>tabel</h2>
<el-table border :data="tableData" style="width: 100%">
<el-table-column align="center" prop="date" label="日期" width="180">
</el-table-column>
<el-table-column align="center" prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
<!-- 重要性列 -->
<!-- prop="important" 这个不需要添加,展示页面才需要加,展示重要性只需要获取重要性的数值并向下传递即可。 -->
<el-table-column align="center" prop="important" label="重要性" width="180">
<!-- 插槽的参数可以为 tableData,tableData在data里定义,传给子组件又传了回来 ,也可以为 row table-column
的作用域插槽,tableData代表的是组件内部使用插槽的时候传递的整体数据,tableData.row 代表的就是 对应表格内某一列的数据。可以直接对应接收row -->
<template v-slot="{ row }">
<el-rate v-model="row.important" disabled :max="row.important">
<!-- :max="row.important
设置最大评分数,不可以设置为小数,但评分本身可以设置为小数 -->
</el-rate></template
>
</el-table-column>
<el-table-column align="center" prop="date" label="操作" width="180">
<el-button size="mini" type="primary">编辑</el-button>
<el-button size="mini" type="danger">删除</el-button>
</el-table-column>
</el-table>
Table 表格与分页器的联动
<h2>分页器</h2>
<el-table border :data="tableData2" style="width: 100%">
<el-table-column align="center" prop="id" label="序号" width="180">
</el-table-column>
<el-table-column prop="title" labeidl="标题"> </el-table-column>
<el-table-column align="center" prop="important" label="重要性" width="180">
<template v-slot="{ row }">
<el-rate v-model="row.important" disabled :max="row.important"> </el-rate
></template>
</el-table-column>
<!-- <template v-slot="{ row }"> -->
<!-- 作用域插槽需要在组件标签内,写的外面没有效果 -->
<el-table-column align="center" prop="date" label="操作" width="180">
<el-button size="mini" type="primary">编辑</el-button>
<el-button @click="deleteClick(1)" size="mini" type="danger"
>删除</el-button
>
</el-table-column>
<!-- </template
> -->
</el-table>
<!-- 分页器部分 -->
<!-- :current-page.sync="currentPage" 对于简单的子级修改父级数据的操作,通过sync关键字可以不需要在父级定义相关数据函数,直接对其修改,子级改变后父级也会对应改变。大大简化了代码量。 -->
<el-pagination
:current-page.sync="currentPage"
:page-size="10"
background
layout="prev, pager, next"
:total="100"
>
<!-- @current-change="pageChange" -->
</el-pagination>
<script>
// 在使用相关插件前,先引入依赖
import axios from "axios";
export default {
data() {
return {
//默认为0
tableData2: [],
currentPage: 1,
};
},
// 可以通过侦听器来代替 生命周期和点击事件,需要用对象写法,页面渲染时执行一次
watch: {
//page 就是监听的数据本身,在这里就是页数。
currentPage: {
handler(page) {
this.getOosts(page);
},
immediate: true,
},
},
//页面开始时先发送一次请求
// created() {
// this.getOosts(this.currentPage);
// },
computed: {
// showTableData() {
// return this.tableData2.slice(
// (this.currentPage - 1) * 10,
// this.currentPage * 10
// );
// },
},
methods: {
//通过创建请求函数减少重复
//发送请求,获取相关数据。
//通过页数来发送请求。
async getOosts(page) {
const res = await axios.get(
`http://localhost:3008/posts?_page=${page}&_limit=10`
);
this.tableData2 = res.data;
},
// pageChange(page) {
// this.currentPage = page;
// this.getOosts(page);
// },
},
};
</script>
pop 弹框
<template>
<el-popconfirm title="这是一段内容确定删除吗?">
<!-- <template #reference> 这是一个具名插槽,给内部按钮注册了具名插槽才能正常显示 -->
<template #reference>
<!-- 这是要展示的按钮,按钮外部用 el-popconfirm 包裹,记得注册Popover -->
<el-button size="mini" type="danger">删除</el-button></template
>
</el-popconfirm></template
>
表单以及表单验证
表单验证通常为必备功能。
element ui 底层内置了许多校验规则:Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。校验规则参见可以在 Form 表单里查到。
校验规则
<!-- 验证规则在el-form-item 里传递
同时需要传递prop,prop的值为内部input指向的data,不写无法获取到input的改变会报错。
required 是否必填
message 提示信息
trigger 验证方式 blur为失去焦点,change为内容改变时 -->
<el-form-item
prop="newUserId"
:rules="[
{
required: true,
<!-- true 表示必填,对填写的内容没有硬性要求 -->
message: '请输入作者',
trigger: 'blur',
<!-- trigger: ['blur','change']表示失去焦点和内容改变都触发验证 -->
},
]"
label="作者"
:label-width="formLabelWidth"
>
<el-input
style="width: 330px"
v-model="newPost.newUserId"
autocomplete="off"
></el-input>
</el-form-item>
<!-- 自定义规则 -->
<!-- validator: validateBody 传递自定义方法名 -->
<el-form-item
prop="newBody"
label="点评"
:rules="[
{ required: true, validator: validateBody, trigger: 'blur' },
]"
:label-width="formLabelWidth"
>
<el-input
style="width: 330px"
type="textarea"
:rows="2"
placeholder="Please input"
v-model="newPost.newBody"
>
</el-input>
</el-form-item>
<!-- methods: {
//自定义规则为一个函数,写在函数里。
validateBody(rule, value, callback) {
if (value === "") {
callback(new Error("请输入点评内容"));
} else if (value.length < 10) {
callback(new Error("字数太少了,再说几句吧"));
} else if (value.includes("敏感")) {
callback(new Error("包含敏感词汇"));
} else {
callback();
}
},} -->
全体总体表单校验、验证表单内所有验证是否都满足
validate 方法:对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promise
// <el-form :model="newPost" ref="createForm">使用方法需要先给组件一个ref名
// 在函数内添加
//createForm 是表单设置的 ref 的值
this.$refs.createForm.validate((result) => {
console.log(result);
});
// result 为true或flase
Notification 通知
Notification 是一个全局方法,注册时与全局组件不同
import { Notification } from "element-ui";
Vue.prototype.$notify = Notification;
// 全局注册后直接在函数内使用方法即可
this.$notify({
title: "提示",
message: "添加文章成功",
duration: 2000, //设置为0 则不会自动关闭,设置2000为2s后自动关闭
type: "success", //提示的类型:success, warning, info, error 成功,警告,消息,错误。
});
无限滚动
需要通过导入指令来应用。
Loading 加载
Vue.use(Loading) 指令注册
lodaing 当 loading 为 true 展示加载中,并且支持自定义样式。
Cascader
默认 value 为获取的结果,options 为展示的数据可以通过定义 prop 自定义修改的
分栏布局
在布局时使用分栏布局会非常任意,并且可以实现看起来很复杂的效果。
国际化与自定义主题
国际化
Element 组件内部默认使用中文,若希望使用其他语言,则需要进行多语言设置
默认为中文,可以直接在文件内修改默认语言设置。
{
plugins: [
new webpack.NormalModuleReplacementPlugin(
/element-ui[\/\\]lib[\/\\]locale[\/\\]lang[\/\\]zh-CN/,
"element-ui/lib/locale/lang/en"
),
];
}
注意:仅 element ui 自带的文字会生效。若想要实现全站语言翻译的效果,推荐使用(https://kazupon.github.io/vue-i18n/zh/)
// 按需引入 Element
import lang from "element-ui/lib/locale/lang/en";
//en 表示为英文,其他语言索引参考 element 文档
import locale from "element-ui/lib/locale";
// 设置语言,语言的注册应当在组件注册前。
locale.use(lang);
自定义主题
element ui 默认是蓝白配色,我们可以通过自定义主题,来实现一个例如绿白配色的系统。
命令行安装项目依赖
执行以下长串命令
$ npm i element-themex element-theme-chalk -D
可能会报错 node-sass 安装失败
npm ERR! node-sass@4.14.1 postinstall: node scripts/build.js
补救办法
-
单独安装
npm i node-sass@4.8.3 -D
npm i element-theme-chalk -D
npm i element-themex
可能依旧无法安装
-
复制包安装(在 Ahtml 软件文件夹中复制)(这个你们电脑上是没有的,在我电脑上,需要请联系龙_qq 1965892300)
先将 node-sass 文件夹放到 node_modules 里
修改 package.jion 文件
将 “element-theme-chalk”: “^2.15.1”,
“element-themex”: “^1.0.3”,添加到 devDependencies 里npm i 重新安装依赖
提示
78 packages are looking for funding
runnpm fund
for details
则安装成功验证是否成功(如果你觉得已经成功了可以不验证)
./node_modules/.bin/et -i
会出现 element-variables 文件
在这个文件内可以任意修改 element ui 组件内的颜色。
修改完成颜色后执行
./node_modules/.bin/et
- Generator variables file
√ Generator variables file
完成后生成一个 theme 文件夹
在 babel.config.js 内
修改
"styleLibraryName": "~theme"
修改默认查找 css 相对路径,去 theme 内查找,这是按需引入,后续打包编译会大大减少项目规模。
以上配置完成则完成了简单的修改主题:重启项目则可以看到修改后的项目。(只能支持固定修改)
注:这一部分整体还是比较复杂的,我记录的也比较乱,大家看不懂可以去看官方文档
element 小结
对少部分常见的组件作了少许记录。大部分组件没有收录,仍需要大家自己学习使用
其他
在自定义 element ui 组件样式时,可以自己给组件添加一个 class 名,通过这个 class 来添加样式。这是我们自己修改 element 里面组件样式的比较好的方法。好不影响在其他地方使用这个组件。
这就是我整理的一些 element ui 的小点,欢迎大家补充