web component

什麼是web component

如今的前端開發幾乎已經離不開組件化開發了,不管是vue中的模板語法仍是react中的JSX,都是把結構、樣式和邏輯封裝成一個組件,採用組件複用來提升開發效率。可是這一類組件在引入後可能對頁面其餘代碼或者樣式產生影響,好比引入第三方組件庫elementUI,若是頁面中某個元素樣式類在elementUI樣式庫中存在,那麼這個元素的樣式就會受到elementUI樣式庫的影響。WebComponents 是這類問題最好的良藥,經過一種標準化的非侵入的方式封裝一個組件,每一個組件能組織好它自身的 HTML 結構、CSS 樣式、javascript 代碼,而且不會干擾頁面上的其餘代碼。javascript

開發者能經過 shadow DOM 在文檔流中建立一些徹底獨立於其餘元素的子 DOM(sub-DOM trees), 因爲這個特性,使得咱們能夠封裝一個具備獨立功能的組件,而且能夠保證不會在不無心中干擾到其它 DOM 元素。shadow DOM 和標準的 DOM 同樣,能夠設置它的樣式,也能夠用 javascript 操做它的行爲。主文檔流和基於 shadow DOM 建立的獨立組件之間的互不干擾,因此組件的複用也就變得異常簡單方便。html

WebComponents除了是一個獨立組件以外,還有一個很重要的優勢,那就是WebComponents能夠跨語音、跨框架使用,好比咱們封裝了一個WebComponent,就能夠用在vue、react等框架中。前端

構建web compoenent

這裏咱們採用vue-cli3構建一個webcomponentvue

建立組件comAjava

<template>
  <div>
    <span>這是組件A</span>
    <slot name="default"></slot>// webcomponent還支持slot
  </div>
</template>

<script>
export default {
  name: 'comA',
  data() {
    return {}
  },
}
</script>

建立組件comBreact

<template>
  <div>這是組件B</div>
</template>

<script>
export default {
  name: 'comB',
  data() {
    return {}
  },
}
</script>

配置打包腳本git

// package.json
{
  "name": "vue",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "lib": "vue-cli-service build --target wc --name foo src/components/*/*.vue"
  },
  "dependencies": {
    "core-js": "^3.4.4",
    "vue": "^2.6.10"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.1.0",
    "@vue/cli-plugin-eslint": "^4.1.0",
    "@vue/cli-service": "^4.1.0",
    "@vue/eslint-config-prettier": "^6.0.0",
    "babel-eslint": "^10.0.3",
    "eslint": "^5.16.0",
    "eslint-plugin-prettier": "^3.1.2",
    "eslint-plugin-vue": "^5.0.0",
    "prettier": "^1.19.1",
    "vue-template-compiler": "^2.6.10"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}

執行npm run lib,打包效果:
image.png
打包生成目錄:
image.png
檢驗組件是否獨立,咱們往demo.html加上樣式看能不能影響到comA組件github

<meta charset="utf-8">
<title>foo demo</title>
<script src="https://unpkg.com/vue"></script>
<script src="./foo.js"></script>

<style>
  span {
    color: red;
  }
</style>

<span>222222222</span>
<foo-com-a><span slot="default">11111111</span></foo-com-a>

<foo-com-b></foo-com-b>

效果:
image.png
能夠看到外部樣式並不能影響到獨立組件web

分析獨立組件原理

image.png
這裏調用了windowcustomElements接口來註冊一個 custom element
image.png
連接:https://developer.mozilla.org...vue-cli

vue_wc_wrapper(external_Vue_default.a, comAshadow)// 返回一個繼承HTMLElment的類,該類定義了元素行爲
// external_Vue_default.a === Vue
// comAshadow自定義的vue組件

code.png

異步 Web Components 組件

當指定多個 Web Components 組件做爲目標時,這個包可能會變得很是大,而且用戶可能只想使用你的包中註冊的一部分組件。這時異步 Web Components 模式會生成一個 code-split 的包,帶一個只提供全部組件共享的運行時,並預先註冊全部的自定義組件小入口文件。一個組件真正的實現只會在頁面中用到自定義元素相應的一個實例時按需獲取:

vue-cli-service build --target wc-async --name foo 'src/components/*.vue'
File                Size                        Gzipped

dist/foo.0.min.js    12.80 kb                    8.09 kb
dist/foo.min.js      7.45 kb                     3.17 kb
dist/foo.1.min.js    2.91 kb                     1.02 kb
dist/foo.js          22.51 kb                    6.67 kb
dist/foo.0.js        17.27 kb                    8.83 kb
dist/foo.1.js        5.24 kb                     1.64 kb

如今用戶在該頁面上只須要引入 Vue 和這個入口文件便可:

<script src="https://unpkg.com/vue"></script>
<script src="path/to/foo.min.js"></script>

<!-- foo-one 的實現的 chunk 會在用到的時候自動獲取 -->
<foo-one></foo-one>

項目地址:https://github.com/Revelation...

參考:
https://www.cnblogs.com/vider...
https://www.cnblogs.com/Adiod...
https://developer.mozilla.org...

相關文章
相關標籤/搜索