欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Web?Components實(shí)現(xiàn)類Element?UI中的Card卡片

 更新時(shí)間:2022年07月07日 17:00:35   作者:天問  
這篇文章主要為大家介紹了Web?Components實(shí)現(xiàn)類Element?UI中的Card卡片實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

Web Components 是一個(gè)瀏覽器原生支持的組件化方案,允許你創(chuàng)建新的自定義、可封裝、可重用的HTML 標(biāo)記。不用加載任何外部模塊,直接就可以在瀏覽器中跑。本文就簡(jiǎn)單介紹一下:使用 Web Components 實(shí)現(xiàn)一個(gè)類 Element UI 中的 Card 卡片組件。

隨著前端工程化生態(tài)日益成熟,出現(xiàn)了很多優(yōu)秀的框架,如:Vue、React、Angular等等,極大的提高了日常開發(fā)效率。

其中組件化開發(fā)發(fā)揮了至關(guān)重要的作用,但是這些組件化開發(fā)都需要依賴第三方框架,編譯打包之后才能在瀏覽器正常使用。

而原生組件 Web Components ,相比與第三方框架使用起來更簡(jiǎn)單直接,符合直覺,不用加載任何外部模塊,代碼量小。

Web Components 核心組成

  • 自定義元素(custom element),使用 window.customElements.define API注冊(cè)
  • Shadow DOM隔離,影藏標(biāo)記結(jié)構(gòu)、樣式和行為
  • 可以在<template>中定義標(biāo)記結(jié)構(gòu)、樣式,多次重用。利用 slot 插槽、命名插槽,可以傳入定制化的結(jié)構(gòu)UI,使用上類似 Vue 中的 slot 插槽

1. Custom Elements

自定義的 HTML 標(biāo)簽,稱為自定義元素(custom element)。根據(jù)規(guī)范,自定義元素的名稱必須包含連詞線-,用與區(qū)別原生的 HTML 元素。所以,<com-card>不能寫成<comcard>。

<div id="custom-card" class="com-card">
  <div class="com-card-head">
    <slot name="head"></slot>
  </div>
  <div class="com-card-body">
    <slot></slot>
    <div class="link-wrap">
      <a class="link" href="" title=" rel="external nofollow"  rel="external nofollow" "></a>
    </div>
  </div>
</div>
<script>
  class ComCard extends HTMLElement {
    constructor() {
      super()
      var tplEle = document.getElementById('custom-card')
      this.append(tplEle)
    }
  }
  window.customElements.define('com-card', ComCard)
</script>

這樣就注冊(cè)了瀏覽器可識(shí)別渲染的一個(gè)自定義元素標(biāo)簽。

2. Shadow DOM

Shadow DOM 是對(duì)DOM的一個(gè)封裝。可以將標(biāo)記結(jié)構(gòu)、樣式和行為隱藏起來,并與頁(yè)面上的其他代碼相隔離,保證不同的部分不會(huì)混在一起,可使代碼更加干凈、整潔。

使用自定義元素的 this.attachShadow() 方法可以開啟 Shadow DOM。

class ComCard extends HTMLElement {
  constructor() {
    super()
    var shadow = this.attachShadow({mode: 'closed'})  // open
    var tplEle = document.getElementById('custom-card')
    shadow.appendChild(tplEle)
  }
}
window.customElements.define('com-card', ComCard); 

其中參數(shù){ mode: 'closed' },表示 Shadow DOM 是封閉的,不允許外部訪問。

3. templates 和 slots

因?yàn)榻M件的樣式應(yīng)該與代碼封裝在一起,只對(duì)自定義元素生效,不影響外部的全局樣式。所以,可以把樣式寫在<template>里面,這樣作為自定義元素結(jié)構(gòu)的基礎(chǔ)可以被多次重用。

<template id="custom-card-template">
  <style>
    .com-card {
    }
  </style>
  <div class="com-card">
  </div>
</template>
<script>
  class ComCard extends HTMLElement {
    constructor() {
      super();
      var shadow = this.attachShadow({mode: 'closed'})  // open
      var tplEle = document.getElementById('custom-card-template')
      var content = tplEle.content.cloneNode(true)
      shadow.appendChild(content)
    }
  }
  window.customElements.define('com-card', ComCard);
</script>

完整代碼

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Web Component</title>
  <style>
    * {
        box-sizing: border-box;
    }
    body {
        font-size: 14px;
    }
    .box {
        padding: 5px 0 30px;
    }
    .box .caption {
        display: none;
    }
    .box h1 {
        text-align: center;
    }
    .box li {
        color: #666;
        font-size: 14px;
        line-height: 1.8;
        margin-top: 15px;
    }
    .img {
        display: block;
        width: 80%;
        margin: 0 !important;
    }
    .card-head {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    .card-title {
        color: #333;
        font-size: 16px;
    }
    .card-head-btn {
        color: #409eff;
        cursor: pointer;
        text-decoration: none !important;
    }
    .card-head-btn:hover {
        text-decoration: none;
    }
  </style>
</head>
<body>
<div class="box">
  <h1>Web Component</h1>
  <com-card data-show-head="0" data-url="https://tiven.cn" data-title="天問博客">
    <div slot="head" class="card-head">
      <div class="card-title">卡片名稱</div>
      <a class="card-head-btn">操作按鈕</a>
    </div>
    <img class="img" src="https://tiven.cn/static/img/kpl-sunwukong-a3Lt-ed2NG9r4NFDm_9DA.jpg" alt="天問">
  </com-card>
  

  

  <com-card data-show-head="1" data-url="https://tiven.cn/p/de241e23/" data-title="Vite+Vue3+Vant快速構(gòu)建項(xiàng)目">
    <div slot="head" class="card-head">
      <div class="card-title">卡片名稱</div>
      <a class="card-head-btn" onclick="hello()">操作按鈕</a>
    </div>
    <img class="img" src="https://tiven.cn/static/img/kpl-xuance-JqX71qH7aTflHV_gqvhIc.jpg" alt="天問">
    <ol>
      <li>君不見黃河之水天上來,奔流到海不復(fù)回。</li>
      <li>君不見高堂明鏡悲白發(fā),朝如青絲暮成雪。</li>
      <li>天生我材必有用,千金散盡還復(fù)來。</li>
    </ol>
  </com-card>
</div>
<template id="custom-card-template">
  <style>
    .com-card {
        min-width: 200px;
        min-height: 100px;
        border-radius: 4px;
        border: 1px solid #ebeef5;
        background-color: #fff;
        overflow: hidden;
        color: #303133;
        transition: .3s;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    }
    .com-card-head {
        padding: 10px 20px;
        border-bottom: 1px solid #ebeef5;
        box-sizing: border-box;
    }
    .com-card-body {
        padding: 20px;
    }
    .link-wrap {
        text-align: left;
        padding-top: 20px;
    }
    .link {
        display: inline-block;
        height: 42px;
        line-height: 43px;
        padding: 0 30px;
        text-align: center;
        cursor: pointer;
        color: #fff;
        background-color: #409eff;
        border-color: #409eff;
        -webkit-appearance: none;
        box-sizing: border-box;
        outline: none;
        transition: .1s;
        font-weight: 500;
        -moz-user-select: none;
        -webkit-user-select: none;
        -ms-user-select: none;
        font-size: 14px;
        border-radius: 4px;
        text-decoration: none !important;
    }
  </style>
  <div class="com-card">
    <div class="com-card-head">
      <slot name="head"></slot>
    </div>
    <div class="com-card-body">
      <slot></slot>
      <div class="link-wrap">
        <a class="link" href="" title=" rel="external nofollow"  rel="external nofollow" "></a>
      </div>
    </div>
  </div>
</template>
<script>
  class ComCard extends HTMLElement {
    constructor() {
      super();
      var shadow = this.attachShadow({mode: 'closed'})  // open
      var tplEle = document.getElementById('custom-card-template')
      var content = tplEle.content.cloneNode(true)
      var attrList = Array.from(this.attributes);
      var props = attrList.reduce((prev, item)=>{
        prev[item.name] = item.value
        return prev
      }, {})
      if (props['data-show-head']!=='1') {
        var head = content.querySelector('.com-card-head')
        head.remove()
      }
      var urlEle = content.querySelector('.link')
      if (props['data-url'] && props['data-title']) {
        urlEle.href = props['data-url']
        urlEle.title = props['data-title']
        urlEle.innerText = props['data-title']
      } else {
        urlEle.remove()
      }
      shadow.appendChild(content)
    }
    connectedCallback(){
      //在這里發(fā)送數(shù)據(jù)請(qǐng)求(Ajax)
      console.log('connectedCallback')
    }
    //被從文檔DOM中刪除時(shí)調(diào)用
    disconnectedCallback(){
      console.log('disconnectedCallback')
    }
    //被移動(dòng)到新的文檔時(shí)調(diào)用
    adoptedCallback(){
      console.log('adoptedCallback')
    }
    //當(dāng)增加、刪除、修改自身的屬性時(shí)被調(diào)用
    attributeChangedCallback(){
      console.log('attributeChangedCallback')
    }
  }
  window.customElements.define('com-card', ComCard);
  function hello() {
    alert('Hello,Web Component')
  }
</script>
</body>
</html>

最終效果如上圖所示

Web Components vs Vue Components

Vue ComponentWeb Component
data實(shí)例屬性
propsattributes
watchobservedAttributes、attributeChangedCallback
computedgetters
methodsclass methods
mountedconnectedCallback
destroyeddisconnectedCallback
style scopedtemplate中的style
templatetemplate

Web Components 生命周期回調(diào)函數(shù)

connectedCallback:當(dāng) custom element首次被插入文檔DOM時(shí),被調(diào)用。

disconnectedCallback:當(dāng) custom element從文檔DOM中刪除時(shí),被調(diào)用。

adoptedCallback:當(dāng) custom element被移動(dòng)到新的文檔時(shí),被調(diào)用。

attributeChangedCallback: 當(dāng) custom element增加、刪除、修改自身屬性時(shí),被調(diào)用。

優(yōu)點(diǎn) and 缺點(diǎn)

優(yōu)點(diǎn):

  • 瀏覽器原生支持,不需要引入額外的第三方庫(kù)
  • 語義化
  • 復(fù)用性,移植性高
  • 不同團(tuán)隊(duì)不同項(xiàng)目可以共用組件

缺點(diǎn):

  • 需要操作DOM
  • 目前瀏覽器兼容性、性能方面不夠友好
  • 和外部css交互比較難

基于web components的框架

LitElement 是一個(gè)快速、輕量級(jí)的 Web UI 框架。使用 lit-html 來渲染元素。

Polymer 是一款實(shí)用、基于事件驅(qū)動(dòng)、封裝性和交互性強(qiáng)的 Web UI 框架。

Omi 是基于 Web 組件的跨框架跨平臺(tái)框架 。移動(dòng)端 & 桌面 & 小程序。

以上就是Web Components實(shí)現(xiàn)類Element UI中的Card卡片的詳細(xì)內(nèi)容,更多關(guān)于Web Components實(shí)現(xiàn)Element UI的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論