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 条评论
登录 后参与评论

相关文章

来自专栏小巫技术博客

高效Mac(三)面向程序员的交互设计神器:Framer Studio

823
来自专栏小樱的经验随笔

【全网最全的博客美化系列教程】04.访客量统计的实现

相信大家也看到了右侧公告栏的访客量统计的效果,我们可以看到有两个样式,一个是单独统计人数的,一个是统计访客来源的,是不是感觉还挺不错的?

1146
来自专栏ytkah

微信小程序开发教程第五章:微信小程序名片夹详情页开发

今天加了新干货!除了开发日志本身,还回答了一些朋友的问题。 闲话不多说,先看下「名片盒」详情页的效果图: ? ? 备注下大致需求:顶部背后是轮播图,二维码...

3978
来自专栏Material Design组件

Human Interface Guidelines — Widgets

1203
来自专栏何俊林

推荐一个Flutter项目(已开源)

4723
来自专栏liuchengxu

如何使用 Vim 的 help

实际上,无论是 Vim 的基础知识还是进阶知识,大都可以从 help 中找到指引。但是我想很多人并没有意识到这一点,或者并没有重视这一点。RTFM (read ...

742
来自专栏极乐技术社区

五个套路看懂微信小程序开发(下)

你或许听说过,快速入门就是要学最小必要知识。而我最近在看微信小程序的官方教程时发现,这个教程虽然简单,但对于微信小程序开发来说,80%的套路都能从这里学习到,你...

3359
来自专栏互联网杂技

前端各种优化

1.  请减少HTTP请求   基本原理:   在浏览器(客户端)和服务器发生通信时,就已经消耗了大量的时间,尤其是在网络情况比较糟糕的时候,这个问题尤其的突...

3488
来自专栏大数据钻研

前端面试那些坑

HTML Doctype作用?严格模式与混杂模式如何区分?它们有何意义? HTML5 为什么只需要写 ? 行内元素有哪些?块级元素有哪些? 空(void)元素有...

3536
来自专栏做全栈攻城狮

小白学编程实战项目-利用Winform开发美女音乐播放器

这是小白学习软件开发系列课程,旨在帮助对电脑编程感兴趣的朋友学习并熟悉C#技术。其中基础部分已经讲解完毕,可以查看:电脑编程入门(10)-C#面向对象编程浅聊,...

2543

扫码关注云+社区

领取腾讯云代金券