整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

如何编写一个原生 Web Components 组件

如何编写一个原生 Web Components 组件

今前端编程中,利用语义化的 HTML 结合 CSS 来完一个组件并不是一件难事,这也意味着无论在 ReactVue 中都可以插入,不过它俩不是今天的主角,接下来我将用一个例子来介绍如何封装一个完整的原生 HTMLWeb Components 组件,让我们开始吧!

HTML结构

首先我们来了解下 HTML 中的 <details> 元素,它可以用于创建一个小部件,其中包含仅在小部件处于“打开”状态时才可见的附加信息,<details>元素内可以包含的内容没有任何限制。

默认情况下,元素创建的小部件<details>处于“关闭”状态(open标签可使其打开)。通过单击小部件在“打开”和“关闭”状态之间切换,以显示或隐藏标签中包含的附加信息,内部标签 <summary> 元素则可为该部件提供概要。

一个简单的例子如下:

<details>
    <summary> 不能说的秘密 </summary>
    藏的这么深,可还是被你发现了
</details>
details {
    border: 1px solid #aaa;
    border-radius: 4px;
    padding: .5em .5em 0;
}

summary {
    font-weight: bold;
    margin: -.5em -.5em 0;
    padding: .5em;
}

details[open] {
    padding: .5em;
}

details[open] summary {
    border-bottom: 1px solid #aaa;
    margin-bottom: .5em;
}

使用语义化 HTML 的优点:页面内容结构更清晰,方便开发者阅读,更利于浏览器的理解与加载,搜索引擎解析与SEO优化。

添加亿点样式

原生元素默认的样式很简陋,因此我们需要为其定制一下样式,这块内容我们简单带过,只讲解关键部分,样式内容有省略,具体可以在文末的码上掘金中看到呈现效果。

.ContentWarning > summary {
  position: relative;
  list-style: none; /** 去除默认样式 **/
  user-select: none; 
  cursor: pointer;
  /** 为其添加一个斜线背景 **/
  --stripe-color: rgb(0 0 0 / 0.1);
  background-image: repeating-linear-gradient(45deg,
      transparent,
      transparent 0.5em,
      var(--stripe-color) 0.5em,
      var(--stripe-color) 1em);
}

/** 通过var变量调整悬停时的颜色样式 **/
.ContentWarning>summary: hover,
.ContentWarning>summary: focus {
  --stripe-color: rgb(150 0 0 / 0.1);
}

封装模板

现在我们来把它封装成一个完整的组件,这需要先将 HTML 编写在模板 template 当中,并设置一个 id,如下所示:

<template id="warning-card">  
  <details class="ContentWarning">
    <summary>
      <strong>?? 注意:</strong> 以下为隐藏内容
    </summary>
    <slot name="desc"> 藏的这么深,可还是被你发现了 </slot>
  </details>
</template>

熟悉 Vue 的小伙伴应该很容易理解上面的代码,结构很相似,不过网页不会直接渲染它包裹的内容。此外我们还对此模板设置了一个插槽 slot,后面会讲到它的作用。

定义组件

有了上面封装好的模板,我们就需要在 JS 中定义成可用组件来让其能够被使用,调用 window 下的 customElements.define 方法,第一个参数是传入组件名称,我们定义组件名为: warning-card ,第二个参数传入一个继承了 HTMLElement 的类,在其构造方法当中获取并克隆一个新的 HTML 节点,它会通过 appendChild 渲染到页面当中。

window.customElements.define('warning-card',
  class extends HTMLElement {
    constructor() {
      super();
      var templateElem=document.getElementById('warning-card');
      var content=templateElem.content.cloneNode(true);
      this.appendChild(content);
    }
  })

接着我们就可以在页面中把它当作组件那样使用了:

<warning-card> </warning-card>

插槽与传参

回头看看上面我们模板中设置的插槽 slot,此时还是没有生效的,我们需要稍微改写一下构造函数中的渲染方式,将 web 组件定义为一个 Shadow DOM,这样构造的是一个可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起的独立元素,并在最后使用 Node.cloneNode() 方法添加了模板的拷贝到 Shadow 的根结点上。

window.customElements.define('warning-card',
  class extends HTMLElement {
    constructor() {
      super();
      var template=document.getElementById('warning-card').content;
      this.attachShadow({ mode: 'open' }).appendChild(template.cloneNode(true));
    }
  })

现在我们尝试使用下组件,往其内容添加一个图片,指向名为 descslot 插槽中:

<warning-card>
  <img slot="desc" src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba825ffee78c4a1b9c0232e5d2f1d048~tplv-k3u1fbpfcp-watermark.image?" />
</warning-card>

这时你会发现,图片插入到 details 元素的隐藏区域当中了,slot 已经成功生效,但是样式却消失了,这时因为组件已经被完全隔离,我们需要将样式作用在其内部才会生效。

<template id="warning-card">
  <style>
    <!-- TODO: 组件的样式 -->
  </style>
  
  <details class="ContentWarning">
    <summary>
      <strong>?? 注意:</strong>
    </summary>
    <slot name="desc">THE DESCRIPTION</slot>
  </details>
</template>

这样组件就正常了:

除了定制模板中的插槽,我们也可以通过 HTML 标签属性来实现一些简单的传参,例如在 summary 标签中显示一个标题:

<warning-card title="前方高能">
</warning-card>

我们只需要在模板中定义好这个标题的位置:

<template id="warning-card">
  <details class="ContentWarning">
    <summary>
        <!-- TODO: 模板中加入一个span标签 -->
      <strong>?? 注意:</strong> <span id="title"></span>
    </summary>
  </details>
</template>

最后在构造函数中我们通过 document 的原生方法写入模板中就可以了:

window.customElements.define('warning-card',
  class extends HTMLElement {
    constructor() {
      super();
      var template=document.getElementById('warning-card').content;
      // TODO: 找到title标签,写入传入组件的title属性值
      template.querySelector('#title').innerText=this.getAttribute('title');
      this.attachShadow({ mode: 'open' }).appendChild(template.cloneNode(true));
    }
  })

结束

至此,我们通过一个简单的原生组件学习了如何编写 Web Components,可以在此代码片段中查看具体源码:原生Web Components组件 - 码上掘金原生Web Components组件 - 码上掘金。

以上就是文章的全部内容,希望对你有所帮助!如果觉得文章写的不错,可以点赞收藏,也欢迎关注,我会持续更新更多前端有用的知识与实用技巧,我是茶无味de一天,希望与你共同成长~

业门户系统是企业信息化系统建设的一个重要支撑,以企业业务系统为基础搭建门户系统作为统一入口和应用中心可以有效支撑系统整合,打造一体化信息整合平台。Portal门户集成平台能够基于企业的实际需要,通过应用集成、数据集成、菜单集成等集成方式构建企业门户网站、应用门户、数据门户、知识中心等,满足企业对外展示、内部业务、数据统计、文档分享等场景需要。

Portlet组件是Portal中重要的组成部分,在页面中注册、配置相应的Portlet组件,通过Portal的聚合机制,从而实现数据的动态展现,同时Portlet组件之间支持通讯,可以实现组件之间的联动,在Portal中Portlet有全动态和普通组件两种,全动态Portlet直接在Portal平台进行开发,而普通的Portlet组件需要借助DP进行扩展开发,二者的应用场景也是有所不同的,本篇文档主要介绍两种组件的开发步骤及配置过程。

整体介绍

Portal门户集成平台作为构建企业门户和统一入口的集成配置平台,提供了灵活的前端展现和后台配置功能,根据企业的实际需要,可用通过Portal平台的配置构建企业门户、应用中心、数据门户、知识中心等各类门户,同时也能基于企业架构分别为集团和子公司、板块独立构建门户。

1.功能架构

Portal门户平台主体功能包括门户展现后台管理两部分,门户展现主要是呈现给最终用户的显示效果,即各类应用门户,后台管理主要作用是对Portal的门户展现进行配置,包括各类导航、主题、页面、组件、数据等。

Portal门户集成平台可以根据最终用户或使用场景的不同构建面对管理层、普通员工、外部人员等不同角色的门户,基于Portal平台预置的各类组件和功能可以实现不同门户的动态配置,包括展现方式、主题样式、显示内容等。同时平台支持CAS认证、群组管理、角色管理、用户管理、权限管理等机制,可以构建统一的认证和授权中心,控制相关的访问权限。

2.集成架构

Portal门户集成平台作为应用的统一入口,支持应用集成、菜单集成、页面集成、数据集成等不同的集成方式,可以将业务系统的访问地址、功能菜单、页面等统一集成到门户中,从而实现在门户的统一访问和业务操作。

根据实际业务需要,Portal平台支持建立多种门户,并支持不同角色、不同终端的访问需要,同时可以将业务系统的功能、业务、数据等集中到一个平台进行查看和操作,借助于ESB企业应用集成平台的应用集成、数据集成,将业务系统的相关数据汇总呈现到Portal门户中。

3.组件说明

Portlet是基于Java的Web组件,在Portal门户中,Portlet作为可插拔的组件实现Portal中数据的展现。在Portal中Portlet有全动态和普通组件两种。

1.全动态Portlet:全动态Portlet组件不需要进行后端的代码开发,只需要在后台管理中定义好HTML的模板代码,在配置页面组件时选择“全动态Portlet”,最后在展现页面通过“编辑组件”配置组件的html模板,以及构建组件的数据URL,从而实现全动态Portlet的构建。

2.普通Portlet:开发时需要通过DP开发平台进行代码开发,一般适用于代码比较复杂,缺少直接获取数据接口的组件,需要通过代码开发来构建组件,以及进行数据的获取与处理。

功能介绍

在开发组件时主要涉及到的后台功能有:组件设置、组件模板和静态数据,下面主要介绍以上三块功能。

1.组件设置

1.在组件设置中可以引入普通Portlet组件的相关信息。

2.配置完组件信息后,可以直接在“导航管理”模块引用该组件。

2.组件模板

1.在组件模板中可以配置全动态Portlet组件的HTML模板代码。

2.配置成功后,可以通过编辑页面的接口地址获取该模板信息。

3.静态数据

1.在“静态数据”模块可以配置组件所需的静态数据,可以配置json、xml等。

全动态Portlet

全动态Portlet组件不需要进行后端的代码开发,只需要在后台管理中定义好HTML的模板代码,在配置页面组件时选择“全动态Portlet”,最后在展现页面通过“编辑组件”配置组件的html模板,以及构建组件的数据URL,从而实现全动态Portlet的构建。下面主要介绍全动态Portlet的开发过程。

1.组件数据

1.首先需要确认组所需数据的格式,数据可以通过接口或者在Portal的静态数据中获取。

2.明确获取数据的地址。

2.组件模板

1.确认完组件所需数据格式后,需要在“组件模板”中添加模板信息。

2.可以在模板明细页面获取该模板的地址信息。

3.展现配置

1.首先在“导航管理”模块的页面布局中配置一个全动态Portlet。

2.在展现页面中对添加的组件切换为EDIT状态,定义Html模板和数据URL。

3.页面展现效果如下:

普通Portlet

普通Portlet在开发时需要通过DP开发平台进行代码开发,一般适用于代码比较复杂,缺少直接获取数据的接口的组件,需要通过代码开发来构建组件,以及进行数据的获取与处理。下面主要介绍普通Portlet组件的开发过程。

1.开发组件

普通Portlet组件后台代码中主要包括以下方法:view、edit、saveConfig和getAjaxData。

1.view方法:用于组件展现的方法。

2.edit方法:显示组件配置页面,用来定义组件的各种属性。

3.saveConfig方法:保存组件属性时调用该方法。

4.getAjaxData:获取组件所需数据方法。

2.配置组件

1.在DP中开发完组件后,需要在“组件设置”模块添加该组件。

3.展现配置

1.首先在“导航管理”模块的页面布局中配置配置该组件。

2.然后在展现页面中对添加的组件切换为EDIT状态,配置组件相关属性。

3.配置成功后页面展现效果如下:

心得总结

在学习portal产品的过程中,自己的技术能力及意识形态等多方面都得到了很大提升,并且有了很多感悟,现在将我在本工作中的收获总结如下。

1.应用场景

Portal作为构建企业门户和应用中心的集成平台,提供了丰富的配置功能,可以根据业务需要配置各类门户,同时支持定制化扩展开发,满足企业业务的灵活展现,构建企业的统一访问入口。基于Portal门户平台可以将各个业务系统的访问入口、功能页面、数据等统一集中展现,支撑同一平台进行多业务的操作,或者跳转到各个平台进行操作。

2.发展趋势

随着数字化和移动互联网时代的来临,云计算、大数据、微服务、移动互联等各种新兴技术为企业业务不断发展带来支撑,门户平台理念技术也根据新技术的发展进行对应的改造与升级,以不断支撑企业内外部业务的处理。新时期互联网环境下,构建连接一切、集成一切的集中化、多层级、高服务、高创新的中台战略出现,而门户搭建做为信息化建设重要阶段,也在此背景下重新定位。

3.集成方案

由于Portal平台是作为统一应用入口存在的,所以在各个解决方案中都可以结合Portal平台构建统一的入口,这样无论是使用还是进行方案演示,都可以通过Portal统一访问,提高操作过程的流畅性,更能体现出方案的一体化特性,提高方案的演示效果。

后续随着Portal产品更多的应用于集成方案和门户网站建设,产品的相关功能也会更加全面和完善,同时随着后续云平台模式的不断深化,不断推动直接面向客户的多租户、云平台的SaaS模式,Portal的使用场景也会更加的丰富和灵活,支撑更多的业务,更全面的支持产品方案的一体化融化。

本文由@数通畅联原创,欢迎转发,仅供学习交流使用,引用请注明出处!谢谢~

能:纯VUE,纯前端实现文件上传,支持文件上传,大文件上传,文件夹上传,100G超大文件断点续传,MD5校验,文件秒传,云存储,比如阿里云,七牛云,华为云,百度云,腾讯云,

核心优势:使用简单,配置简单,集成简单,维护简单。提供前端源代码,提供后端源代码,提供7*24小时专业工程师技术支持。


代码:https://gitee.com/xproer/up6-vue-cli

1.引入up6组件

2.配置接口地址

接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表

参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

3.定义事件