web组件——template标签,影子DOM,自定义组件


template标签

innerHTML会带来安全问题,document.createElemt()又太过麻烦,template就很方便且安全

注意:

  1. 这两种添加方法效果是不一样的,importNode是克隆;而直接添加,就是把它掏空了,移走了。再想克隆/'拿'就是个空的
    第一种效果:tmeplate里的内容不可展开了

    第二种效果:tmeplate里的内容可展开,可见

影子DOM

放影子DOM的"容器"(标签)叫"宿主",一个宿主里只能放一个影子DOM,若不小心放多了,就是"先到先得",谁在前就放谁,后面的不管
功能:

  1. 普通html中为了不同的样式,要避免class名一样,而影子DOM有自己的class,即使与外界class重名了,也不影响

两个同名class,互不影响


注意:

{ mode: 'open' }中的open与closed适用于创建开放与保密的影子DOM。log(d1)打印d1的详细信息,log(d2)null,目的是为了安全,但是在"有心人"面前还是显得鸡肋

  1. 影子DOM会具有更高的优先级:宿主里的内容会被影子DOM的内容覆盖,除非影子DOM提供插槽,把宿主原本的内容放在slot中保存

I am host

效果:原内容被替代


加上slot

color: red

效果:宿主的内容被放到slot里保存了下来

  1. 改变宿主中元素的渲染顺序
a
b

效果:先渲染了b,后a

自定义组件

html的标签名时可以自己随便起的,唯一的要求就是自定义的组件中间要有横线:-
如:
最简单的用法就是直接写在html中慢慢改style,但是它搭配template或影子DOM有更高级的用法




如此后,在html'中只需要一个,就能达到下面的效果:

template也是一样,要注意的时通过影子DOM实现自定义标签内部的样式只能在影子DOM内部写style,外部不会生效。
这样的标签也是一个组件,我们可以通过在构造函数中通过constructor()和其他JS的API监听组件的属性变化等,来实现组件的生命周期:

//1. 创建元素可以通过:
constructor() {
  super()
  log('beforeCreated') 
  this.attachShadow({ mode: 'open' })
      .innerHTML = `....`
  log('created')
}
//2.组件被添加进某个容器时 <=> mounted
connected
//3.组件被从某容器移除时 <=> unmounted
discounted
//4.组件属性改变时 <=> updated
attributeChanged