最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解vue3.2新增的defineCustomElement底層原理

 更新時間:2021年08月27日 09:35:53   作者:artist  
本文主要介紹了vue3.2新增的defineCustomElement底層原理,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

Web Components

Web Components 是一套不同的技術(shù),允許您創(chuàng)建可重用的定制元素(它們的功能封裝在您的代碼之外)并且在您的web應(yīng)用中使用它們。

相當(dāng)于是瀏覽器原生的定義組件的方式,不用通過vue或者react這些框架實現(xiàn)組件的定義

customElements

概述

customElements 是Window對象上的一個只讀屬性,接口返回一個CustomElementRegistry 對象的引用,可用于注冊新的 custom elements,或者獲取之前定義過的自定義元素的信息。

HTMLTemplateElement 內(nèi)容模板元素

概述

HTML內(nèi)容模板(<template>)元素是一種用于保存客戶端內(nèi)容機制,該內(nèi)容在加載頁面時不會呈現(xiàn),但隨后可以(原文為 may be)在運行時使用JavaScript實例化。
將模板視為一個可存儲在文檔中以便后續(xù)使用的內(nèi)容片段。雖然解析器在加載頁面時確實會處理<template>元素的內(nèi)容,但這樣做只是為了確保這些內(nèi)容有效;但元素內(nèi)容不會被渲染。

常用屬性

content 獲取DocumentFragment 元素片段的內(nèi)容
相當(dāng)于通過document.createDocumentFragment()創(chuàng)建的元素片段,

  <!-- 定義template片段 -->
  <template id="element-template">
    <div>test-template</div>
  </template>

  <script>
    /* 獲取template片段 */
    const ele = document.getElementById('element-template')
    ele.content instanceof DocumentFragment  //true

    /* 通過createDocumentFragment創(chuàng)建html片段*/
    const div = document.createDocumentFragment('div')
    div instanceof DocumentFragment    //true

    /* 結(jié)論 */
    // 定義在html上的template獲取它的content相當(dāng)于和通過createDocumentFragment創(chuàng)建的html片段是一個東西
  </script>

ShadowRoot

概述

Shadow DOM API 的 ShadowRoot 接口是一個 DOM 子樹的根節(jié)點, 它與文檔的主 DOM 樹分開渲染。
你可以通過使用一個元素的 Element.shadowRoot 屬性來檢索它的參考,假設(shè)它是由 Element.attachShadow() 創(chuàng)建的并使 mode 設(shè)置為 open.

通過 Element.attachShadow()掛載影子DOM

完整的演示代碼

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>

  <test-shadow-root></test-shadow-root>

  <template id="temEle">
    <style>
      .main{
        color: #f00;
      }
    </style>
    <div class="main">
      我是template片段
      <!-- 使用插槽 -->
      <slot name="header"></slot>
    </div>
  </template>
  <test-template-ele>
    <!-- 定義插槽 -->
    <style>
      .slot{
        color: rgb(87, 28, 223);
      }
    </style>
    <div class="slot" slot="header">我是slot</div>
  </test-template-ele>

  <!-- 生命周期測試 -->
  <div id="moveDiv">
    <button id="add">添加</button>
    <button id="update">更新</button>
    <button id="move">移動</button>
    <button id="remove">刪除</button>
  </div>

  <!-- 通過is掛載 -->
  <div is="test-is-com">
    <div>AAA</div>
  </div>


  <script>
    /* 自定義web-components */
    customElements.define('test-shadow-root', class extends HTMLElement {
      /* 當(dāng)test-shadow-root組件被掛載到DOM上時,執(zhí)行構(gòu)造函數(shù) */
      constructor() {
        super()
        const shadowRoot = this.attachShadow({mode: 'open'}) //給指定的元素掛載影子DOM
        // 當(dāng)執(zhí)行 this.attachShadow()方法時,shadowRoot被掛載構(gòu)造函數(shù)中,可以通過this訪問
        // mode open shadow root元素可以從js外部訪問根節(jié)點
        // mode closed  拒絕從js外部訪問關(guān)閉的shadow root節(jié)點
        // console.log('執(zhí)行', this)
        const div = document.createElement('div')
        div.textContent = '我是div的內(nèi)容'
        // shadowRoot.appendChild()
        // console.log('this', this.shadowRoot)
        shadowRoot.appendChild(div)
        // this.shadowRoot === shadowRoot  true
      }
    })

    /* 通過template自定義HTMLTemplateElement */
    customElements.define('test-template-ele', class extends HTMLElement {
      constructor() {
        super()
        const temEle = document.querySelector('#temEle')
        const templateContent = temEle.content //獲取html片段
        // console.log('AA', templateContent instanceof DocumentFragment) //true
        // templateContent
        // 創(chuàng)建影子DOM,用于掛載template的片段
        const shadowRoot = this.attachShadow({mode: 'open'})
        // console.log('shadowRoot', shadowRoot)
        shadowRoot.appendChild(templateContent)
      }
    })

    /* 通過js創(chuàng)建web-組件,測試生命周期函數(shù) */
      class LifeCycle extends HTMLElement {
        static get observedAttributes() {  //必須添加組件上的屬性,才能觸發(fā)attributeChangedCallback
          return ['c', 'l'];
        }

        constructor() {
          super()
          const shadowRoot = this.attachShadow({mode: 'open'})
          const div = `<div>
            <heaher>我的頭</header>
            <div>內(nèi)容</div>
            <footer>尾部</footer>
          </div>`
          shadowRoot.innerHTML = div
        }

        connectedCallback() {  //添加時,執(zhí)行
          console.log('添加')
        }
        disconnectedCallback() {//刪除時,執(zhí)行
          console.log('disconnectedCallback')
        }
        adoptedCallback() {
          console.log('adoptedCallback')
        }
        attributeChangedCallback() {  //屬性被改變時
          console.log('attributeChangedCallback')
        }
      }

      customElements.define('test-life-cycle', LifeCycle)

      const add = document.querySelector('#add')
      const update = document.querySelector('#update')
      const move = document.querySelector('#move')
      const remove = document.querySelector('#remove')
      const moveDiv = document.querySelector('#moveDiv')
      let testLifeDom = null

      function random(min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
      }

      add.addEventListener('click', () => {
        testLifeDom = document.createElement('test-life-cycle')  //創(chuàng)建上面定義的自定義組件
        // console.log('testLifeDom', testLifeDom)
        document.body.appendChild(testLifeDom);
        testLifeDom.setAttribute('l', '100');
        testLifeDom.setAttribute('c', 'red');
        console.log('add', testLifeDom)
      })

      update.addEventListener('click', () => {
        const div = '<div>更新后</div>'
        // console.log('update', testLifeDom.shadowRoot.innerHTML)
        testLifeDom.shadowRoot.innerHTML = div
        testLifeDom.setAttribute('l', random(50, 200));
        testLifeDom.setAttribute('c', `rgb(${random(0, 255)}, ${random(0, 255)}, ${random(0, 255)})`);
      })

      move.addEventListener('click', () => {
        console.log('moveDiv', moveDiv)
        moveDiv.appendChild(testLifeDom)
      })

      remove.addEventListener('click', () => {
        console.log('remove')
        document.body.removeChild(testLifeDom);
      })

      /* 通過is掛載組件 */

      customElements.define('test-is-com', class extends HTMLDivElement {
        constructor() {
          super()
          console.log('掛載', this.innerHTML)
          // 通過掛載,this,就是當(dāng)前被掛載的元素實例,通過這種方式,可以實現(xiàn)一些操作
        }
      }, {extends: 'div'})

  </script>
</body>
</html>

到此這篇關(guān)于詳解vue3.2新增的defineCustomElement底層原理的文章就介紹到這了,更多相關(guān)vue3.2 defineCustomElement內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue 虛擬DOM快速入門

    vue 虛擬DOM快速入門

    這篇文章主要介紹了vue 虛擬DOM的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-04-04
  • 淺析Vue 中的 render 函數(shù)

    淺析Vue 中的 render 函數(shù)

    在vue中我們使用模板HTML語法組建頁面的,使用render函數(shù)我們可以用js語言來構(gòu)建DOM,今天小編就通過本文給大家簡單介紹下Vue 中 render 函數(shù),需要的朋友可以參考下
    2020-02-02
  • vue-cli是什么及創(chuàng)建vue-cli項目的方法

    vue-cli是什么及創(chuàng)建vue-cli項目的方法

    vue-cli是 vue 官方提供的、快速生成 vue 工程化項目的工具,支持創(chuàng)建vue2和vue3的項目,本文給大家詳細講解vue-cli是什么及創(chuàng)建vue-cli項目的方法,感興趣的朋友跟隨小編一起看看吧
    2023-04-04
  • 詳解vue-router2.0動態(tài)路由獲取參數(shù)

    詳解vue-router2.0動態(tài)路由獲取參數(shù)

    本篇文章主要介紹了詳解vue-router2.0動態(tài)路由獲取參數(shù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • vue+el-select?多數(shù)據(jù)分頁搜索組件的實現(xiàn)

    vue+el-select?多數(shù)據(jù)分頁搜索組件的實現(xiàn)

    本文主要介紹了vue+el-select?多數(shù)據(jù)分頁搜索組件的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • vue如何使用媒體查詢實現(xiàn)響應(yīng)式

    vue如何使用媒體查詢實現(xiàn)響應(yīng)式

    這篇文章主要介紹了vue如何使用媒體查詢實現(xiàn)響應(yīng)式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue中給el-radio添加tooltip并實現(xiàn)點擊跳轉(zhuǎn)方式

    vue中給el-radio添加tooltip并實現(xiàn)點擊跳轉(zhuǎn)方式

    這篇文章主要介紹了vue中給el-radio添加tooltip并實現(xiàn)點擊跳轉(zhuǎn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Vue混合文件使用以及ref的引用實例詳解

    Vue混合文件使用以及ref的引用實例詳解

    ref用來輔助開發(fā)者在不依賴于jQuery的情況下,獲取DOM元素或組件的引用,下面這篇文章主要給大家介紹了關(guān)于Vue混合文件使用以及ref的引用的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • import.meta.glob() 如何導(dǎo)入多個目錄下的資源(最新推薦)

    import.meta.glob() 如何導(dǎo)入多個目錄下的資源(最新推薦)

    import.meta.glob() 其實不僅能接收一個字符串,還可以接收一個字符串?dāng)?shù)組,就是匹配多個位置,本文給大家介紹import.meta.glob() 如何導(dǎo)入多個目錄下的資源,感興趣的朋友一起看看吧
    2023-11-11
  • 10個Vue3中常用的組合式?API用法詳解

    10個Vue3中常用的組合式?API用法詳解

    通過Vue?3,組合式API增強了我們利用Vue的能力,使我們的代碼更具模塊性和可讀性,本文主要來和大家分享10個常用的Vue3組合式API,希望對大家有所幫助
    2024-01-01

最新評論

南开区| 金塔县| 台安县| 本溪市| 南漳县| 北京市| 洪雅县| 赫章县| 航空| 屏山县| 隆林| 长乐市| 云林县| 竹溪县| 尼玛县| 怀来县| 鄂尔多斯市| 邯郸县| 宁安市| 丰镇市| 大同市| 吉木乃县| 伊金霍洛旗| 玉林市| 慈利县| 信阳市| 开化县| 当涂县| 诸城市| 资溪县| 丹江口市| 绍兴县| 霍城县| 郎溪县| 道真| 乐山市| 炉霍县| 潜江市| 横山县| 西峡县| 石屏县|