2024-08-27 10:08:47 +08:00

200 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 自定义组件
## 介绍和组件模板
关于自定义组件https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/
在使用自定义组件的时候,首先需要注意版本问题,基础库要大于等于 1.6.3
在使用自定义组件的时候,一般单独拿一个目录来存放自定义组件,一般是 components
页面中在使用自定义组件时,需要在在 json 文件中进行一个配置,例如:
```js
{
"usingComponents": {
"item" : "/components/item/item"
}
}
```
不同于页面对应的 JS 文件中的 Page 构造器,在自定义组件中,对应的 JS 文件的构造器为 Component
- properties在使用自定义组件时父组件传入的属性
- data表示该自定义组件自身的数据
- methods书写对应的事件处理函数
- options: 关于自定义组件的选项配置,例如我们要使用多插槽的时候,就需要配置 multipleSlots 为 true
- externalClasses用于指定外部传入的样式类
从开发者工具 1.02.1810190 及以上版本开始,可以在 app.json 中使用 usingComponents 来注册组件,在 app.json 中所注册的组件被视为全局组件,各个页面,以及其他自定义组件中都可以使用。
在设计自定义组件的时候,是可以添加插槽,插槽的用法和 Vue 是非常类似的。
并且和 Vue 中的插槽一样,可以设置具名插槽
定义插槽:
```wxml
<view class="container">
<view bindtap="tapHandle">{{name}}</view>
<slot name="before"></slot>
<view>{{content}}</view>
<slot></slot>
<view>计数器:{{count}}</view>
<slot name="after"></slot>
</view>
```
使用自定义组件时,就可以往插槽插入动态的内容
```wxml
<view class="container">
<view bindtap="tapHandle">index</view>
<item content="传入的内容" count="{{count}}" class="my-class"></item>
<item count="{{count}}">
<view slot="before">这部分内容会被放入到before</view>
<view slot="after">这部分内容会被放入到after</view>
<view>这部分内容会被放入到默认插槽</view>
</item>
</view>
```
## Component 构造器
- App整个小程序的构造器
- Page页面对应的构造器
- Component自定义组件构造器
- properties在使用自定义组件时父组件传入的属性
- data表示该自定义组件自身的数据
- methods书写对应的事件处理函数
- options: 关于自定义组件的选项配置,例如我们要使用多插槽的时候,就需要配置 multipleSlots 为 true
- externalClasses用于指定外部传入的样式类
- lifetimes生命周期钩子函数早期的时候生命周期钩子函数和 Page、App 一样,直接写在配置对象里面,但是后面随着版本的更新,现在推荐写在 lifetimes 配置对象里面,并且写在 lifetimes 里面的优先级是最高的。
- pageLifetimes组件所在页面的生命周期
**实际上,页面也可以被当作是一个自定义组件来使用。**
组件之间涉及到数据的传递,和 Vue 是相似的,父传子通过 properties子传父通过触发父组件的自定义事件来传递注意在触发父组件的自定义事件时使用的是 this.triggerEvent 来进行触发的。
可以通过 this.selectComponent('自定义组件的样式类') 来获取自定义组件实例对象
## 生命周期
在自定义组件中,提供了
- created组件实例刚刚被创建好时**此时还不能调用 `setData` 。**通常情况下,这个生命周期只应该用于给组件 `this` 添加一些自定义属性字段。有点类似于 Vue 里面的 created
- attached在组件完全初始化完毕、进入页面节点树后 `attached` 生命周期被触发,这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。有点类似于 Vue 里面的 mounted
- detached在组件离开页面节点树后触发类似于 Vue 里面的 destory
## behaviors
这个就类似于 Vue 里面的 mixin用来提取组件公共的部分data、method、生命周期钩子
当我们要定义一个 behavior 的时候,需要用到 Behavior 构造器
```js
Behavior({
// ...
})
```
## 组件间关系
在使用自定义组件的时候,可以使用 relations 字段来指定自定义组件之间的关系,指定了关系之后,就可以获取到对应组件的实例。
在使用 relations 的时候,必须两个关联的组件都要加入此字段。
组件间使用 relations 设定了相互关系后,最大的好处在于能够和关联的组件进行通信,如何通信的?
主要就是拿到关联组件的实例对象实例对象一拿到data 这些数据也就拿到了.
## 数据监听器
数据监听器可以用于监听和响应任何属性和数据字段的变化。从小程序基础库版本 [2.6.1](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) 开始支持。
这个实际上就和 Vue 里面的 watch 是类似的。
## 纯数据字段
在 data 里面所定义的数据,一般来讲在页面是会重新渲染的。如果有一些数据,既不会展示在界面上,也不会传递给其他组件,仅仅是拿来做数据计算的,那么这个时候如果定义在 data 中,就会参与页面重新渲染。但是我们不需要这些字段(纯数据字段)发生改变时页面重新渲染,因此在微信小程序中,提供了一种机制。
1. 首先,在 Component 中的 options 中书写一个正则
2. 在 data 中所定义的数据如果能够匹配上该正则,该数据字段就是一个纯数据字段
3. 纯数据字段值发生变化时,不会引起页面的重新渲染
## 抽象节点
这个就类似于 react 的 renderProps抽象节点的核心就是在使用自定义组件时可以将另一个组件以 props 的形式传递到该自定义组件中。因此传递的是什么组件,最终渲染的就是什么组件。
首先第一步,我们在使用自定义组件的时候,可以将另外的自定义组件像 props 一样传入
```js
<item4 generic:selectable="sel1"/>
<item4 generic:selectable="sel2"/>
```
在上面的代码中,我们使用了 item4 这个自定义组件,然后我们还分别将 sel1 和 sel2 作为 props 传入到了 item4 里面。
注意这里需要在对应的 json 文件中注册 sel1、sel2、item4 这几个组件。
接下来在 item4 这个自定义组件中,书写 selectable 来渲染传入的自定义组件
```js
<view class="container">
<view>item4</view>
<view>该示例演示了抽象节点</view>
<selectable/>
</view>
```
另外在接受渲染组件的自定义组件中item4的 json 文件中,需要开启 selectable
```js
"componentGenerics": {
"selectable": true
}
```
这玩意儿和插槽非常类似?
这个抽象节点和 react 的 renderProps 非常相似,主要作用是用来横向抽离公共的逻辑,因为我们是传入的一个组件,组件里面是一套完整的功能。回头我们可以将一些公共的业务逻辑(视图、数据、行为)单独的以组件的形式抽离出来。