小程序自定义组件 slot

和 vue 的 slot 几乎是一模一样的. 这个学小程序就相当于复习了一把 vue, 还是很值的.

我们之前说组件是页面的一部分, 目的是为了代码复用, 作为组件封装者, 有时候需要设计一些让用户能自定义输入的内容, 即通过预留一些 "占位符" 空间给到用户, 那实现这种占位的设计就叫做 slot.

作为组件的使用这, 在使用组件时通过按需 "填充 slot" 则完成了自身的业务逻辑.

单个 slot

在小程序中, 默认每个自定义组件中只允许使用一个 slot 进行占位. 这种就成为单个插槽.

<!-- 1.组件的封装者, 假设组件名叫 cj -->

<view>
  <view>我是组件的内部节点</view>
  <!-- 对于未知内容可用 slot 进行占位, 内容由用户决定 -->
  <slot></slot>
</view>

<!-- 2.组件的使用者, 给组件传一个 "hello, youge" 的内容 -->

<cj>
  <!-- 这个 view 的区域会替换掉组件的 slot 区域 -->
  <view>hello, world</view>
</cj>

这一看就秒懂. 俺之前学 vue 的时候对这个 slot 还不太懂, 现在突然觉得好简单, 感谢小程序让我复习. 具体演示一下, 还是以之前的 cj 组件为例.

组件 cj 的 .wxml 部分:

<!--components/cj/cj.wxml-->

<view>
  <view>这是组件的内部结构,</view>
  <slot></slot>
</view>

在 index 页面中使用组件, 并给组件 slot 传递内容:

<!--/pages/index/index.wxml-->
<view>
  <text>下面显示的都是 cj 组件内容: </text>
  <cj>
    <view>我是外面传递给组件用以占位 slot 的.</view>
  </cj>
</view>

则最终在 index 的渲染为:

下面显示的都是 cj 组件内容:
这是组件的内部结构,
我是外面传递给组件用以占位 slot 的.

多个 slot

但当组件比较复杂, 且需要使用多个 slot 的时候, 也是可以在组件的 js 中进行配置的, 即在组件定义时的 options 配置中设置 multipleSlots: true 即可.

Component({
    options: {
        multipleSlots: true
    }
})

在使用的时候, 通过在 slot 标签中通过设置 name 属性值来区分, 即相当于 vue 中的具名插槽啦.

<view>
  <slot name="before"></slot>
  <text>俺是中间部分一段固定文本啦</text>
  <slot name="after"></slot>
</view>

在使用的时候通过添加一个属性 slot="插槽名" 这样就对号入座了. 这里也整个例子演示一下啦.

组件 cj 的 wxml 部分:

<!--components/cj/cj.wxml-->

<view class="cj">
  <slot name="before"></slot>
  <view>俺是中间躺着不动的部分</view>
  <slot name="after"></slot>
</view>

组件 js 中开启了多个 slot 设置:

Component({
    options: {
        multipleSlots: true
    }
})

然后在 index 页面中使用 cj 组件, 分别给名为 before 和 after 这两个槽传递内容.

<!--/pages/index/index.wxml-->
<view>
  <text>下面显示的都是 cj 组件内容: </text>
  <cj>
    <view slot="before">我是外面传递给 cj 组件中 before 槽的</view>
    <view slot="after">我是外面传递给 cj 组件中 after 槽的</view>
  </cj>
</view>

最终页面渲染如下:

下面显示的都是 cj 组件内容: 
我是外面传递给 cj 组件中 before 槽的
俺是组件中间躺着不动的部分
我是外面传递给 cj 组件中 after 槽的

我一脸问号, 这不就是和 vue 一模一样嘛, vue 中这就叫做具名插槽, 直接用 v-slot="xxx". 但小程序这里和 vue 不同是, 它要在组件 js 中的 options 配置 multipleSlots=true. 但我感觉小程序还满简单的,相对于 vue 中的各种通信又传值的 slot 各种骚操作来说.

耐心和恒心, 总会获得回报的.