# 组件
## 定义
- 组件是视图层的基本组成单元。
- 组件是一个单独且可复用的功能模块的封装。
每个组件,包括如下几个部分:以组件名称为标记的开始标签和结束标签、组件内容、组件属性、组件属性值。
- 组件名称由尖括号包裹,称为标签,它有开始标签和结束标签。结束标签的`<`后面用`/`来表示结束。结束标签也称为闭合标签。如下面示例的``是开始标签,``是结束标签。
- 在开始标签和结束标签之间,称为组件内容。如下面示例的`content`
- 开始标签上可以写属性,属性可以有多个,多个属性之间用空格分割
- 每个属性通过`=`赋值
easycom
手动引入
### easycom
#### components 目录下创建组件 @components-directory
在 components 目录新建一个 uvue 文件,按 vue 组件规范编写代码。
组件界面通过 uvue 构造,script 使用 [uts](../uts/README.md) 编写。
返回的类型是组件实例 ComponentPublicInstance
#### uni_modules 组件 @uni-module-components
> uni_module其实不止服务于组件,它可以服务于组件、js库、页面、项目等所有DCloud插件市场所支持的种类。
符合uni_module规范的组件都在项目的`uni_modules`目录下,以插件id为目录存放。(项目模板不放在`uni_modules`目录下)
在HBuilderX中点右键可方便的更新插件,插件作者也可以方便的上传插件。
uni_module有详细的专项文档,请另行查阅[uni_module规范](/plugin/uni_modules.md)。
#### 使用 easycom 组件 @easycom-component
传统vue组件,需要安装、引用、注册,三个步骤后才能使用组件。`easycom` 将其精简为一步。
只要组件安装在项目的 `components` 目录下或 `uni_modules/插件 id/components` 目录下,并符合 `组件名称/组件名称.(vue|uvue)` 目录结构。就可以不用引用、注册,直接在页面中使用。
- 比如 [uni-rate组件](https://ext.dcloud.net.cn/plugin?id=33),它导入到项目后,存放在了目录 /uni_modules/uni-rate/uni-rate.vue
同时它的组件名称也叫 uni-rate,所以这样的组件,不用在 script 里注册和引用。
如下:
```html
```
### 手动 import 组件
在新建一个组件后,如果不符合 easycom 规范,则需要手动引入:
```vue
Child Component
```
## 通信
### 页面与页面通信 @page-page-communication
1. 使用 [navigateTo](https://doc.dcloud.net.cn/uni-app-x/api/navigator.html#navigateto) 在 `url` 地址中携带参数
2. 使用 [event-bus](https://doc.dcloud.net.cn/uni-app-x/api/event-bus.html)
### 页面与组件通信 @page-component-communication
#### 向组件传递 `props` @transfer-component-props
示例 [详情]()
::: warning 注意
- 选项式 API:`this.$props` 是 `Map` 类型,需要使用 `this.$props["propName"]` 来访问
- 组合式 API:可以使用 `.` 点操作符来访问
:::
::: preview
> 选项式 API
> 组合式 API
:::
#### 向组件传递回调函数 @transfer-component-method
示例 [详情]()
::: preview
> 选项式 API
> 组合式 API
:::
#### 使用 `provide/inject` 来向下传递参数 @provide-inject
示例 [详情]()
::: preview
> 选项式 API
> 组合式 API
:::
#### 使用 [全局变量与状态管理](../tutorial/store.md) @global-store
> store/index.uts [文件详情](https://gitcode.net/dcloud/hello-uvue/-/blob/alpha/store/index.uts)
示例 [详情]()
::: preview
> 选项式 API
> 组合式 API
:::
#### 在 `main.uts` 中使用 `app.config.globalProperties`
如在 `main.uts` 中的 `createApp` 方法中使用:
```ts
app.config.globalProperties.globalPropertiesReactiveObj = reactive({
str: 'default reactive string',
num: 0,
bool: false,
} as UTSJSONObject)
```
示例 [详情]()
::: preview
> 选项式 API
> 组合式 API
:::
### 父组件与子组件通信 @parent-child-communication
上述 [页面与组件通信](#page-component-communication) 方法同样适用于父组件与子组件通信。
### 页面调用组件方法 @page-call-component-method
#### 调用 `easycom` 组件方法 @call-easycom-component-method
> 3.97+ 支持 uni_modules 目录下的组件
>
> 在调用组件方法的时候如报错 `error: Reference has a nullable type` 则需要使用 `?.` 操作符,如:a?.b?.()。
easycom组件,用法和内置组件一样。也是使用 `this.$refs` 获取组件并转换为组件的类型,通过 `.`操作符 调用组件方法或设置属性。
**语法**
```(this.$refs['组件ref属性值'] as 驼峰ComponentPublicInstance).foo();```
**easycom组件的类型规范**
组件标签名首字母大写,驼峰+ComponentPublicInstance,如:
`` 类型为:TestComponentPublicInstance
`` 类型为:UniDataCheckboxComponentPublicInstance
示例 [详情]()
::: preview
> 选项式 API
> 组合式 API
:::
##### 调用 `uni_modules easycom` 组件方法 @call-uni-modules-easycom-component-method
使用 `ref` 属性拿到组件实例,调用 `easycom` 组件方法时不需要使用 `$callMethod` 方法,直接使用点操作符即可 `.`
> 在调用组件方法的时候如报错 `error: Reference has a nullable type` 则需要使用 `?.` 操作符,如:a?.b?.()。
> 与 ts 不同,在 `()` 前也需要使用 `?.` 操作符。
示例 [详情]()
::: preview
> 选项式 API
> 组合式 API
:::
#### 使用 `ref` 属性搭配 `$callMethod` 方法 @call-component-method
如果不是内置组件,也不是easycom组件,那么无法使用`.`操作符了。
此时需使用 `this.$refs` 获取组件实例,然后通过 `$callMethod` 调用组件的方法。也就是把组件的方法名、参数,当做callMethod的参数来传递。此时也就没有`.`操作符那样的代码提示和校验了。
callMethod可用于所有自定义组件,包括easycom组件也可以使用,只不过easycom组件有更简单的用法。
**语法**
```(this.$refs['组件ref属性值'] as ComponentPublicInstance).$callMethod('方法名', ...args)```
**组件类型**
ComponentPublicInstance
示例 [详情]()
::: preview
> 选项式 API
> 组合式 API
:::
**注意:**
- App-Android 平台 `4.0` 版本开始支持 `$callMethod` 调用 `defineExpose` 导出的方法
- Web 平台、App-iOS 平台 `4.13` 版本开始支持 `$callMethod` 调用 `defineExpose` 导出的方法
#### 内置组件的方法调用或设置属性 @call-builtin-component-method
使用 `this.$refs` 获取组件并as转换为组件对应的element类型,通过 `.`操作符 调用组件方法或设置属性。
**语法**
```(this.$refs['组件ref属性值'] as Uni[xxx]Element).foo();```
**内置组件的element类型规范**
Uni`组件名(驼峰)`Element
如:
`