Vue.js slots: 为何你须要它们?

也许你已经看过了Vue.js slots的文档。我对这个功能从“为何你可能须要它”到“没有它我怎么可能工做”的态度转变很是快。
虽然文档已经解释了它的概念,可是这里有一个关于slots怎么改进应用程序代码库的真实例子。
在我看来,slots是vue最有用和最有趣的特性之一。虽然这是web组件所推荐的标准,可是我不知道有其余框架已经实现了这一特性。解释slots的做用很简单,可是很难解释它为何有用(若是不使用“可组合性”这个术语),因此我要给你一个使用例子。css

假设你的app有不少表单,表单包含几个部分:html

  • 表单头部:包含关于表单的信息
  • 表单元素:供用户输入
  • 按钮

如今你想要把表单抽象为一个独立组件。你那些使用react和angular的同事告诉你,你须要使用相似React的组合vs继承或者Angular1的Transclude这样的特性,因而你找到了slots的文档。vue

你建立了这样一个组件:react

<!-- FormHelper.vue -->
<form class="form">
  <h3>{{ title }}</h3>
  <slot></slot><!-- children will go here -->
  <button>Submit</button>
</form>

使用方法以下:angularjs

<!-- App.vue -->
<form-helper title="Password Reset">
  <input type="text" name="name" value="">
  <input type="text" name="email" value="">
</form-helper>

这样就能够正常运行了。但是,产品告诉你,一个特定的表单须要一个文本块来得到帮助信息的标题,按钮名要改成“Request”。这超出了“children”能作的范围。web

<!-- FormHelper.vue -->
<form class="form">
  <h3>{{ title }}</h3>
  <div :v-if="hasHelp">{{ helpMessage }}</div>
  <slot></slot><!-- children will go here -->
  <button>{{ customButtonName }}</button>
</form>

上述代码可能会出现一些问题,若是须要更多按钮、更多交互等等这些状况,怎么办?幸亏,vuejs提供了一个更简洁的解决方案:具名slots。因而,你把代码改为下面这样:bootstrap

<!-- FormHelper.vue -->
<form class="form">
  <h3>{{ title }}</h3>
  <slot name="help"></slot>
  <slot name="elements"></slot><!-- children will go here -->
  <slot name="buttons"></slot>
</form>

使用方法:api

<!-- App.vue -->
<form-helper title="Request Form">
  <div slot="help">
    Please ask your manager before requesting hardware.
  </div>
  <div slot="elements">
    <input type="text" name="item_name" value="">
    <input type="text" name="item_value" value="">
  </div>
  <div slot="buttons">
    <button type="button" name="button">Request</button>
  </div>
</form-helper>

在我看来,关键思想是:app

将slots看成传递给子组件的属性。就像传递字符串、整数和对象,而slots是传递一个子dom树,让子组件能够在任何须要的地方使用。框架

使用slots的其余场景:

使用slots的更多优势:

  • 子组件用于样式和展现,业务逻辑都保留在父元素中。
  • 若是没有传递内容给slots,就不会展现东西。这让你能够很好地复用它们,而且只在你想要的slots中传递。
相关文章
相关标签/搜索