Angular Elements 组件在非angular 页面中使用的DEMO

一、Angular Elements 介绍

      Angular Elements 是伴随Angular6.0一起推出的新技术。它借助Chrome浏览器的ShadowDom  API,实现一种自定义组件。 这种组件可以用Angular普通组件的开发技术进行编写,学习成本低,当它构建好后生成一个打包的js文件。如果页面引入该Js文件 ,就相当于在页面中新增了一个标签,所以在任意框架中都可以使用新标签,就像它是原生div一样。

       ShadowDom  API  是谷歌自己一直强推的API,也一直未标准化的技术。2013年推出的chrome25中,就支持Shadow Dom v0的API,至今都没有其它浏览器附和谷歌的。2016年的chrome53时,谷歌又推出了Shadow Dom v1的API。v1版本似乎将成正式标准,就连Edge都是都示正在考虑。无论v0,v1版本,现在都是草案的状态,距离正式标准还很远。幸运的是,现在有个项目@webcomponents/custom-elements提供polyfill技术方案,能让其它浏览器提前用上该技术。

二、Angular Elements 使用实战

     前不久看到项目angular-elements-dashboard 支持动态加载模块和动态加载外部的模块。其中加载动态外部模块就是先编译一个angular elements项目,然后动态把该bundle.js插入到页面中。于是我就尝试一下,看这个构建的angular elements 文件到底如果引入一个空白的页面中,引入后的组件在浏览器中又是如何呈现的。

     页面结构:     

demo.html

主文件是一个标准的html5页面

external-dashboard-tile.emulated.js  external-dashboard-tile.native.js

是angular elements 用两种组件封装的方式打包的结果,分别是ViewEncapsulation.Emulated和                 ViewEncapsulation.Native封装。它们也是今天的测试主要对象。

custom-elements.min.js

@webcomponents/custom-elements 的文件,是Shadow Dom v1 的polyfill文件 。  如果用chrome53以后的浏览器的话,可以不引入它。如果是其它浏览器,它是必须的。

native-shim.js

如果angular elements项目打包时,tsconfig.json中, 编译参数 target: "es5"时,  所有的class都被编译为function,此时就必须引入该文件。 编译参数 target:"es2015"或更高级的模块时,则不需要引入它。 根本原因是,Shadow Dom v1的api 只支持自定义元素是一个class类型,不能是一个function。

zone.js

angular依赖的文件

页面代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Angular Elements 演示Demo</title>
  <link rel="stylesheet" href="./bootstrap.min.css">
</head>
<body class="container">
  <h1>Angular Elements 演示Demo</h1>
  <div class="row">
    <h3>原生JS插入一个自定义元素</h3>
    <div id="byJs"></div>
  </div>
  <div class="row">
    <h3>用jqyery插入一个自定义元素</h3>
    <div id="byJquery"></div>
  </div>
  <script src="./zone.js"></script>
  <script src="./custom-elements.min.js"></script>
  <script src="./native-shim.js"></script>
  <script src="./jquery.min.js"></script>
  <script src="./external-dashboard-tile.native.js"></script>
  <script>
    // 新引入的external-dashboard-tile元素,  它有三个属性a,b,c,它展示为一个表格

    // 原生JS插入
    const dom = document.createElement("external-dashboard-tile"), byJs = document.getElementById("byJs");
    dom.classList.add("col-sm-2");
    dom.setAttribute('a', '' + Math.round(Math.random() * 100));
    dom.setAttribute('b', '' + Math.round(Math.random() * 100));
    dom.setAttribute('c', '' + Math.round(Math.random() * 100));

    byJs.appendChild(dom);

    // Jquery 插入
    const $dom = $("<external-dashboard-tile>"), $byJquery = $("#byJquery");
    $dom.addClass("col-sm-2");
    $dom.attr("a", Math.round(Math.random() * 100));
    $dom.attr("b", Math.round(Math.random() * 100));
    $dom.attr("c", Math.round(Math.random() * 100));

    $byJquery.append($dom);

    // 定时去修改两个表格的某个列
    setInterval(function () {
      dom.setAttribute('b', '' + Math.round(Math.random() * 100));
      $dom.attr("a", Math.round(Math.random() * 100));
    }, 2000)
  </script>
</body>

</html>

效果:

  注意:上下两个组件中,a,b两个列是定时变化的。

三、Angular Elements应用页面的分析

        代码逻辑估计小学生也看的懂了,分别用原生JS 和 jquery 两种技术,生成<external-dashboard-tile>元素,并且设置元素的class 和 属性,最后插入到页面上。   最后写个定时器,分别用两种技术定时修改它们的一个属性

       当我引入external-dashboard-tile.emulated.js  文件时,它是angular模拟组件的方式插入页面的,就是自定义标签里直接嵌入了div,这种模式并不是真正的Shadow Dom ,它只是一种模拟手段,它通过引入_ng_content-c0的属性空间隔离css 样式。

当我引入external-dashboard-tile.native.js  文件时,就是用原生的方式引入了,看效果,页面上有了 #showdow-root节点,并且外部的bootstrap样式传递不进去了,造成组件的样式全无。

     总结一下,通过使用两个种方式操作自定义元素和以前学习的内置元素的概念一模一样。  那么就是说一个angular elements技术打包好的组件可以: build once ,run any framework!  这个黑科技还是让人惊喜的。  

     Angular Elements的开发技术和Angular普通组件是一致的,像Input属性,Output事件,  依赖注入的支持, 内容投影的支持(这个好像要用<slot> 来做)  ,总之并没有因为 Angular Elements需要脱离ng环境,没有Module 没有Route等支持,它就阉割功能,添加限制。没有,全部没有, 这一点谷歌还是良心。

四、Angular Elements应用后记

       组件封装方式分别是native,emulated 。按照以前看的文章说明,Native模式其实用的是Shadow Dom v0,并不是最新的技术,在2018.7.25号的6.1.0升级中,它又引入了新的封装方式ViewEncapsulation.Shadow 。它的目的是为了不改变Native的模式情况下,引入最新的Shadow Dom v1技术 ,而Native已经过时,不鼓励使用。详见  (#24718

      现在这种打包模式,对于一个最简单的组件,打包后体积是189kb,是非常之大的。据说伴随angular 7推出的ivy 渲染引擎能大大减小组件的构建体积,忘在哪个视频中看到说打包后可到10kb的量级,但现在找不到该说法的来源。现在angular的commit中,有一半都是关于ivy的提交,只需要大家静等angular 7.0的到来了! 

       现在相关资料还比较少,我也是看youtube视频学习的相关介绍,下面给大家几个学习资料

官方文档:https://www.angular.cn/guide/elements

视频 Elements in v6 and Beyond :https://www.youtube.com/watch?v=Z1gLFPLVJjY

示例项目angular-elements-dashboardhttps://github.com/manfredsteyer/angular-elements-dashboard

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏有趣的django

博客园美化终极版-(自定义导航栏)----什么CSDN、简书、腾讯云专栏、个人博客和微信公众号都弱爆了

3230
来自专栏向治洪

React 介绍及实践教程

概述 React 是近期非常热门的一个前端开发框架,其本身作为 MVC 中的 View 层可以用来构建 UI,也可以以插件的形式应用到 Web 应用非 UI 部...

1829
来自专栏iKcamp

翻译 | 关键CSS和Webpack: 减少阻塞渲染的CSS的自动化解决方案

原文地址: Critical CSS and Webpack: Automatically Minimize Render-Blocking CSS 原文作者:...

2348
来自专栏Bug生活2048

微信小程序版博客——图片相关处理

前面提到,小程序服务端的数据是基于Ghost的公共API的,在设计首页文章列表时,为了美观加上了头图,但是服务端没有提供对应的字段(头图url)。

702
来自专栏黑白安全

二次元图片API平台PHP代码

1222
来自专栏数据科学学习手札

(数据科学学习手札50)基于Python的网络数据采集-selenium篇(上)

  接着几个月之前的(数据科学学习手札31)基于Python的网络数据采集(初级篇),在那篇文章中,我们介绍了关于网络爬虫的基础知识(基本的请求库,基本的解析库...

1144
来自专栏向治洪

React Native项目组织结构介绍

代码组织: 目录结构: . ├── components //组成应用的各个组件 │   ├── Routers.android.js //每个组...

1927
来自专栏小古哥的博客园

基于jquery的-获取短信验证码-倒计时

在制作短信验证的时候,需要做一个获取短信按钮,点击后显示倒计时, html代码如下: 1 <input class="gain" type="button" v...

34310
来自专栏杨逸轩 ' sBlog

什么是静态和动态网页?

2207
来自专栏葡萄城控件技术团队

如何在施工物料管理Web系统中处理大量数据并显示

最近在开发施工物料管理系统,其中涉及大量的物料信息需要管理和汇总,数据量非常庞大。之前尝试自己通过将原始数据,加工处理建模,在后台代码中通过分组、转置再显示到 ...

19910

扫码关注云+社区