电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

2023年了該了解下WebComponent使用教程

瀏覽:116日期:2022-06-01 17:38:12
目錄
  • 正文
  • 三項主要技術
    • 1、Custom elements (自定義元素)
      • 生命周期函數
    • 2、HTML templates(HTML 模板)
      • 3、Shadow DOM(影子 DOM)
      • 動態創建 webComponent 組件例子

        正文

        WebComponent 是官方定義的自定義組件實現方式,它可以讓開發者不依賴任何第三方框架(如Vue,React)來實現自定義頁面組件;達到組件復用效果

        一個簡單例子,讓頁面顯示 hello world:

        <body>  <!-- 使用組件的方式 -->  <my-text />  <script>    class MyText extends HTMLElement {      constructor() {super();this.append("hello world");      }    }    window.customElements.define("my-text", MyText);  </script></body>

        三項主要技術

        1、Custom elements (自定義元素)

        • 一組 JavaScript API,允許您定義 custom elements 及其行為,然后可以在您的用戶界面中按照需要使用它們

        分為兩種形式:

        自主定制元素:是獨立的元素,它不繼承其他內建的 HTML 元素,可以直接把它們寫成 HTML 標簽的形式,來在頁面上使用,例如我們剛才自定義的 <my-text>

        自定義內置元素:繼承自內置的 HTML 元素。指定所需擴展的元素

        • 使用時需通過 is 屬性指定 custom element 的名稱,必須包含一個短橫線
        • 注冊的時候必須使用 extends 的屬性
        <!-- 自定義內置元素 使用 is--><body>  <!-- 使用組件的方式 -->  <p is="color-p" color="green">云牧</p>  <script>    class ColorP extends HTMLParagraphElement {      constructor() {super();this.style.color = this.getAttribute("color");      }    }    window.customElements.define("color-p", ColorP, { extends: "p" });  </script></body>

        推薦在 connectedCallback 生命周期函數,處理節點操作

        <!-- 自主定制元素--><body>  <my-text />  <script>    class MyText extends HTMLElement {      constructor() {super();      }      connectedCallback() {this.append("hello world");      }    }    window.customElements.define("my-text", MyText);  </script></body>

        生命周期函數

        connectedCallback:插入文檔時,可能被多次觸發,比如刪除后又添加到文檔

        disconnectedCallback:從文檔刪除時,可配置做清理工作

        adoptedCallback:被移動新文檔時

        attributeChangedCallback:屬性變化時

        • 配合 observedAttributess 屬性一起使用,指定監聽的屬性
        • 使用 setAttribute 方法更新屬性

        不同操作觸發的生命周期函數:

        例子:

        <body>  <div id="container">    <p is="my-text" text="云牧" id="myText"></p>  </div>  <button id="btnUpdateText">更新屬性</button>  <button id="btnRemove">刪除節點</button>  <button id="btnRestore">恢復節點</button>  <button id="btnAdopt">移動節點</button>  <iframe src="./ifr.html" id="ifr"></iframe>  <script>    class MyText extends HTMLParagraphElement {      constructor() {super();      }      connectedCallback() {console.log("生命周期:connectedCallback");this.append("你好:" + this.getAttribute("text"));      }      disconnectedCallback() {console.log("生命周期:disconnectedCallback");this.innerHTML = "";      }      // 監測的屬性      static get observedAttributes() {return ["text"];      }      attributeChangedCallback(name, oldValue, newValue) {console.log("生命周期:attributeChangedCallback", name, oldValue, newValue);// 最先觸發是此函數,判斷是不是第一次觸發,第一次的話,只由 connectedCallback 處理if (oldValue != null) {  this.replaceChildren("你好:" + newValue);}      }      adoptedCallback() {console.log("生命周期:adoptedCallback");      }    }    window.customElements.define("my-text", MyText, { extends: "p" });    const myText = document.getElementById("myText");    btnUpdateText.addEventListener("click", function (e) {      myText.setAttribute("text", "黛玉");    });    btnRemove.addEventListener("click", function (e) {      myText.remove();    });    btnRestore.addEventListener("click", function (e) {      container.appendChild(myText);    });    btnAdopt.addEventListener("click", () => {      const textNode = ifr.contentWindow.document.getElementById("myText");      container.appendChild(document.adoptNode(textNode));    });  </script></body>

        2、HTML templates(HTML 模板)

        • 使用 JS 模板字串符的方式創建模板,提示不友好,復用性差
        <body>  <product-item    name="關東煮"    img="http://img10.360buyimg.com/seckillcms/s200x200_jfs/t1/121953/18/20515/175357/61e7dc79Ee0acbf20/4f4f56abd2ea2f75.jpg!cc_200x200.webp"    price="49.8"  ></product-item>  <script>    class ProductItem extends HTMLElement {      constructor() {super();      }      connectedCallback() {const content = `  <img src="https://misc.360buyimg.com/lib/skin/e/i/error-jd.gif" />  <div></div>  <div></div>      `;this.innerHTML = content;this.querySelector(".img").src = this.getAttribute("img");this.querySelector(".name").innerText = this.getAttribute("name");this.querySelector(".price").innerText = this.getAttribute("price");      }    }    window.customElements.define("product-item", ProductItem);  </script></body>

        template 方式

        <body>  <!-- template -->  <template id="tpl-product-item">    <img src="https://misc.360buyimg.com/lib/skin/e/i/error-jd.gif" />    <div></div>    <div></div>  </template>  <product-item    name="關東煮"    img="http://img10.360buyimg.com/seckillcms/s200x200_jfs/t1/121953/18/20515/175357/61e7dc79Ee0acbf20/4f4f56abd2ea2f75.jpg!cc_200x200.webp"    price="49.8"  ></product-item>  <script>    class ProductItem extends HTMLElement {      constructor() {super();      }      connectedCallback() {const content = document.getElementById("tpl-product-item").content.cloneNode(true);// 插入克隆的模板內容this.append(content);this.querySelector(".img").src = this.getAttribute("img");this.querySelector(".name").innerText = this.getAttribute("name");this.querySelector(".price").innerText = this.getAttribute("price");      }    }    window.customElements.define("product-item", ProductItem);  </script></body>

        slot

        <body>  <template id="tpl-test">    <style>      .title {color: green;      }    </style>    <div>標題</div>    <slot name="slot-des">默認內容</slot>  </template>  <test-item>    <div slot="slot-des">不是默認內容</div>  </test-item>  <script>    class TestItem extends HTMLElement {      constructor() {super();      }      connectedCallback() {const content = document.getElementById("tpl-test").content.cloneNode(true);const shadow = this.attachShadow({ mode: "open" });shadow.append(content);      }    }    window.customElements.define("test-item", TestItem);  </script></body>

        3、Shadow DOM(影子 DOM)

        影子DOM,其內部樣式不共享

        <body>  <!--  不受外部 .container.container 的顏色影響 -->  <my-item-s></my-item-s>  <div>My item</div>  <style>    .container.container {      color: green;    }  </style>  <template id="tpl">    <style>      .container {color: pink;      }    </style>    <div>My Item</div>  </template>  <script>    class MyItemShadow extends HTMLElement {      constructor() {super();      }      connectedCallback() {const content = document.getElementById("tpl").content.cloneNode(true);const shadow = this.attachShadow({ mode: "open" });shadow.append(content);      }    }    window.customElements.define("my-item-s", MyItemShadow);  </script></body>

        影子DOM,其內部元素不可以直接被訪問到

        有一個重要的參數 mode

        • open: shadow root 元素通過 js 從外部訪問根節點
        • closed:拒絕 js 從外部訪問關閉的 shadow root 節點
        <body>  <template id="tpl">    <div></div>    <div></div>  </template>  <note-item title="標題" des="內容"></note-item>  <script>    class NoteItem extends HTMLElement {      constructor() {super();      }      connectedCallback() {const content = document.getElementById("tpl").content.cloneNode(true);const shadow = this.attachShadow({ mode: "open" });shadow.append(content);// 如果是 open 則可以繼續訪問操作內部 dom// console.log(document.querySelector(".note-item").shadowRoot.querySelector(".title"));shadow.querySelector(".title").textContent = this.getAttribute("title");shadow.querySelector(".des").textContent = this.getAttribute("des");      }    }    window.customElements.define("note-item", NoteItem);  </script></body>

        引入外部樣式:

        <body>  <template id="tpl">    <!-- 方式一: -->    <link rel="stylesheet" href="index.css" rel="external nofollow"  />    <div>My Item</div>  </template>  <my-item></my-item>  <script>    class MyItem extends HTMLElement {      constructor() {super();      }      connectedCallback() {const content = document.getElementById("tpl").content.cloneNode(true);const shadow = this.attachShadow({ mode: "open" });shadow.append(content);// 方式二:const linkEl = document.createElement("link");linkEl.setAttribute("rel", "stylesheet");linkEl.setAttribute("href", "index.css");shadow.appendChild(linkEl);      }    }    window.customElements.define("my-item", MyItem);  </script></body>

        動態創建 webComponent 組件例子

        • 通過創建 商品 組件,并使得點擊能跳轉
        <body>  <div id="product-list"></div>  <template id="product-item">    <style>      .product-item {margin-left: 15px;cursor: pointer;      }      .img {width: 100px;      }      .name {text-align: center;      }      .price {color: #999;text-align: center;      }    </style>    <div>      <img src="https://misc.360buyimg.com/lib/skin/e/i/error-jd.gif" />      <div></div>      <div></div>    </div>  </template>  <script>    class ProductItemElement extends HTMLElement {      constructor(props) {super(props);this.addEventListener("click", () => {  window.open(`https://item.jd.com/${this.id}.html`);});      }      connectedCallback() {const shadow = this.attachShadow({ mode: "open" });const content = document.getElementById("product-item").content.cloneNode(true);content.querySelector(".img").src = this.img;content.querySelector(".name").innerText = this.name;content.querySelector(".price").innerText = this.price;shadow.appendChild(content);      }    }    window.customElements.define("product-item", ProductItemElement);  </script>  <script>    const products = [      {name: "關東煮",img: "http://img10.360buyimg.com/seckillcms/s200x200_jfs/t1/121953/18/20515/175357/61e7dc79Ee0acbf20/4f4f56abd2ea2f75.jpg!cc_200x200.webp",id: "10026249568453",price: 49.8      },      {name: "土雞蛋",img: "http://img11.360buyimg.com/seckillcms/s200x200_jfs/t1/172777/32/27438/130981/61fbd2e0E236000e0/7f5284367e2f5da6.jpg!cc_200x200.webp",id: "10024773802639",price: 49.8      },      {name: "東北蜜棗粽子",img: "http://img20.360buyimg.com/seckillcms/s200x200_jfs/t1/129546/31/19459/110768/60b1f4b4Efd47366c/3a5b80c5193bc6ce.jpg!cc_200x200.webp",id: "10035808728318",price: 15      }    ];    const productList = document.getElementById("product-list");    const elList = products.map(product => {      // 創建組件      const el = document.createElement("product-item");      el.img = product.img;      el.name = product.name;      el.price = product.price;      el.id = product.id;      return el;    });    productList.append.apply(productList, elList);  </script></body>

        以上就是2023年了該了解下WebComponent使用教程的詳細內容,更多關于WebComponent使用教程的資料請關注其它相關文章!

        標簽: JavaScript
        主站蜘蛛池模板: 微信小程序定制,广州app公众号商城网站开发公司-广东锋火 | 步进_伺服_行星减速机,微型直流电机,大功率直流电机-淄博冠意传动机械 | 首页-恒温恒湿试验箱_恒温恒湿箱_高低温试验箱_高低温交变湿热试验箱_苏州正合 | 上海冠顶工业设备有限公司-隧道炉,烘箱,UV固化机,涂装设备,高温炉,工业机器人生产厂家 | 合肥汽车充电桩_安徽充电桩_电动交流充电桩厂家_安徽科帝新能源科技有限公司 | 玻璃瓶厂家_酱菜瓶厂家_饮料瓶厂家_酒瓶厂家_玻璃杯厂家_徐州东明玻璃制品有限公司 | 垃圾处理设备_餐厨垃圾处理设备_厨余垃圾处理设备_果蔬垃圾处理设备-深圳市三盛环保科技有限公司 | 校服厂家,英伦校服定做工厂,园服生产定制厂商-东莞市艾咪天使校服 | 淋巴细胞分离液_口腔医疗器材-精欣华医疗器械(无锡)有限公司 | 北京网站建设-企业网站建设-建站公司-做网站-北京良言多米网络公司 | 氧化锆陶瓷_氧化锆陶瓷加工_氧化锆陶瓷生产厂家-康柏工业陶瓷有限公司 | 膏剂灌装旋盖机-眼药水灌装生产线-西林瓶粉剂分装机-南通博琅机械科技 | 拉卡拉POS机官网 - 官方直营POS机办理|在线免费领取 | 螺纹三通快插接头-弯通快插接头-宁波舜驰气动科技有限公司 | 硬度计_影像测量仪_维氏硬度计_佛山市精测计量仪器设备有限公司厂家 | 耐磨陶瓷管道_除渣器厂家-淄博浩瀚陶瓷科技有限公司 | 优考试_免费在线考试系统_培训考试系统_题库系统_组卷答题系统_匡优考试 | 青州搬家公司电话_青州搬家公司哪家好「鸿喜」青州搬家 | 【直乐】河北石家庄脊柱侧弯医院_治疗椎间盘突出哪家医院好_骨科脊柱外科专业医院_治疗抽动症/关节病骨伤权威医院|排行-直乐矫形中医医院 | COD分析仪|氨氮分析仪|总磷分析仪|总氮分析仪-圣湖Greatlake | 华夏医界网_民营医疗产业信息平台_民营医院营销管理培训 | 南汇8424西瓜_南汇玉菇甜瓜-南汇水蜜桃价格 | 塑料脸盆批发,塑料盆生产厂家,临沂塑料广告盆,临沂家用塑料盆-临沂市永顺塑业 | 伺服电机维修、驱动器维修「安川|三菱|松下」伺服维修公司-深圳华创益 | 超声骨密度仪,双能X射线骨密度仪【起草单位】,骨密度检测仪厂家 - 品源医疗(江苏)有限公司 | 铝板冲孔网,不锈钢冲孔网,圆孔冲孔网板,鳄鱼嘴-鱼眼防滑板,盾构走道板-江拓数控冲孔网厂-河北江拓丝网有限公司 | 电缆桥架生产厂家_槽式/梯式_热镀锌线槽_广东东莞雷正电气 | 尚为传动-专业高精密蜗轮蜗杆,双导程蜗轮蜗杆,蜗轮蜗杆减速机,蜗杆减速机生产厂家 | 丽陂特官网_手机信号屏蔽器_Wifi信号干扰器厂家_学校考场工厂会议室屏蔽仪 | 奇酷教育-Python培训|UI培训|WEB大前端培训|Unity3D培训|HTML5培训|人工智能培训|JAVA开发的教育品牌 | 橡胶电子拉力机-塑料-微电脑电子拉力试验机厂家-江苏天源 | 西子馋火锅鸡加盟-太原市龙城酉鼎餐饮管理有限公司 | 宿松新闻网 宿松网|宿松在线|宿松门户|安徽宿松(直管县)|宿松新闻综合网站|宿松官方新闻发布 | 防爆型气象站_农业气象站_校园气象站_农业四情监测系统「山东万象环境科技有限公司」 | 车件|铜件|车削件|车床加工|五金冲压件-PIN针,精密车件定制专业厂商【东莞品晔】 | 净水器代理,净水器招商,净水器加盟-FineSky德国法兹全屋净水 | 精密光学实验平台-红外粉末压片机模具-天津博君 | 浴室柜-浴室镜厂家-YINAISI · 意大利设计师品牌 | 咿耐斯 |-浙江台州市丰源卫浴有限公司 | pos机办理,智能/扫码/二维码/微信支付宝pos机-北京万汇通宝商贸有限公司 | BESWICK球阀,BESWICK接头,BURKERT膜片阀,美国SEL继电器-东莞市广联自动化科技有限公司 | 生物除臭剂-除味剂-植物-污水除臭剂厂家-携葵环保有限公司 |