Web components
组件化介绍背景:原先一个复杂页面,什么是组件化:组件化的优点:组件是模块化编程思想的体现,便于代码复用便于团队协作开发,提高了开发效率代码维护性好,对于代码的管理和使用非常方便,组件的加载和卸载只需要添加或删除一行代码即可完成组件提供了html、css、js的封装方法,实现了与同一页面其他代码的隔离组件非常灵活,定制非常容易,组件往往会留出接口,供使用者设置常用属性,比如title组件,使用者可以
组件化介绍
背景:
原先一个复杂页面,如果不是组件化的开发模式的话,那么页面中所有的逻辑都是放在一块的,非常的混乱,不友好,彼此之间的依赖性也比较强,耦合度比较高,不便于后续维护,如果其中有一处有问题的话,很有可能会影响到别的地方
什么是组件化:
简单的讲就是将一个复杂页面拆分成具有各自功能的部分,这每个就单独包括展示结构、样式、逻辑控制,对功能的封装,这就是组件,组件与组件之间互不干扰,如果有数据来往,也可以正常的传值
组件化的优点:
- 组件是模块化编程思想的体现,便于代码复用
- 便于团队协作开发,提高了开发效率
- 代码维护性好,对于代码的管理和使用非常方便,组件的加载和卸载只需要添加或删除一行代码即可完成
- 组件提供了html、css、js的封装方法,实现了与同一页面其他代码的隔离
- 组件非常灵活,定制非常容易,组件往往会留出接口,供使用者设置常用属性,比如title组件,使用者可以自定义标题、样式等
组件化开发的方式:
- 原生DOM操作封装
- jquery插件
- YUI
- ExtJs
- 原生Web components
- React
- Vue
- Angular
使用Web components
基本步骤:
-
首先现在html中定义一个模板Template,模板中书写组件的结构
<Template id='hello-tem'> <h1>hello world</h1> </Template>
-
在Template模板中定义组件专属的样式,用style标签包起来
<Template id='hello-tem'> <!-- 组件单独的样式,只对template内部的标签有效 --> <style> h1{ font-size: 20px; color: aquamarine; padding: 10px; background-color: blueviolet; } </style> <h1>hello world</h1> </Template>
-
定义组件类
<script> class HelloWorld extends HTMLElement{ constructor(){ super() // 得到组件的模板内容 const template = document.querySelector('#hello-tem').content; //创建组件的根节点(也叫影子节点) const shadowRoot = this.attachShadow({mode:'open'}) //将模板节点添加到根节点中 shadowRoot.appendChild(template.cloneNode(true)) } } </script>
-
在js中注册自定义组件
<script> ....... customElements.define('hello-world',HelloWorld) //注册组件,组件名为‘hello-world’, 第二个参数是组件类 </script>
-
在html中使用自定义组件,直接插入使用组件名标签即可
<!-- 使用组件 --> <hello-world></hello-world>
-
这样你就可以在页面中看到一个最简单的自定义组件效果了
注意:
1、自定义组件名必须由中间的”-“连接
2、定义在template中的style样式只对template中的内容生效
组件传值:
上面的例子中,假设我们通过传值的方式来给内部组件的h1自定义内容,来看下如何处理:
组件调用时,就直接给组件添加自定义属性,这里比如定为content
<hello-world content="你好啊"></hello-world>
然后在组件内部的类中通过this.getAttribute(“属性名”)获取对应的属性数据:
<script>
class HelloWorld extends HTMLElement{
constructor(){
super()
// 得到组件的模板内容
const template = document.querySelector('#hello-tem').content;
//创建组件的根节点(也叫影子节点)
const shadowRoot = this.attachShadow({mode:'open'})
//将模板节点添加到根节点中
shadowRoot.appendChild(template.cloneNode(true))
//通过操作DOM元素把获取到的值塞到元素内部作为值
const content = this.getAttribute('content')
shadowRoot.querySelector('h1').innerText = content
}
}
</script>
组件生命周期:
它的生命周期包含以下四个:
- connectedCallback: 当 custom element首次被插入文档DOM时,被调用
- disconnectedCallback: 当 custom element从文档DOM中删除时,被调用
- adoptedCallback: 当 custom element被移动到新的文档时,被调用
- attributeChangedCallback: 当 custom element增加、删除、修改自身属性时,被调用
组件插槽(slot):
比如,此时我们要自定义一个卡片组件,卡片的内容部分自定义传入,我们可以这么做:
<!-- 调用组件时,直接在组件内部写上要替换slot插槽的内容即可 -->
<hello-world content="你好">
<div slot='content'>我是插槽内容</div>
</hello-world>
<Template id='hello-tem'>
<style>
.card{
height: 200px;
width: 200px;
border: 1px solid greenyellow;
}
.header{
background-color: grey;
}
</style>
// 在Template模板中的内容区可以写上一个slot标签,代表着这块的内容我可以通过外面自定义插槽的形式传入
<div class="card">
<div class="header">我是标题</div>
<slot name="content"></slot>
</div>
</Template>
注意:调用组件时写的slot值要和定义插槽时的name值一致,不然它找不到要插槽的位置,因为可能存在多个插槽
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)