在上一篇文章中,我们讨论了为什么数据封装是设计良好的 Web 组件的关键特征。 Web 组件作为一个独立的结构,应该最大限度地减少外部依赖,以确保易用性、可移植性和测试性。然而,这种封装给开发者带来了新的挑战:如果一个组件是“隔离的”,那么如何使用外部数据来初始化它?
这个问题提出了一系列与将数据传递到 Web 组件相关的令人着迷的挑战。做好准备——这会太乏味,按照你喜欢的方式来!
初始化 Web 组件是让自定义元素准备好在 Web 应用程序中工作的过程。简单来说,它涉及创建使用 customElements.define 方法注册的类的实例,并运行组件生命周期方法中定义的代码,例如构造函数和connectedCallback。
正如我们在上一篇文章中讨论的,在初始化期间,组件必须建立其本地状态 - 本质上是它将使用的数据对象。该对象可以填充默认值,但通常需要外部数据来填充它。
组件必须以某种方式接收这些外部数据,这意味着数据必须从一开始就存储在某个地方。这些数据在初始化阶段传递给组件。因此,该组件需要一个特定的环境来处理数据的准备、存储和传输,以及启动初始化过程本身。
最简单的初始化情况是针对自治组件。自主组件独立于任何环境或外部因素,使其具有高度通用性。它可以集成到文档的任何部分 - 无论是结构最少的页面还是完全空白的页面。这种方法显着简化了开发,因为您不需要考虑外部环境的具体情况,并且测试变得更加容易。开发人员可以隔离组件并在干净的环境中对其进行测试,而无需重新创建上下文。这不仅节省了时间,还消除了因环境变化而可能影响组件功能的潜在风险。
但是,大多数组件执行更复杂的任务,包括与其他元素或外部数据源交互。为此,他们需要一个环境。在这种情况下,环境尽可能保持简单性至关重要。最终,开发人员的目标是将自主组件的优势与在更复杂的系统中运行的能力结合起来。这可以通过确保环境尽可能保持轻量级和用户友好性、接近自主组件所需的简单性来实现。
那么,这样的环境应该具备哪些特点呢?简单的环境是可以用最少的努力快速设置的环境。为此,它应该是开发人员可以理解的、紧凑的和熟悉的。当开发人员面临一项需要最少操作并使用广泛接受的方法和标准的任务时,工作就会变得更容易、更快地完成。
例如,如果您正在编写 Web 组件,您将立即明白以下代码的作用。您可以凭记忆重复它,也可以简单地将其复制并粘贴到您的项目中,而不会浪费太多时间。
<script> class SomeComponent extends HTMLElement { connectedCallback() { } } customElements.define("some-component", SomeComponent); </script> <some-component></some-component>
这就是为什么简单环境的关键特征是使用标准术语和广泛采用的方法。您的代码越接近标准,就越容易理解、使用和部署。
让我们更深入地探讨在环境中放置组件的主题。我们所说的“放置”究竟是什么意思?在这里,我们指的是与定位相关的所有内容:这可能涉及放置组件的模块文件、组件的 JavaScript 代码本身或将组件添加到页面的 HTML 标记。无论我们放置什么,放置规则必须清晰、易于理解,并且不需要遵循复杂的条件,这一点至关重要。
为了理解为什么这如此重要,让我们看一个标准 HTML 标记的典型示例。我们知道 li 标签通常应该位于 ul 标签内。但是如果我们将 li 放在 div 中会发生什么?或者,相反,如果我们将 div 嵌套在 ul 中,并将 li 放在 div 中?这是此类结构的示例:
<ul> <div> <li></li> <li></li> </div> </ul>
乍一看,这似乎是一个小错误,但这种违反规则的行为可能会导致意想不到的后果。为什么?因为 HTML 规范明确定义了某些元素相对于彼此的放置规则。即使使用众所周知的标签,这也会产生额外的问题和混乱。
现在,想象一下我们建立了严格的规则来将组件放置在环境中。这可能会给开发人员带来更多问题,尤其是那些刚刚开始使用我们的组件的人。例如,该组件是否应该只放置在页面的特定部分?它的相邻元素是否需要遵循某些条件?严格的放置规则可能会使组件的使用变得复杂。
由此,我们可以得出一个重要的结论:如果组件的使用不依赖于严格的放置要求,那么环境会更加简单,组件也会更加用户友好。理想情况下,组件应该足够灵活,可以放置在页面上的任何位置,而无需任何附加条件。
环境的组成越复杂,其整体复杂性就越高。这是显而易见的:执行一项操作总是比执行多项操作容易。每个额外的操作都会增加出错的机会,无论是忘记的操作还是错误执行的步骤。此外,流程中涉及的步骤越多,花费的时间就越多,这会影响整体性能。
让我们在使用组件的背景下看看这个。当一个组件只需要指定一个属性时,使用它是简单而直观的。然而,当一个组件需要同时设置五个属性时,任务就会变得更加困难。如果某些属性的值依赖于其他属性,情况会更加复杂。这种相互依赖性增加了错误的可能性,并需要开发人员给予更多关注。
例如,我曾经使用过一个需要设置初始值和边界值的组件。尽管边界值有默认值,但我经常忘记它们可能不适合特定项目。这导致了必须通过返回文档或重新检查代码来修复的错误。以下是此类组件的代码示例:
<script> class SomeComponent extends HTMLElement { connectedCallback() { } } customElements.define("some-component", SomeComponent); </script> <some-component></some-component>
这里可以看到maximum_value属性有一个默认值,但也可以显式设置。然而,在实际项目中,默认值并不总是满足当前的要求。如果忽视这一点,可能会出现不立即明显的错误。
由此可以得出一个重要的结论:环境的组成部分越少,使用起来就越容易。每个新元素都会增加复杂性,因此最大限度地减少所需配置和依赖项的数量有助于使该过程更易于理解、方便且高效。以这样的方式设计环境,即用户只需最少的操作即可开始,并且您将显着简化它们的使用。
让我们考虑一下组件在初始化期间需要与其环境交互的情况。为此,组件必须能够访问环境——无论是变量、对象还是事件。然而,要使这种交互成功,组件必须“了解”其环境,或者更准确地说,有一个明确的方法来识别它。
一个简单的例子:假设组件需要检索另一个元素的内容。可以按如下方式完成:
<script> class SomeComponent extends HTMLElement { connectedCallback() { } } customElements.define("some-component", SomeComponent); </script> <some-component></some-component>
在这种情况下,组件将始终使用 global_const 变量的值,无论其所处的环境如何。这会产生对全局状态的严格依赖并使适应过程变得复杂。如果您需要更改组件的行为,则必须编辑代码或修改全局变量,这并不总是方便或安全。
因此,重要的结论是:如果环境为组件提供了使用易于替换的名称的能力,那么环境就会变得更简单、更方便。
当组件与其环境交互时,该过程的正确性主要责任在于组件本身。该组件是必须使用名称来访问必要数据的组件。然而,环境也扮演着重要的角色:它必须以一种易于组件使用的方式提供数据。
让我们考虑前面代码中的一个示例,其中组件直接访问全局变量。在这种情况下,更改环境名称变得非常困难,因为组件与特定变量紧密耦合。如果需要不同的变量,则必须重写组件代码。这不仅不方便,而且降低了组件的灵活性和可重用性。
现在,让我们稍微改进一下方法:
<ul> <div> <li></li> <li></li> </div> </ul>
在此版本中,组件通过 const_name 属性获取变量名称。这提供了更大的灵活性:要使用不同的变量,通过属性传递新名称就足够了。当然,使用eval方法并不是一个理想的解决方案。它带来潜在的安全风险并可能降低性能。然而,即使这种方法也展示了如何通过为组件提供更方便的数据访问方式来简化环境变化。
这引出了另一个重要规则:如果环境为组件提供了一种方便且易于理解的数据访问方式,那么环境就会变得更简单。
在本文中,我试图涵盖有助于评估初始化 Web 组件的环境简单性的关键标准。这些标准不仅有助于了解使用组件有多么容易,而且还允许您找到改进组件与其环境之间交互的方法。然而,我确信我没有涵盖所有可能的方面。如果您有任何想法、想法或示例,我很乐意考虑它们并将其包含在文章中。
在下一篇文章中,我计划深入探讨该主题并讨论组件之间数据传输的具体方法。我们将使用此处概述的简单性、方便性和灵活性的标准来分析它们。这将帮助我们选择适合各种任务和场景的最有效、最通用的方法。
根据我在工作中确定的最佳实践,我创建了 KoiCom 库。
KoiCom 文档
KoiCom github
它已经采用了最成功的方法来处理组件与其环境之间的交互。我真诚地希望这个库对您有用并帮助简化 Web 组件的开发。如果您对其使用有任何疑问或反馈,我很高兴收到您的来信。
以上是使用外部数据初始化 Web 组件的详细内容。更多信息请关注PHP中文网其他相关文章!