[Web翻译]使用Open-WC创建一个Web Components

716 阅读8分钟

原文地址:www.nexmo.com/blog/2020/0…

原文作者:www.nexmo.com/blog/author…

发布时间:2020年8月13日

在本系列之前,我们介绍了什么是Web Components,以及用于创建它们的一些工具。现在,我们将创建一个Web Components,发布它,并在网页上使用它。

我们将制作什么?使用Material Design Web Components制作一个键盘组件。构建一个由Web Components组成的Web Components,很玄乎,我知道。

我们的想法是能够在项目中插入一个键盘,尽可能少的麻烦。只需几行代码,用户就可以拥有在应用程序中输入数字的方式,来拨打电话、设置温度、选择测验的答案、投票,以及其他许多应用。

我们来列举一下将要构建的键盘组件的功能。

  • 开箱即用的Web Components将呈现一个显示屏,在它下面,有0 -9、*和#等数字的按钮。
  • 用户可以通过设置属性和特性来隐藏显示和*、#按钮。
  • 当用户点击按钮时,一个字符将被添加到显示屏中。同时,一个自定义事件将被发送,这样组件外部的应用程序将知道一个按钮被按下。
  • 将会有一个'Action'按钮,它将会把所有被按下的数字作为一个自定义事件发送,让更大的应用程序如何处理它。按钮的文本可以由用户通过一个属性来设置。
  • 另一个按钮将提供给用户来 "结束 "动作。它的文本也是可以自定义的。当按下按钮时,显示将被清除,并且另一个自定义事件将被发送到应用程序以使其知道。
  • Web Components将有一个可用的公共方法,因此应用程序可以切换到 "活动 "状态,然后显示 "结束 "按钮。
  • 为了给Web Components添加一些样式,将使用Material Design按钮和textfield组件。

请看Web Components的操作

这里是CodePen上的一个工作实例

codepen.io/conshus/emb…

继续输入一些数字,按回车键。在提示上点击确定,然后点击取消。

使用Open Web Components构建组件

我们将如何构建这个键盘组件?我们将通过Open Web Components (Open-WC)的方式使用lit-html。正如他们网站上所说。

Open Web Components的目标是让每个人都能通过一个强大的、经过实战检验的设置来分享开源的网络组件。我们试图通过给出一套关于如何促进你的Web Components项目的建议和默认值来实现这个目标。我们的建议包括:开发、磨合、测试、工具、演示、发布和自动化。

通过从Open-WC开始,团队中的每个人都可以有相同的起点来构建Web Components。与许多事情一样,一致性是成功的因素。

由于Open-WC对如何构建Web Components和项目非常有意见,他们有一个非常彻底的CLI工具来生成它们。让我们设置好一切。

在你的终端中,导航到Web Components项目所在的地方,然后,键入npm init @open-WC。

然后,键入npm init @open-WC。这将启动Open-WC设置过程。

以下是我在这篇博文中为项目使用的选项。

  • 你今天想做什么?构建一个新项目
  • 你想做什么脚手架?网络组件
  • 你想补充什么?Linting (eslint & prettier)
  • 您想使用排版稿吗?不愿意
  • 你的应用程序/网络组件的标签名是什么? whatever-you-like-keypad (你可以给网络组件取任何你喜欢的名字,只要它至少有两个字用'-'隔开即可)
  • 你想把这个文件结构写入磁盘吗?愿意
  • 你想安装依赖关系吗?是的,使用npm(如果你喜欢yarn,你可以选择这个)。

要安装材料设计按钮和文本字段。进入由Open-WC设置过程创建的新文件夹,并键入以下内容。

npm i @material/mwc-button
npm i @material/mwc-textfield

组件代码

Web Components的代码可以在这个GitHub仓库中找到。让我们来看看src文件夹中唯一一个文件的代码。

首先是导入。Open-WC推荐使用lit-htmllit-element基类来构建和渲染Web组件。我们还导入Material Design按钮和文本字段,以便在Web组件中使用。

import { html, css, LitElement } from 'lit-element';
import '@material/mwc-button/mwc-button';
import '@material/mwc-textfield/mwc-textfield';

我们将新的Web组件基于LitElement。

export class WhateverYouLikeKeypad extends LitElement { {

样式化Web组件

  static get styles() {
    return css`
      :host {
        display: block;
        padding: 25px;
        color: var(--vwc-dialer-text-color, #000);
      }

      #container {
        width: 75vw;
        max-width: 300px;
      }

      .button-row {
        display: flex;
        justify-content: space-evenly;
      }

      .full-width {
        width: 100%;
      }

      mwc-button {
          margin: 10px;
      }

      mwc-textfield {
        --mdc-notched-outline-leading-width: 28px;
        --mdc-notched-outline-leading-border-radius: 28px 0 0 28px;
        --mdc-notched-outline-trailing-border-radius: 0 28px 28px 0;
        width: 100%;
      }
    `;
  }

在这里,Web组件接受的属性和属性与它们的类型一起被设置。这样,lit-html就知道如何处理传递进来的值。

  static get properties() {
    return {
      noAsterisk: { attribute: 'no-asterisk', type: Boolean },
      noHash: { attribute: 'no-hash', type: Boolean },
      noDisplay: { attribute: 'no-display', type: Boolean },
      actionText: { type: String },
      cancelText: { type: String },
      actionStarted: { type: Boolean },
      digits: { type: String }
    };
  }

``Web组件继承了LitElement的所有 "超级 "能力,并定义了默认值。

```js
  constructor() {
    super();
    this.noAsterisk = false;
    this.noHash = false;
    this.noDisplay = false;
    this.digits = "";
    this.actionText = "Enter";
    this.cancelText = "Cancel"
    this.actionStarted = false;
  }

接下来是Web组件的各种方法。比如在添加或发送数字时调度自定义事件,以及结束一个动作。还有一个方法可以在Web组件上调用,让它知道一个动作已经开始。

  __addDigit(digit){
    this.digits += digit;
    const digitAdded = new CustomEvent('digit-added', {
      detail: { digit },
      bubbles: true,
      composed: true });
    this.dispatchEvent(digitAdded);
  }

  __sendDigits(){
    const digitsSent = new CustomEvent('digits-sent', {
      detail: { digits: this.digits },
      bubbles: true,
      composed: true });
    this.dispatchEvent(digitsSent);
  }

  createAction(){
    this.actionStarted = true;
  }

  __endAction(){
    const actionEnded = new CustomEvent('action-ended', {
      detail: { },
      bubbles: true,
      composed: true });
    this.dispatchEvent(actionEnded);
    this.digits = "";
    this.actionStarted = false;
  }

你可能已经注意到,__addDigit函数,只是将数字加到最后。如果用户将光标移动到数字的中间,新的数字将只加到最后。

现在,作为一个练习,让我们允许在光标所在的地方添加新的数字。这里有一个提示,告诉你从哪里开始

渲染Web组件的标记。根据状态和设置的属性/特性,Web组件将渲染或隐藏不同的元素。

  render() {
    return html`
        <div id="container">
            ${this.noDisplay ? "" : html`<mwc-textfield outlined label="" .value=${this.digits}></mwc-textfield>`}
            <div class="button-row">
                  <mwc-button unelevated @click=${()=>this.__addDigit('1')}>1</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('2')}>2</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('3')}>3</mwc-button>
            </div>
            <div class="button-row">
                  <mwc-button unelevated @click=${()=>this.__addDigit('4')}>4</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('5')}>5</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('6')}>6</mwc-button>
            </div>
            <div class="button-row">
                  <mwc-button unelevated @click=${()=>this.__addDigit('7')}>7</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('8')}>8</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('9')}>9</mwc-button>
            </div>
            <div class="button-row">
                  ${this.noAsterisk ?
      ""
      : html`<mwc-button unelevated @click=${()=>this.__addDigit('*')}>*</mwc-button>`
    }
                  <mwc-button unelevated @click=${()=>this.__addDigit('0')}>0</mwc-button>
                  ${this.noHash ?
      ""
      :html`<mwc-button unelevated @click=${()=>this.__addDigit('#')}>#</mwc-button>`
    }
            </div>
            <div class="button-row">
                ${this.actionStarted ?
      html`<mwc-button unelevated fullwidth @click=${this.__endAction}>${this.cancelText}</mwc-button>`
      :html`<mwc-button unelevated fullwidth @click=${this.__sendDigits}>${this.actionText}</mwc-button>`
    }
            </div>
        </div>
    `;
  }

发布您的新Web Components

现在Web Components已经构建完成,让我们来发布它,这样我们和其他人就可以在项目中使用它。

要做到这一点,我们将使用一个像npm这样的注册表。如果你还没有一个,请注册一个账户。这里有一些信息。这不仅会告诉你如何注册账户,而且还会告诉你如何使用终端登录你的账户,以便你可以发布Web Components。

一旦设置完毕,Web Components将作为一个公共范围的包被发布。这将有助于防止冲突,以防万一有一个Web Components或包与您选择的名称相同。关于作用域的更多信息可以在这里找到。

在你的终端中的项目目录下,键入(用你的npm用户名替换你的npm-username)。

npm init --scope=@your-npm-username

接受所有的默认选择,或者根据自己的需要对每一步进行更改。

由于你的Web Components现在是在一个作用域后面,让我们修改由Open-WC生成的Readme来反映这一点。再次用你自己的名字替换占位符(你的-npm-username和whatever-you-like-keypad)。

安装的命令是

npm i @your-npm-username/whatever-you-like-keypad

要在项目中使用它,你将使用如下所示的导入语法。

import '@your-npm-username/whatever-you-like-keypad/whatever-you-like-keypad.js'

保存你的修改。

现在,让我们发布Web Components。在终端中输入

npm publish --access public

如果成功的话,你应该可以在npm网站上找到这个Web Components,网址是:www.npmjs.com/package/@yo…

当然,用你的值代替your-npm-usernamewhatever-you-like-keypad

恭喜您,您已经发布了。您现在有了一个公开的Web Components,您和其他人可以在项目中使用它。

使用Web Components

要在本地安装一个副本,在终端中键入一个项目的目录,同样用你的值替换。

npm i @your-npm-username/whatever-you-like-keypad

但是如果你不想安装这个包呢?也许你想确保你总是加载最新的版本,或者想在一个不允许安装的环境中看到Web组件,比如CodePen

这就是内容分发网络(CDN)的作用。他们托管你的包,你可以直接链接到你的文件。在这篇文章中,我们将使用unpkg.com。他们会自动复制你的文件,所以你不需要做什么。

这里有一个CodePen示例,你可以用它来测试你的Web组件。

再次在HTMLJS选项卡中用你自己的名字替换用户名和组件名称的占位符。

codepen.io/conshus/emb…

试着为我们创建的Web组件添加一些属性和特性(no-asterisk no-hash no-display),并为按钮的文本设置值(actionText="Something" cancelText="Something else")。

注意:当使用no-display时,为了看到数字,需要一个输入或textarea HTML元素。就像这个例子。

codepen.io/conshus/emb…

下一步是什么?

现在你有了一个闪亮的新Web组件,你还能为它添加什么呢?也许,添加一个删除字符的退格键,或者允许用户设置自己的按钮。或者,也许只是创建一个全新的东西。

请在我们的社区Slack频道中留下您的Web组件的链接、问题和/或反馈。我很期待看到你的作品。


通过www.DeepL.com/Translator(免费版)翻译