又是许久没有写博客了,这几年的疫情,总是居家,时间久了,慢慢的总会想很多。现在越发觉得想做的事情一定要尽早去做,不然总说等下一次,很多时候,就没有下一次了。
今天给大家分享一下如何用原生JS封装一个基础版的ElementUI表格组件。代码篇幅较短,所以有很大的拓展空间,有兴趣可以自己捯饬一下,让功能更加完善。比如增加获取数据和设置数据的功能,再比如增加删除一行、添加一行的操作,以及整合一个分页组件,这些都是可以实现的,大家需要的话,后续有空再慢慢分享。
一、分析需求
今天要做的功能是一个用原生JS代码去手写一个基础版的ElementUI表格组件,任何一个需求做之前不要忙慌着去写,我们可以先构思一下。比如这个表格组件,要实现的话怎么样写更加简便呢?
既然打算用原生梭哈,那么html结构肯定是采用tabel,表格内又分为thead和tbody,还有一点是我们需要做到让表格的内容自动渲染,毕竟我们在使用表格的时候,数据都是从接口来的。有了大致的思路之后就可以着手去写代码了,这里我在一个文件夹下创建了四个文件,大家嫌麻烦的话也可以少写点。创建四个文件,index.html、index.js、tabel.js、tabel.css
二、直接上代码了
1、index.html中的内容只有css的引入和script标签的引入,其实这里css最好是在tabel.js中引入,做好模块化。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="table.css">
<script src="https://unpkg.com/axios@1.2.0/dist/axios.min.js"></script>
</head>
<body>
<div id="main"></div>
<script type="module" src="./index.js"></script>
</body>
</html>
2、tabel.css就是很简单的样式,所以就写在前面了。
table {
border-collapse: collapse;
}
table, th, td {
font-size: 14px;
color: #606266;
padding: 10px 20px;
border: 1px solid #ebeef5;
}
3、tabel.js就是今天的核心代码了
/**
* @class 基础版ElementUI组件
* @description 该组件可自定义标题内容、按钮文字内容、以及弹窗展示内容
* @param { Object } config
* @param { Array } config.el -绑定的元素
* @param { Array } config.column -列
* @param { Array } config.tableData -行数据
*/
export class Table { // 封装要点:数据驱动视图
constructor(config) {
let { el, column, tableData } = config
var thHtml, tdHtml, trHtml = `` // 表头, 每行单元格, 表格每行
tableData.forEach(tdItem => { // 遍历每一行
thHtml = tdHtml = ``
column.forEach(item => { // 遍历每一列
thHtml += `<th>${item.label}</th>` // 表头html
tdHtml += `<td>${tdItem[item.prop]}</td>` // 单元格html
})
trHtml += `<tr>${tdHtml}</tr>` // 每行
})
// console.log(trHtml)
this.initHTML = `<table><tr>${thHtml}</tr>${trHtml}</table>`
document.getElementById(`${el}`).innerHTML = this.initHTML
}
}
4、index.js中使用tabel组件
import { Table } from './Table.js'
let table = new Table({
el: 'main',
column : [
{ prop: "date", label: '日期' }, // prop为每行数据渲染字段,label为每列表头
{ prop: "name", label: '姓名' },
{ prop: "address", label: '地址' }
],
tableData : [
{
date: '2016-05-02',
name: '王小虎1',
address: '上海市普陀区金沙江路 1518 弄'
},
{
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
},
{
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
},
{
date: '2016-05-06',
name: '王小虎',
address: '上海市普陀区金沙江路 1520 弄'
},
{
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}
]
})
代码效果如下:
这里用的是静态数据, 未免有点low,我们就来请求一下接口看看吧,检验一下自己封装的组件能否做到自动渲染。
修改index.js中的代码如下:
import { Table } from './Table.js'
let table = {
el: 'main',
column : [
{ prop: "id", label: 'ID' },
{ prop: "userId", label: '用户ID' },
{ prop: "title", label: '标题' },
{ prop: "body", label: '内容' }
],
tableData : []
}
axios.get("https://jsonplaceholder.typicode.com/posts").then(res => {
console.log(res.data);
table.tableData = res.data
new Table(table)
})
实现效果如下,这里用的是 jsonplaceholder提供的接口。
本文为原创内容,如需转载,请注明出处,谢谢