1.2w word | От 0 до 1, чтобы начать разработку библиотеки бизнес-компонентов веб-компонентов

внешний интерфейс JavaScript Web Components
1.2w word | От 0 до 1, чтобы начать разработку библиотеки бизнес-компонентов веб-компонентов

Компонентизация — важное направление фронтенд-разработки, с одной стороны, повышающая эффективность разработки, а с другой — снижающая затраты на сопровождение. Основной поток Vue.js, React и его расширения Ant Design, uniapp, Taro и т. д. — все это компонентные фреймворки. ​Web Components— это общий термин для набора собственных веб-API, которые позволяют нам создавать повторно используемые пользовательские компоненты и использовать их в качестве собственных тегов HTML в наших веб-приложениях. В настоящее время многие интерфейсные фреймворки/библиотеки поддерживаютWeb Components.

Эта статья познакомит вас сWeb ComponentsCore API и реализовать библиотеку бизнес-компонентов на основе разработки API веб-компонентов от 0 до 1. ​

окончательный эффект:Пропингуйте 8787.com/exe-comp один…Адрес склада:GitHub.com/Ping An8787/…

1. Просмотрите веб-компоненты

В истории фронтенд-разработки, от начала повторения бизнеса и повсеместного копирования одного и того же кода до появления веб-компонентов, мы использовали пользовательские компоненты с нативными HTML-тегами для повторного использования кода компонентов для повышения эффективности разработки. Компоненты, созданные с помощью веб-компонентов, можно использовать практически в любой интерфейсной среде.

1. Обзор основного API

Веб-компоненты состоят из 3 основных API:

  • Пользовательские элементы: используется для определенияпользовательский элемента такжеповедение, который предоставляет метку компонента для внешнего мира;
  • Тень ДОМ: используется для инкапсуляции внутренней структуры компонента во избежание конфликтов с внешней средой;
  • HTML-шаблоны:включать<template>а также<slot>Элементы, поэтому мы можем определить HTML-шаблоны различных компонентов, а затем мультиплексировать в другом месте, студенты использовали каркас Vue / React и т. Д. Должен быть очень знакомым.

Кроме того, есть HTML-импорты, но они в настоящее время устарели, поэтому подробно не представлены, а их роль заключается в управлении загрузкой зависимостей компонентов.

image.png

2. Пример начала работы

Давайте быстро рассмотрим следующий простой примерКак создать простые веб-компоненты.

  • использовать компоненты
<!DOCTYPE html>
<html lang="en">
<head>
    <script src="./index.js" defer></script>
</head>
<body>
    <h1>custom-element-start</h1>
    <custom-element-start></custom-element-start>
</body>
</html>
  • определить компоненты
/**
 * 使用 CustomElementRegistry.define() 方法用来注册一个 custom element
 * 参数如下:
 * - 元素名称,符合 DOMString 规范,名称不能是单个单词,且必须用短横线隔开
 * - 元素行为,必须是一个类
 * - 继承元素,可选配置,一个包含 extends 属性的配置对象,指定创建的元素继承自哪个内置元素,可以继承任何内置元素。
 */

class CustomElementStart extends HTMLElement {
    constructor(){
        super();
        this.render();
    }
    render(){
        const shadow = this.attachShadow({mode: 'open'});
        const text = document.createElement("span");
        text.textContent = 'Hi Custom Element!';
        text.style = 'color: red';
        shadow.append(text);
    }
}

customElements.define('custom-element-start', CustomElementStart)

Приведенный выше код в основном делает 3 вещи:

  1. Реализовать класс компонента

путем реализацииCustomElementStartклассы для определения компонентов.

  1. определить компоненты

Принимая метку компонента и класс компонента в качестве параметров, передайтеcustomElements.defineМетоды определяют компоненты.

  1. использовать компоненты

После импорта компонента используйте пользовательский компонент напрямую, как обычные HTML-теги.<custom-element-start></custom-element-start>.

Затем доступ к браузеруindex.htmlВы можете увидеть следующее:image.png

3. Введение в совместимость

существуетMDN | Web ComponentsСовместимость описана в главах:

  • Firefox (версия 63), Chrome и Opera по умолчанию поддерживают веб-компоненты.
  • Safari поддерживает множество функций веб-компонентов, но меньше, чем вышеупомянутые браузеры.
  • Edge работает над реализацией.

Для совместимости вы можете увидеть следующий рисунок:image.pngИсточник изображения:www.webcomponents.org/

На этом веб-сайте есть много отличных проектов о веб-компонентах для изучения.

4. Резюме

В этом разделе в основном используется простой пример для краткого обзора основ, а подробности вы можете прочитать в документации:

image.png

2. Анализ и проектирование библиотеки компонентов EXE-Components

1. Введение

Предположим, нам нужно реализовать библиотеку компонентов EXE-Components, компоненты библиотеки компонентов разделены на 2 категории:

  1. тип компонентов

кОбщие простые компонентыглавным образом, какexe-avatarкомпонент аватара,exe-buttonкомпоненты кнопок и т.д.;

  1. тип модулей

ксложные составные компонентыглавным образом, какexe-user-avatarКомпонент аватара пользователя (включая информацию о пользователе),exe-attachement-listКомпонент списка вложений и многое другое. ​

Подробности можно увидеть ниже:image.png

Далее мы спроектируем и разработаем библиотеку компонентов EXE-Components на основе рисунка выше. ​

2. Дизайн библиотеки компонентов

При проектировании библиотеки компонентов необходимо учитывать следующие моменты:

  1. Именование компонентов, наименование параметров и другие спецификации для облегчения последующего обслуживания компонентов;
  2. Определение параметров компонента;
  3. Изоляция стиля компонента;

Конечно, это самые основные моменты, которые необходимо учитывать.С учетом сложности реального бизнеса необходимо учитывать больше, например: связанные с проектированием, развязку компонентов, тему компонентов и так далее.

В ответ на три пункта, упомянутых выше, вот несколько соглашений об именах:

  1. Имя компонента начинается сexe-功能名称названный какexe-avatarПредставляет компонент аватара;
  2. Имена параметров свойства начинаются сe-参数名称названный какe-srcвыражатьsrcАтрибут адреса;
  3. Имена параметров событий начинаются сon-事件类型названный какon-clickПредставляет событие щелчка;

3. Дизайн компонентов библиотеки компонентов

Здесь мы в основном проектируемexe-avatar,exe-buttonа такжеexe-user-avatarТри компонента, первые два являются простыми компонентами, последний представляет собой сложный компонент, а первые два компонента используются внутри для комбинирования. Здесь сначала определите свойства, поддерживаемые этими тремя компонентами:EXE-Components 组件库.png

Здесь именование атрибута кажется более сложным, вы можете назвать его в соответствии со своими и командными привычками.

Таким образом, наше мышление становится намного яснее, и мы можем реализовать соответствующие компоненты.

Три, подготовка библиотеки компонентов EXE-компонентов

Примеры в этой статье в конечном итоге выполнят реализацию компонентовиспользовать в сочетании, реализовать следующее "список пользователей"Эффект:image.pngАдрес опыта:Пропингуйте 8787.com/exe-comp один…

1. Единые спецификации разработки

Во-первых, давайте унифицируем спецификации разработки, в том числе:

  1. Спецификация каталога

image.png

  1. Определение спецификаций компонентов

image.png

  1. Шаблон разработки компонентов

шаблон разработки компонентовindex.jsфайл входа компонентаа такжеtemplate.js Файл HTML-шаблона компонента:

// index.js 模版
const defaultConfig = {
    // 组件默认配置
}

const Selector = "exe-avatar"; // 组件标签名

export default class EXEAvatar extends HTMLElement {
    shadowRoot = null;
    config = defaultConfig;

    constructor(){
        super();
        this.render(); // 统一处理组件初始化逻辑
    }

    render() {
        this.shadowRoot = this.attachShadow({mode: 'closed'});
        this.shadowRoot.innerHTML = renderTemplate(this.config);
    }
}

// 定义组件
if (!customElements.get(Selector)) {
    customElements.define(Selector, EXEAvatar)
}
// template.js 模版

export default config => {
    // 统一读取配置
    const { avatarWidth, avatarRadius, avatarSrc } = config;
    return `
        <style>
            /* CSS 内容 */
        </style>
        <div class="exe-avatar">
            /* HTML 内容 */
        </div>
    `
}

2. Строительство среды разработки и инженерная обработка

Чтобы облегчить использование библиотеки компонентов EXE-Components и приблизиться к использованию фактической библиотеки компонентов, нам необходимо упаковать библиотеку компонентов в файл js типа UMD. Здесь мы используемrollupСоберите и, наконец, упакуйте вexe-components.jsфайл, который используется следующим образом:

<script src="./exe-components.js"></script>

Далее черезnpm init -yгенерироватьpackage.jsonфайл, затем установите накопительный пакет глобально иhttp-server(Используется для запуска локального сервера для упрощения отладки):

npm init -y
npm install --global rollup http-server

затем вpackage.jsonизscriptдобавить под"dev"а также"build"сценарий:

{
	// ...
  "scripts": {
    "dev": "http-server -c-1 -p 1400",
    "build": "rollup index.js --file exe-components.js --format iife"
  },
}

в:

  • "dev"Команда: Запустите статический сервер через http-сервер для использования в качестве среды разработки. Добавить к-c-1Параметр используется для отключения кеша, чтобы не обновлять страницу и будет кеш.Подробнее см.документация http-сервера;
  • "build"Команда: использовать index.js в качестве входного файла для накопительной упаковки, выводexe-components.jsфайл и имеет тип iife.

Таким образом, инженерная конфигурация простой локальной разработки и построения библиотеки компонентов завершена, после чего можно выполнять разработку. ​

В-четвертых, разработка библиотеки компонентов EXE-компонентов.

1. Конфигурация файла записи библиотеки компонентов

Переднийpackage.jsonнастроено в файле"build"команда, будет использовать корневой каталогindex.jsВ качестве входного файла, а также для облегчения введения компонентов, общих базовых компонентов и модулей, общих сложных компонентов, мы создаем 3index.js, структура каталогов после создания выглядит следующим образом:image.pngСодержимое трех входных файлов следующее:

// EXE-Components/index.js
import './components/index.js';
import './modules/index.js';

// EXE-Components/components/index.js
import './exe-avatar/index.js';
import './exe-button/index.js';

// EXE-Components/modules/index.js
import './exe-attachment-list/index.js.js';
import './exe-comment-footer/index.js.js';
import './exe-post-list/index.js.js';
import './exe-user-avatar/index.js';

2. Разработайте файл index.js компонента exe-аватар.

Из предыдущего анализа мы можем знать, чтоexe-avatarКомпоненты должны поддерживать параметры:

  • e-avatar-src: адрес изображения аватара, например: ./testAssets/images/avatar-1.png
  • e-avatar-width: Ширина аватара, по умолчанию такая же, как высота, например: 52px
  • e-button-radius: закругленные углы аватара, например: 22px, по умолчанию: 50%
  • on-avatar-click: событие щелчка аватара, по умолчанию нет

Затем по предыдущему шаблону разработайте входной файлindex.js:

// EXE-Components/components/exe-avatar/index.js
import renderTemplate from './template.js';
import { Shared, Utils } from '../../utils/index.js';

const { getAttributes } = Shared;
const { isStr, runFun } = Utils;

const defaultConfig = {
    avatarWidth: "40px",
    avatarRadius: "50%",
    avatarSrc: "./assets/images/default_avatar.png",
    onAvatarClick: null,
}

const Selector = "exe-avatar";

export default class EXEAvatar extends HTMLElement {
    shadowRoot = null;
    config = defaultConfig;

    constructor(){
        super();
        this.render();
    }

    render() {
        this.shadowRoot = this.attachShadow({mode: 'closed'});
        this.shadowRoot.innerHTML = renderTemplate(this.config);// 生成 HTML 模版内容
    }

		// 生命周期:当 custom element首次被插入文档DOM时,被调用。
    connectedCallback() {
        this.updateStyle();
        this.initEventListen();
    }

    updateStyle() {
        this.config = {...defaultConfig, ...getAttributes(this)};
        this.shadowRoot.innerHTML = renderTemplate(this.config); // 生成 HTML 模版内容
    }

    initEventListen() {
        const { onAvatarClick } = this.config;
        if(isStr(onAvatarClick)){ // 判断是否为字符串
            this.addEventListener('click', e => runFun(e, onAvatarClick));
        }
    }
}

if (!customElements.get(Selector)) {
    customElements.define(Selector, EXEAvatar)
}

Некоторые из этих методов являются извлекаемыми общедоступными методами, а их функции кратко представлены.Подробности см. в исходном коде:

  • renderTemplateметод

Из методов, предоставляемых template.js, передайте конфигурацию конфигурации для создания HTML-шаблона.

  • getAttributesметод

Передайте элемент HTMLElement и верните все пары ключ-значение атрибута в элементе, который будетe-а такжеon-Атрибуты в начале перерабатываются в обычные атрибуты и атрибуты событий соответственно. Примеры следующие:

// input
<exe-avatar
    e-avatar-src="./testAssets/images/avatar-1.png"
    e-avatar-width="52px"
    e-avatar-radius="22px"
    on-avatar-click="avatarClick()"
></exe-avatar>
  
// output
{
  avatarSrc: "./testAssets/images/avatar-1.png",
  avatarWidth: "52px",
  avatarRadius: "22px",
  avatarClick: "avatarClick()"
}
  • runFunметод

Поскольку метод, передаваемый через атрибут, является строкой, он инкапсулируется и передается вeventИ имя события в качестве параметра, вызовите этот метод, пример такой же, как и в предыдущем шаге, он выполнитavatarClick()метод.

Кроме того, жизненный цикл веб-компонентов можно подробно посмотреть в документации:Использование функций обратного вызова жизненного цикла.

3. Разработайте файл template.js компонента exe-аватар

Этот файл предоставляет метод, который возвращает HTML-шаблон компонента:

// EXE-Components/components/exe-avatar/template.js
export default config => {
  const { avatarWidth, avatarRadius, avatarSrc } = config;
  return `
    <style>
      .exe-avatar {
        width: ${avatarWidth};
        height: ${avatarWidth};
        display: inline-block;
        cursor: pointer;
      }
      .exe-avatar .img {
        width: 100%;
        height: 100%;
        border-radius: ${avatarRadius};
        border: 1px solid #efe7e7;
      }
    </style>
    <div class="exe-avatar">
      <img class="img" src="${avatarSrc}" />
    </div>
  `
}

Окончательный эффект выглядит следующим образом:image.png

После разработки первого компонента мы можем кратко суммировать шаги по созданию и использованию компонента:image.png

4. Разработать компонент exe-кнопки

следовать впередexe-avatarИдеи разработки компонентов, которые можно быстро реализоватьexe-buttonкомпоненты. Необходимо поддерживать следующие параметры:

  • e-button-radius: закругленные углы кнопки, например: 8px
  • e-button-type: тип кнопки, например: по умолчанию, основная, текстовая, пунктирная
  • e-button-text: текст кнопки, по умолчанию: открыть
  • on-button-click: событие нажатия кнопки, по умолчанию нет
// EXE-Components/components/exe-button/index.js
import renderTemplate from './template.js';
import { Shared, Utils } from '../../utils/index.js';

const { getAttributes } = Shared;
const { isStr, runFun } = Utils;
const defaultConfig = {
    buttonRadius: "6px",
    buttonPrimary: "default",
    buttonText: "打开",
    disableButton: false,
    onButtonClick: null,
}

const Selector = "exe-button";

export default class EXEButton extends HTMLElement {
    // 指定观察到的属性变化,attributeChangedCallback 会起作用
    static get observedAttributes() { 
        return ['e-button-type','e-button-text', 'buttonType', 'buttonText']
    }

    shadowRoot = null;
    config = defaultConfig;

    constructor(){
        super();
        this.render();
    }

    render() {
        this.shadowRoot = this.attachShadow({mode: 'closed'});
    }

    connectedCallback() {
        this.updateStyle();
        this.initEventListen();
    }

    attributeChangedCallback (name, oldValue, newValue) {
        // console.log('属性变化', name)
    }

    updateStyle() {
        this.config = {...defaultConfig, ...getAttributes(this)};
        this.shadowRoot.innerHTML = renderTemplate(this.config);
    }

    initEventListen() {
        const { onButtonClick } = this.config;
        if(isStr(onButtonClick)){
            const canClick = !this.disabled && !this.loading
            this.addEventListener('click', e => canClick && runFun(e, onButtonClick));
        }
    }

    get disabled () {
        return this.getAttribute('disabled') !== null;
    }

    get type () {
        return this.getAttribute('type') !== null;
    }

    get loading () {
        return this.getAttribute('loading') !== null;
    }
}

if (!customElements.get(Selector)) {
    customElements.define(Selector, EXEButton)
}

Шаблон определяется следующим образом:

// EXE-Components/components/exe-button/tempalte.js
// 按钮边框类型
const borderStyle = { solid: 'solid', dashed: 'dashed' };

// 按钮类型
const buttonTypeMap = {
    default: { textColor: '#222', bgColor: '#FFF', borderColor: '#222'},
    primary: { textColor: '#FFF', bgColor: '#5FCE79', borderColor: '#5FCE79'},
    text: { textColor: '#222', bgColor: '#FFF', borderColor: '#FFF'},
}

export default config => {
    const { buttonRadius, buttonText, buttonType } = config;

    const borderStyleCSS = buttonType 
        && borderStyle[buttonType] 
        ? borderStyle[buttonType] 
        : borderStyle['solid'];

    const backgroundCSS = buttonType 
        && buttonTypeMap[buttonType] 
        ? buttonTypeMap[buttonType] 
        : buttonTypeMap['default'];

    return `
        <style>
            .exe-button {
                border: 1px ${borderStyleCSS} ${backgroundCSS.borderColor};
                color: ${backgroundCSS.textColor};
                background-color: ${backgroundCSS.bgColor};
                font-size: 12px;
                text-align: center;
                padding: 4px 10px;
                border-radius: ${buttonRadius};
                cursor: pointer;
                display: inline-block;
                height: 28px;
            }
            :host([disabled]) .exe-button{ 
                cursor: not-allowed; 
                pointer-events: all; 
                border: 1px solid #D6D6D6;
                color: #ABABAB;
                background-color: #EEE;
            }
            :host([loading]) .exe-button{ 
                cursor: not-allowed; 
                pointer-events: all; 
                border: 1px solid #D6D6D6;
                color: #ABABAB;
                background-color: #F9F9F9;
            }
        </style>
        <button class="exe-button">${buttonText}</button>
    `
}

Окончательный эффект выглядит следующим образом:image.png

5. Разработайте компонент exe-user-avatar

Этот компонент является переднимexe-avatarкомпоненты иexe-buttonкомпоненты объединены, нужно не только поддерживатьсобытие щелчка, тоже нужна поддержкаслот слот функция. ​ Поскольку это комбинация, ее относительно просто разработать ~ сначала взгляните на файл ввода:

// EXE-Components/modules/exe-user-avatar/index.js

import renderTemplate from './template.js';
import { Shared, Utils } from '../../utils/index.js';

const { getAttributes } = Shared;
const { isStr, runFun } = Utils;

const defaultConfig = {
    userName: "",
    subName: "",
    disableButton: false,
    onAvatarClick: null,
    onButtonClick: null,
}

export default class EXEUserAvatar extends HTMLElement {
    shadowRoot = null;
    config = defaultConfig;

    constructor() {
        super();
        this.render();
    }

    render() {
        this.shadowRoot = this.attachShadow({mode: 'open'});
    }

    connectedCallback() {
        this.updateStyle();
        this.initEventListen();
    }

    initEventListen() {
        const { onAvatarClick } = this.config;
        if(isStr(onAvatarClick)){
            this.addEventListener('click', e => runFun(e, onAvatarClick));
        }
    }

    updateStyle() {
        this.config = {...defaultConfig, ...getAttributes(this)};
        this.shadowRoot.innerHTML = renderTemplate(this.config);
    }
}

if (!customElements.get('exe-user-avatar')) {
    customElements.define('exe-user-avatar', EXEUserAvatar)
}

Основное содержимое находится в template.js:

// EXE-Components/modules/exe-user-avatar/template.js

import { Shared } from '../../utils/index.js';

const { renderAttrStr } = Shared;

export default config => {
    const { 
        userName, avatarWidth, avatarRadius, buttonRadius, 
        avatarSrc, buttonType = 'primary', subName, buttonText, disableButton,
        onAvatarClick, onButtonClick
    } = config;
    return `
        <style>
            :host{
                color: "green";
                font-size: "30px";
            }
            .exe-user-avatar {
                display: flex;
                margin: 4px 0;
            }
            .exe-user-avatar-text {
                font-size: 14px;
                flex: 1;
            }
            .exe-user-avatar-text .text {
                color: #666;
            }
            .exe-user-avatar-text .text span {
                display: -webkit-box;
                -webkit-box-orient: vertical;
                -webkit-line-clamp: 1;
                overflow: hidden;
            }
            exe-avatar {
                margin-right: 12px;
                width: ${avatarWidth};
            }
            exe-button {
                width: 60px;
                display: flex;
                justify-content: end;
            }
        </style>
        <div class="exe-user-avatar">
            <exe-avatar
                ${renderAttrStr({
                    'e-avatar-width': avatarWidth,
                    'e-avatar-radius': avatarRadius,
                    'e-avatar-src': avatarSrc,
                })}
            ></exe-avatar>
            <div class="exe-user-avatar-text">
                <div class="name">
                    <span class="name-text">${userName}</span>
                    <span class="user-attach">
                        <slot name="name-slot"></slot>
                    </span>
                </div>
                <div class="text">
                    <span class="name">${subName}<slot name="sub-name-slot"></slot></span>
                </div>
            </div>
            ${
                !disableButton && 
                `<exe-button
                    ${renderAttrStr({
                        'e-button-radius' : buttonRadius,
                        'e-button-type' : buttonType,
                        'e-button-text' : buttonText,
                        'on-avatar-click' : onAvatarClick,
                        'on-button-click' : onButtonClick,
                    })}
                ></exe-button>`
            }

        </div>
    `
}

вrenderAttrStrМетод принимает объект свойства и возвращает его строку пары ключ-значение:

// input
{
  'e-avatar-width': 100,
  'e-avatar-radius': 50,
  'e-avatar-src': './testAssets/images/avatar-1.png',
}
  
// output
"e-avatar-width='100' e-avatar-radius='50' e-avatar-src='./testAssets/images/avatar-1.png' "

Окончательный эффект выглядит следующим образом:image.png

6. Внедрите бизнес со списком пользователей

Далее, давайте посмотрим на влияние наших компонентов на реальный бизнес:

image.pngНа самом деле реализация тоже очень проста, согласно приведенным данным, компоненты могут быть переработаны и использованы, предполагая следующие пользовательские данные:

const users = [
  {"name":"前端早早聊","desc":"帮 5000 个前端先跑 @ 前端早早聊","level":6,"avatar":"qdzzl.jpg","home":"https://juejin.cn/user/712139234347565"}
  {"name":"来自拉夫德鲁的码农","desc":"谁都不救我,谁都救不了我,就像我救不了任何人一样","level":2,"avatar":"lzlfdldmn.jpg","home":"https://juejin.cn/user/994371074524862"}
  {"name":"黑色的枫","desc":"永远怀着一颗学徒的心。。。","level":3,"avatar":"hsdf.jpg","home":"https://juejin.cn/user/2365804756348103"}
  {"name":"captain_p","desc":"目的地很美好,路上的风景也很好。今天增长见识了吗","level":2,"avatar":"cap.jpg","home":"https://juejin.cn/user/2532902235026439"}
  {"name":"CUGGZ","desc":"文章联系微信授权转载。微信:CUG-GZ,添加好友一起学习~","level":5,"avatar":"cuggz.jpg","home":"https://juejin.cn/user/3544481220801815"}
  {"name":"政采云前端团队","desc":"政采云前端 ZooTeam 团队,不掺水的原创。 团队站点:https://zoo.team","level":6,"avatar":"zcy.jpg","home":"https://juejin.cn/user/3456520257288974"}
]

Мы можем объединить фрагменты HTML с помощью простого цикла for и добавить их к элементу на странице:

// 测试生成用户列表模版
const usersTemp = () => {
    let temp = '', code = '';
    users.forEach(item => {
        const {name, desc, level, avatar, home} = item;
        temp += 
`
<exe-user-avatar 
    e-user-name="${name}"
    e-sub-name="${desc}"
    e-avatar-src="./testAssets/images/users/${avatar}"
    e-avatar-width="36px"
    e-button-type="primary"
    e-button-text="关注"
    on-avatar-click="toUserHome('${home}')"
    on-button-click="toUserFollow('${name}')"
>
${
    level >= 0 && `<span slot="name-slot">
        <span class="medal-item">(Lv${level})</span>
    </span>`}
</exe-user-avatar>
`
})
    return temp;
}

document.querySelector('#app').innerHTML = usersTemp;

На данный момент мы поняли, что такое список пользователей.Конечно, реальный бизнес может быть более сложным и нуждается в оптимизации.

V. Резюме

В этой статье сначала кратко рассматривается основной API веб-компонентов, затем анализируются и проектируются требования к библиотеке компонентов, а затем создается и разрабатывается среда. Контента много, и он может не охватывать все пункты. посмотрите на исходный код моего склада.В чем проблема?Добро пожаловать, чтобы обсудить со мной. ​ Несколько основных целей написания этой статьи:

  1. Когда мы получаем новое задание, нам нужно начинать с анализа и проектирования, а потом уже к разработке, а не начинать разработку вслепую;
  2. Давайте посмотрим, как разработать простую библиотеку бизнес-компонентов с помощью веб-компонентов;
  3. Испытайте недостатки разработки библиотеки компонентов с помощью веб-компонентов (то есть слишком много вещей, которые нужно написать).

После прочтения этой статьи вы думаете, что разрабатывать библиотеки компонентов с помощью веб-компонентов сложно? Слишком много, чтобы написать. Это не имеет значения, в следующей статье я возьму вас с собой, чтобы использовать его вместеStencilФреймворк развивает стандартную библиотеку компонентов Web Components, ведь вся ionic уже используюStencilРефакторинг, общая тенденция веб-компонентов~!

Расширенное чтение