Javascript 在Vanilla JS中为单个页面创建可重用的web组件?
我有一个HTML页面,它使用jQuery创建一个表来获取数据,并使用vanilla JavaScript创建表。我想为我的集合表创建方法创建一个类,这样我就可以导出它并在整个HTML代码中重用它。我走对了吗 当前表创建代码Javascript 在Vanilla JS中为单个页面创建可重用的web组件?,javascript,jquery,oop,html-table,web-component,Javascript,Jquery,Oop,Html Table,Web Component,我有一个HTML页面,它使用jQuery创建一个表来获取数据,并使用vanilla JavaScript创建表。我想为我的集合表创建方法创建一个类,这样我就可以导出它并在整个HTML代码中重用它。我走对了吗 当前表创建代码 function(data) { //Rename the variable so I can reuse some code var data_list = data.dataList;
function(data) {
//Rename the variable so I can reuse some code
var data_list = data.dataList;
//Headers for our tables second row
var titles = data.headers;
//HTML table variables
var perRow = 2, html = "<table><tr>";
//Loop through our array of data
for (var i = 0; i < data_list.length; i++) {
//Add our header first, as we want that to appear first
html += "<td>" + titles[i]+ "</td>";
//Then add the correct data piece for the header
html += "<td>" + data_list[i]+ "</td>";
//Break into the next row
var next = i+1;
if (next % perRow == 0 && next != data_list.length) {
//Start new row
html += "</tr><tr>";
}
}
//End the table
html += "</tr><table>";
//Attach the table to the HTML doc when finished
document.getElementById("container").innerHTML = html;
};
功能(数据){
//重命名变量,以便可以重用一些代码
var data_list=data.dataList;
//表的第二行标题
var titles=data.headers;
//HTML表变量
var perRow=2,html=“”;
//循环遍历我们的数据数组
对于(变量i=0;i
我在想它在另一个.js文件中的样子
class dataTable extends HTMLElement {
constructor() {
super();
//Get our data
this.dataList = data.dataList;
this.dataHeaders = data.headers;
//HTML attribute for creating our table
this.html = "<table><tr>";
}
createTable() {
//Items we want per roq
var perRow = 2;
//Loop through our data
for (var i = 0; i < this.dataList; i++) {
//Add our headers first
this.html += "<td>" + this.dataHeaders[i] + "</td>";
//Then add the corresponding piece of data
this.html += "<td>" + this.dataList[i] + "</td>";
//Decide when to break into the next row
var next = i+1;
if (next % perRow == 0 && next != this.dataList.length) {
//Add the end row HTML
this. html += "</tr><tr>"
}
}
//End the table
this.html += "</tr><table>";
document.getElementById("container").innerHTML = this.html;
}
}
类数据表扩展HtmleElement{
构造函数(){
超级();
//获取我们的数据
this.dataList=data.dataList;
this.dataHeaders=data.headers;
//用于创建表的HTML属性
this.html=“”;
}
createTable(){
//每个roq我们需要的项目
var perRow=2;
//循环浏览我们的数据
对于(var i=0;i
我走对了吗?我应该只使用一个函数吗?如果我将其.js文件包含在同一目录中,该类是否可以正常工作?在学习框架之前,我只想使用一些OOP原则来制作我自己的web组件。理想情况下,应该有一个shadowRoot,其中有一个用于元素html的插槽,否则可以将表插入shadowRoot。此示例将通过插槽以HTML为目标: 在HTML(静态页面或其他任何页面)中包括:
datagrid
在加载的模块中,通过导入或脚本类型=模块:
/*
this is an example to show basics, it's not ideal, however it answers the question with a working example
*/
class DataTable extends HTMLElement {
constructor() {
super();
// static, or request, or setup default and update later...
this.dataList = [[1,2], [7,9]];
this.dataHeaders = ['one', 'two'];
// only work with shadowRoot in constructor, never the HTML element
// minimize work here too, do that later in lifecycle callbacks
this.attachShadow({mode:'open'}).innerHTML = `
<!-- NOTE how this th styling doesn't work because the table is rendered into the HTML, not the shadowRoot -->
<style>
/* styles shadow content in the host */
:host th{text-align:left;color:blue;}
/* only top-level selectors */
::slotted(table){text-align:right;}
</style>
<table style="width:100%;"><tr><th>ok</th></tr></table>
<button>update table</button>
<slot></slot>
`;
this.shadowRoot.querySelector('button').addEventListener('click', this.updateTable.bind(this));
}
connectedCallback(){
// change attributes, html, etc here
this.createTable();
}
random(){
const max=Date.now();
return Math.floor(Math.random() * Math.floor(max));
}
updateTable(){
this.dataList = this.dataList.map((row, i)=>{
return row.map(this.random);
});
this.createTable();
}
createTable() {
// use the render cycle
cancelAnimationFrame(this._createTable);
this._createTable = requestAnimationFrame(()=>{
// html will go into the shadowRoot slot (default or whatever is targeted)
this.innerHTML = `
<table>
<thead><tr>
${ this.dataHeaders.reduce((html, col, i)=>{
return html + `<th>${i+1} ${col}</th>`;
}, '') }
</tr></thead>
<tbody>
<tr>${ this.dataList.map((row, i)=>{
return `<td>${ row.join('</td><td>') }</td>`;
}).join('</tr><tr>') }</tr>
</tbody>
</table>
`;
});
}
}
// define the element, if not already
customElements.get('data-grid') || customElements.define('data-grid', DataTable);
/*
这是一个展示基本知识的示例,它并不理想,但是它用一个工作示例回答了这个问题
*/
类DataTable扩展了HtmleElement{
构造函数(){
超级();
//静态,或请求,或设置默认值并稍后更新。。。
this.dataList=[[1,2],[7,9];
this.dataHeaders=['one','two'];
//只能在构造函数中使用shadowRoot,而不能使用HTML元素
//在这里也要最小化工作,稍后在生命周期回调中这样做
this.attachShadow({mode:'open'}).innerHTML=`
/*设置宿主中阴影内容的样式*/
:host th{文本对齐:左;颜色:蓝色;}
/*仅限顶级选择器*/
::开槽(表格){文本对齐:右;}
好啊
更新表
`;
this.shadowRoot.querySelector('button').addEventListener('click',this.updateTable.bind(this));
}
connectedCallback(){
//在此处更改属性、html等
这个.createTable();
}
随机的{
const max=Date.now();
返回Math.floor(Math.random()*Math.floor(max));
}
updateTable(){
this.dataList=this.dataList.map((行,i)=>{
返回row.map(this.random);
});
这个.createTable();
}
createTable(){
//使用渲染周期
cancelAnimationFrame(此._createTable);
这是._createTable=requestAnimationFrame(()=>{
//html将进入shadowRoot槽(默认或任何目标)
this.innerHTML=`
${this.dataHeaders.reduce((html,col,i)=>{
返回html+`${i+1}${col}`;
}, '') }
${this.dataList.map((行,i)=>{
返回`${row.join('')}`;
}).join(“”)}
`;
});
}
}
//定义元素(如果尚未定义)
customElements.get('data-grid')| | customElements.define('data-grid',DataTable);
请参阅一个正在运行的()和Google Web Developer文档。您走上了正确的道路。但据我所知,
类
和扩展
不是普通Javascript的一部分,大多数浏览器都不支持它。你必须使用类
和扩展
创建javascript,然后使用webpack将其编译为普通javascript。@KaleshKaladharan是的,我观看的视频没有使用导出,他们只是将其保存为单独的.js文件并导入。谢天谢地,他们可能传输了ES6JS文件,并导入了生成的纯javascript文件。扩展HTMLElement
是一个不同的主题:,这是一组标准,并非所有标准都得到广泛支持。谢谢@HereticMonkey。你知道我在哪里可以学到如何扩展它吗?