导入Element-Plus
具体步骤如下:(内容参照官网:安装 | Element Plus)
# 选择一个你喜欢的包管理器
# NPM
$ npm install element-plus --save
# Yarn
$ yarn add element-plus
# pnpm
$ pnpm install element-plus
在main.js文件的引入
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
完成以上步骤后即可在官网组件部分查找自己想用的插件进行使用了。
VUE2版本方式
一、将官网中HTML源码复制到自己的文件中,对其中的参数进行修改。主要修改的是数据的绑定和部分样式的选择。
<div class="demo-pagination-block">
<div class="example-demonstration">
<el-table :data="currentData" style="width: 100%">
<el-table-column fixed type="index" :index="indexMethod" label="序号" width="50" />
<el-table-column prop="nativeTip" show-overflow-tooltip label="本国子目" width="100" />
<el-table-column prop="childrenTip" show-overflow-tooltip label="子目条文" width="100" />
<el-table-column prop="date" label="数据版本" width="100" />
<el-table-column fixed="right" label="操作" width="60">
<template #default="scope">
<el-button link type="primary" size="small" @click="handleClick(scope.$index)">
详细
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页器 -->
<el-pagination v-model:current-page="searchParams.pagenum" v-model:page-size="searchParams.pagesize" :small="small"
:disabled="disabled" background layout="total,prev, pager, next, jumper" :total="total"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
说明:这里我用了首列索引来作为表头元素,但索引值并不是渲染在页面上副本数组中的索引,而是通过该索引计算后的值(即需要渲染在页面上的值),所以通过:index="indexMethod",绑定了indexMethod方法,该方法在methods中定义。
二、将JavaScript中的源码复制后进行修改
export default {
data() {
return {
searchParams: {
pagesize: 5, //页面条数
pagenum: 1, //当前页
},
total: 0,
disabled: false, //是否禁选
small: true,
currentData: [], //渲染在页面上的副本
tableData: [//虚拟数据
{
nativeTip: 'Cals',
childrenTip: 'Tom',
date: '2016-05-02',
},
{
nativeTip: 'Sdaornia',
childrenTip: 'Tom',
date: '2016-05-22',
},
{
nativeTip: 'Csfofif',
childrenTip: 'Tom',
date: '2016-05-21',
}, {
nativeTip: 'Gsdaw',
childrenTip: 'Tom',
date: '2016-05-11',
}, {
nativeTip: '2016-05-12',
childrenTip: 'Tom',
date: 'California',
}, {
nativeTip: 'FedDsa',
childrenTip: 'Tom',
date: '2016-05-04',
},
{
nativeTip: 'California',
childrenTip: 'Tom',
date: '2016-05-31',
}, {
nativeTip: 'California',
childrenTip: 'Tom',
date: '2016-05-01',
}, {
nativeTip: 'California',
childrenTip: 'Tom',
date: '2016-05-04',
}
]
};
}
}
说明:这里用的是虚拟数据,所以需要一个副本将虚拟数据的内容进行深拷贝,然后根据当前页面大小和当前页数进行计算,将最终的副本数据进行渲染到页面上。步骤如下:
- 每次调用切换页面都将虚拟数据进行深拷贝到副本数据中。
- 对副本数据进行处理,根据要渲染第几页数据、一页有几条数据进行裁剪。
- 将最终的副本渲染到页面上。
methods: {
// 修改索引
indexMethod(index) {
return index + 1 + (this.searchParams.pagenum - 1) * this.searchParams.pagesize
},
handleSizeChange(e) {
console.log('SizeChange', e)
},
// 切换当前页面
handleCurrentChange(e) {
console.log('CurrentChange', e)
this.searchParams.pagenum = e
// 1.将获取到的数据存入副本中 深拷贝
this.currentData = JSON.parse(JSON.stringify(this.tableData))
console.log(this.tableData)
// 2. 对数据进行处理
let len = this.currentData.length //数据总条数
console.log(len)
this.total = len
console.log('this.total', this.total)
let num = len - this.searchParams.pagesize //判断是否过长了 多了多少个元素
console.log(num)
if (num > 0 && this.searchParams.pagenum === 1) {
// 2.1 如果是第一页 且长度超过了页面展示长度
// 进行裁剪 从页面展示的最后一个元素开始 一共num个元素
this.currentData.splice(this.searchParams.pagesize, num)
console.log(this.currentData)
} else if (num > 0 && this.searchParams.pagenum !== 1) {
// 数据过长 但不是第一页
// 2.2.1 先裁剪掉前面的元素
this.currentData.splice(0, (this.searchParams.pagenum - 1) * this.searchParams.pagesize)
// 2.2.2 再裁剪掉后面的元素
let len2 = this.currentData.length //判断是否过长了 还多了多少个元素
if (len2 - this.searchParams.pagesize > 0) {
this.currentData.splice((this.searchParams.pagesize), len2 - this.searchParams.pagesize)
}
}
}
},
onLoad() {
this.handleCurrentChange(1)
}
项目成果:
VUE3版本方式
Vue3和Vue2的区别
两个最本质的区别在于拷贝,因为Vue3使用的是组合式API,所以在响应式基础上,能够对data中的数组进行直接拷贝渲染。
完整项目实例:
<template>
<div>
<!-- 面包屑 :separator-icon="ArrowRight"-->
<el-breadcrumb>
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>账号列表</el-breadcrumb-item>
</el-breadcrumb>
<!-- 白色内容区域 -->
<div class="page_content">
<div class="flex">
<div class="input_box">
<el-input v-model="searchParams.query" placeholder="搜索关键字" class="input-with-select">
<template #append>
<el-button @click="searchList"><el-icon>
<Search />
</el-icon></el-button>
</template>
</el-input>
</div>
<el-button type="primary" @click="addUser">新建用户</el-button>
</div>
<!-- 表格 -->
<!--
el-table 的 data:要展示的数据数组
el-table-column:列 prop每条数据的对应属性
label:列标题
scope.row:相当于一条数据
-->
<el-table :data="users" style="width: 100%">
<el-table-column prop="username" label="姓名" width="180" />
<el-table-column prop="email" label="邮箱" width="180" />
<el-table-column prop="mobile" label="电话" />
<el-table-column prop="role_name" label="角色" />
<el-table-column prop="mg_state" label="状态">
<!-- <template #default="scope">
<el-switch
v-model="scope.row.mg_state"
@change="switchChange(scope.row)"
/>
</template> -->
</el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" @click="editRow(scope.row)">编辑</el-button>
<el-button type="danger" @click="deleteRow(scope.row)">删除</el-button>
</template>
</el-table-column>
<!-- mg_state 状态 -->
</el-table>
<!-- 分页 -->
<el-pagination v-model:currentPage="searchParams.pagenum" v-model:page-size="searchParams.pagesize"
:page-sizes="[1, 3, 5, 10]" layout="total, sizes, prev, pager, next" :total="total" @size-change="searchList"
@current-change="searchList" />
</div>
<!-- 编辑弹窗 -->
<el-dialog v-model="dialogFormEVisible" title="编辑用户">
<!--
表单
| email | 邮箱 | 可以为空 |
| mobile | 手机号 | 可以为空 |
-->
<el-form ref="userForm2" :model="formData2" :rules="rules2">
<el-form-item label="邮箱" prop="email">
<el-input v-model="formData2.email" placeholder="请输入用户邮箱" />
</el-form-item>
<el-form-item label="手机号" prop="mobile">
<el-input v-model="formData2.mobile" placeholder="请输入用户手机号" />
</el-form-item>
</el-form>
<template #footer>
<div class="flex">
<el-button>取消</el-button>
<el-button type="primary" @click="submitEForm(userForm2)">确定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
import { toRefs, reactive, ref } from "vue";
// import { ArrowRight } from "@element-plus/icons-vue";
export default {
name: "userList",
setup() {
const data = reactive({
searchParams: {
query: "",
pagesize: 5,
pagenum: 1,
},
total: 0,
userList: [
{
username: "谭梦寻",
email: "1232412@qq.com",
mobile: "123123312312",
role_name: "管理员",
mg_state: "正常",
id: 0,
},
{
username: "江青影",
email: "123242312@qq.com",
mobile: "12312331231",
role_name: "用户",
mg_state: "正常",
id: 1,
},
{
username: "诸葛亮",
email: "1232122@qq.com",
mobile: "12312331231",
role_name: "用户",
mg_state: "正常",
id: 2,
},
{
username: "刘伯温",
email: "1231232@qq.com",
mobile: "12312331231",
role_name: "用户",
mg_state: "正常",
id: 3,
},
{
username: "张角",
email: "1231232@qq.com",
mobile: "13344431323",
role_name: "用户",
mg_state: "正常",
id: 4,
},
{
username: "刘备",
email: "1231232@qq.com",
mobile: "13344434343",
role_name: "用户",
mg_state: "正常",
id: 5,
},
{
username: "关羽",
email: "1231232@qq.com",
mobile: "12542331231",
role_name: "用户",
mg_state: "正常",
id: 6,
},
{
username: "曹操",
email: "1231232@qq.com",
mobile: "15678331231",
role_name: "用户",
mg_state: "正常",
id: 7,
},
],
users: [],
dialogFormVisible: false,
dialogFormEVisible: false,
formData: {
username: "",
password: "",
email: "",
mobile: "",
},
formData2: {
id: "",
email: "",
mobile: "",
},
rules: {
username: [{ required: true, message: "此项为必填", trigger: "blur" }],
password: [{ required: true, message: "此项为必填", trigger: "blur" }],
email: [
{
required: false,
pattern:
/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
message: "请填写正确邮箱",
trigger: "blur",
},
],
mobile: [
{
required: false,
pattern: /^[1][2,3,4,5,6,7,8,9][0-9]{9}$/,
message: "请填写正确手机号",
trigger: "blur",
},
],
},
rules2: {
email: [
{
required: false,
pattern:
/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
message: "请填写正确邮箱",
trigger: "blur",
},
],
mobile: [
{
required: false,
pattern: /^[1][3,4,5,7,8][0-9]{9}$/,
message: "请填写正确手机号",
trigger: "blur",
},
],
},
});
const searchList = () => {
// 使用正则表达式进行模糊查询
const searchTerm = data.searchParams.query;
const regex = new RegExp(searchTerm, "gi");
console.log(data.searchParams);
data.users = data.userList;
data.users = data.users.filter((item) => regex.test(item.username));
let len = data.users.length;
let num = len - data.searchParams.pagesize;
// 获取到的数组长度大于页面展示的长度
if (num > 0 && data.searchParams.pagenum === 1) {
console.log("展示首页内容!");
data.users.splice(data.searchParams.pagesize, num);
} else if (num > 0 && data.searchParams.pagenum !== 1) {
console.log("展示后面的内容!");
console.log(
"前面要删除的数目:" +
(data.searchParams.pagenum - 1) * data.searchParams.pagesize
);
data.users.splice(
0,
(data.searchParams.pagenum - 1) * data.searchParams.pagesize
);
// 二次截断
let len2 = data.users.length;
data.users.splice(
data.searchParams.pagesize,
len2 - data.searchParams.pagesize
);
}
data.total = len;
};
const addUser = () => {
data.dialogFormVisible = true;
};
// 新增提交
const submitForm = (formEl) => {
// validate
formEl.validate((res) => {
if (!res) {
return;
}
// 表单通过对象形式新增到数组中
// data.userList.push(data.formData);
data.users.push(data.formData);
// 隐藏弹窗
data.dialogFormVisible = false;
// 清空form
data.formData = {
username: "",
password: "",
email: "",
mobile: "",
};
});
};
// 修改提交
const submitEForm = (formEl) => {
formEl.validate((res) => {
if (!res) {
return;
}
// 提交修改
console.log(data.formData2);
data.users[data.formData2.id].email = data.formData2.email;
data.users[data.formData2.id].mobile = data.formData2.mobile;
data.dialogFormEVisible = false;
searchList();
});
};
// 状态更改
const switchChange = (row) => {
console.log("操作的那条数据", row);
if (row) {
searchList();
}
};
// 数据编辑
const editRow = (row) => {
console.log("编辑的那条数据", row);
const { email, mobile, id } = row;
// 展示编辑表单
data.dialogFormEVisible = true;
data.formData2.email = email;
data.formData2.mobile = mobile;
data.formData2.id = id;
};
// 删除数据
const deleteRow = (row) => {
console.log("删除的那条数据", row);
let i = 0;
console.log(row.email);
for (i; i < data.users.length; i++) {
if (data.users[i].email === row.email) {
data.users.splice(i, 1);
}
}
console.log(data.users);
};
// 方法初始化
searchList();
const userForm = ref();
const userForm2 = ref();
return {
...toRefs(data),
searchList,
addUser,
submitForm,
submitEForm,
userForm,
userForm2,
// switchChange,
editRow,
deleteRow,
};
},
};
</script>
<style scoped>
.input_box {
width: 200px;
margin-right: 15px;
}
</style>
项目成果图:
总结:
Element-Plus虽然给我们提供了框架,但是在实际运用时,还需要根据需求来编写代码逻辑,比如我这里用的是虚拟数据,所以需要利用副本来渲染,每一切换页面都要更新副本数据,假如后端直接提供参数来获取对应页数的数据条数,则不需要这样复杂的过程。