Components

未匹配的标注

Edge 组件系统深受 Vue 与 Svelte 等前端框架的启发。它借鉴了 reusabilityisolated statepropsslots 的概念。

请注意,Edge 是一个后端模板引擎,我们不能用 Edge 复制一些前端生态系统原则。它包括。

  • 反应性: 在后端没有反应性的概念。你可以生成 HTML 并通过网络发送它。
  • 限定作用域的CSS: Edge 不是使用 Webpack 这样的前端构建工具来编译的, 因此,它不会为编译和从组件中提取 css 而烦恼。为此,你必须使用现有的前端工具。

创建组件

组件使用常规 Edge 模板文件表示。例如,你可以使用以下标记创建一个名为 button.edge 的文件。

<button type="{{ type }}">
  {{ text }}
</button>

然后将其用作其他模板中的组件。

@!component('button', {
  text: 'Login',
  type: 'submit'
})

@component 标签总共接受两个参数。一是组件路径(相对于 views 目录),二是组件状态(props)。

注:组件不能访问父模板的状态。但是,它们可以访问模板 [globals]() 和 [locals]()。

Props

props 作为键值对对象的第二个参数传递给组件。通过使用对象属性名,可以在组件文件中直接访问 prop。例如:

@!component('button', {
  text: 'Login',
  type: 'submit'
})

然后 button 组件可以访问 texttype 属性,如下所示。

<button type="{{ type }}">{{ text }}</button>

$props

访问 props 的另一种方法是使用 $props 属性。它是 Props 类 的一个实例,并带有一些额外的功能,以使组件编写更容易。

在以下示例中,serializeExcept 方法会将所有道具转换为 HTML 属性,但 text Prop 除外。

<button {{ $props.serializeExcept(['text']) }}>{{ text }}</button>
@!component('button', {
  text: 'Login',
  type: 'submit',
  class: 'py-2 px-8 text-white bg-gray-800',
})

serializeExcept 方法类似,你可以使用 serializeOnly 方法仅序列化选定的道具或使用 serialize 方法将所有 Prop 转换为 HTML 属性。

插槽

除了 props,组件还可以接受 slots。slots 是父组件可以为其定义标记的命名插槽。

例如,让我们接受 button 组件的文本作为插槽而不是 prop。

<button type="{{ type }}">
  {{{ await $slots.main() }}}
</button>

组件调用者可以如下定义主槽的标记。

@component('button', {
  type: 'submit'
})
  <i class="fa-icon-lock" />
  <span> Login </span>
@end

主插槽

@component 开始和结束标记之间的内容是主插槽的一部分,除非你将其移动到命名插槽中。

@slot('trigger') 之外的所有内容都是以下示例中主插槽的一部分。

@component('modal')
  @slot('trigger')
    <a href=""> Show modal </a>
  @end

  <h1> Modal title </h1>
  <p> Modal content </p>
@end

命名插槽

命名槽允许组件接受多个出口的标记。例如,模态组件可以接受模态标题、正文和操作的标记。

// components/modal.edge 文件
<div>
  <header>
    {{{ await $slots.header() }}}
  </header>

  <main>
    {{{ await $slots.main() }}}
  </main>

  <footer>
    {{{ await $slots.actions() }}}
  </footer>
</div>

父模板可以按如下方式定义它们。

@component('components/modal')
  @slot('header')
    <h1> Delete post </h1>
  @end

  @slot('main')
    <div>
      <p>Are you sure, you want to delete the post</p>
    </div>
  @end

  @slot('actions')
    <div class="flex">
      <button>Yes, delete it</button>
      <button>Cancel</button>
    </div>
  @end
@end

输出

插槽作用域

插槽可以访问定义它们的模板(也称父模板)的状态。

以下是按钮组件的标记

// components/button.edge 文件
@set('title', 'I am a button')

<button>
  {{{ await $slots.main() }}}
</button>

父模板正在尝试访问在 component 中定义的 title 属性。

// home.edge 文件
@component('components/button')
  <span>{{ title }}</span>
@end
<!-- 输出 -->
<button>
  <span>undefined</span>
</button>

你可以将组件中的数据作为参数传递给 slot 方法。

// components/button.edge 文件
@set('title', 'I am a button')

<button>
  {{{ await $slots.main({ title }) }}}
</button>
// home.edge 文件
@component('components/button')
  @slot('main', scope)
    <span>{{ scope.title }}</span>
  @end
@end

总结:

  • 父模板可以使用 prop 或插槽将数据传递给组件。
  • 组件只能将数据作为参数传递给插槽。

向组件树注入数据

Edge 的数据注入 API 的灵感来自于 Svelte 上下文 APIVue provide/inject API

目的是简化树内组件之间的通信,但是请注意,这是一个高级 API,只能在你自行创作一组组件并希望它们之间进行透明通信时使用。

基本示例

让我们从最基本的示例开始,看看实际的注入 API。你可以使用 @inject 标签与组件树共享对象。

// 主题: 组件文件
{{-- Declare a local variable --}}
@set('counter', { value: 0 })

{{-- Inject it to the components tree --}}
@inject({ counter })

{{{ await $slots.main() }}}

由于 @inject 标记通过引用共享对象,因此组件树的任何部分都可以改变其属性,如下所示。

注入的值在 $context 变量中可用。

@component('components/parent')
  <p> Value of counter is {{ $context.counter.value }} </p>

  {{-- Bump the value by one --}}
  @set($context, 'counter.value', $context.counter.value + 1)

  <p> Updated value is {{ $context.counter.value }} </p>
@end

作为标签的组件

Edge 允许你将存储在 ./resources/views/components 目录中的组件作为 Edge 标签引用。

resources/views/components/button.edge 文件中创建以下模板。

// 文件名: resources/views/components/button.edge
<button type="{{ type }}">
  {{ text }}
</button>

现在,除了使用 @component 标记来引用按钮组件,你也可以将其引用为 @button 标签。

@!button({
  type: 'primary',
  text: 'Login'
})

你可以使用点符号引用嵌套目录中的组件。例如, ./components/form/input.edge 中存储的文件引用如下:

@!form.input({
  type: 'text',
  placeholder: 'Enter username'
})

以下是一个对照表,用于了解应用于组件路径以计算标签名称的转换。

模板路径 标签名
form/input.edge @form.input
tool_tip.edge @toolTip
checkout_form/input.edge @checkoutForm.input

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/adonisjs/5.x/vi...

译文地址:https://learnku.com/docs/adonisjs/5.x/vi...

上一篇 下一篇
贡献者:2
讨论数量: 0
发起讨论 查看所有版本


暂无话题~