# 组件 ## 定义 - 组件是视图层的基本组成单元。 - 组件是一个单独且可复用的功能模块的封装。 每个组件,包括如下几个部分:以组件名称为标记的开始标签和结束标签、组件内容、组件属性、组件属性值。 - 组件名称由尖括号包裹,称为标签,它有开始标签和结束标签。结束标签的`<`后面用`/`来表示结束。结束标签也称为闭合标签。如下面示例的``是开始标签,``是结束标签。 - 在开始标签和结束标签之间,称为组件内容。如下面示例的`content` - 开始标签上可以写属性,属性可以有多个,多个属性之间用空格分割 - 每个属性通过`=`赋值 ## 使用入门教程 uni-app x 支持的组件包括: - 内置基础组件 - 自定义 vue 组件 - uts 组件插件 > 除了微信小程序,其他平台不支持的小程序wxml组件。 内置组件比较简单,扩展组件的2种方式详细介绍下 ### 自定义组件 @custom-component 在 components 目录新建一个 uvue/vue 文件,按 vue 组件规范编写代码。 组件界面通过 uvue 构造,script 使用 [uts](../uts/README.md) 编写。 返回的类型是组件实例 ComponentPublicInstance ### uts 组件插件 @uts-component > uts组件插件,指把原生的、需要在界面上显示的、内嵌于页面中整体排版的组件,编写uts代码调用原生sdk,通过uni_modules插件的方式集成到uni-app项目中。 `uts 组件插件`的名称可能有点拗口,这是因为是相对于另一个分类`uts api 插件`。\ 它们同属于`uts 插件`,是 [uni_modules](https://uniapp.dcloud.net.cn/plugin/uni_modules.html)。api 插件指能力扩展,比如蓝牙 api。而组件插件指界面元素扩展,比如 video、map、lottie 动画等。 在 app 端,它的内部界面是由原生 SDK 绘制的,而不是 uvue 代码绘制的。通过封装嵌入到 uvue/nvue 页面中。比如 > * lottie组件,使用uts调用原生的lottie sdk来开发组件,再引入页面中。[详见](https://ext.dcloud.net.cn/plugin?name=uni-animation-view) > * video组件,其实官方的video,也是用uts组件插件实现的。[详见](https://gitcode.net/dcloud/uni-component/-/tree/master/uni_modules/uni-video) > > uts组件插件,主要用于原生sdk涉及界面时,将其封装为界面组件。当然uts组件也是全端支持的。上述lottie组件也支持web端。 一个 uts 插件都是可以同时兼容 uni-app x 和 uni-app js 引擎版的。目前js引擎版仅支持内嵌于nvue页面中。所以上述lottie组件也是可以在app-nvue页面中使用的。 uts 组件的返回类型是dom元素[Element](../dom/element.md) uts 组件插件的开发教程,[详见](https://uniapp.dcloud.net.cn/plugin/uts-component.html) ## 在页面使用组件 ### 内置组件 @builtin-component 内置组件可以直接在页面中使用,不需要引入。如:[view](../component/view.md),组件文档中都有相应示例供查看使用 ### easycom 传统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 ``` #### uni_modules 组件规范 uni_module其实不止服务于组件,它可以服务于组件、js库、页面、项目等所有DCloud插件市场所支持的种类。 符合uni_module规范的组件都在项目的`uni_modules`目录下,以插件id为目录存放。(项目模板不放在`uni_modules`目录下) 在HBuilderX中点右键可方便的更新插件,插件作者也可以方便的上传插件。 uni_module还支持云端一体的插件。 uni_module有详细的专项文档,请另行查阅[uni_module规范](/plugin/uni_modules.md)。 ### 手动 import 组件 在新建一个组件后,如果不符合 easycom 规范,则需要手动引入: ```vue ``` ## 通信 ### 页面与页面通信 @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 #### 在 `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 ::: #### 向组件传递 `props` @transfer-component-props 示例 [详情]() ::: preview > 选项式 API > 组合式 API ::: #### 向组件传递回调函数 @transfer-component-method 示例 [详情]() ::: preview > 选项式 API > 组合式 API ::: #### 使用 `provide/inject` 来向下传递参数 @provide-inject 示例 [详情]() ::: preview > 选项式 API(1) > 选项式 API(2) > 组合式 API ::: #### 使用 [全局变量与状态管理](../tutorial/store.md) @global-store 示例 [详情]() ::: preview > 选项式 API > 组合式 API ::: ### 父组件与子组件通信 @parent-child-communication 上述 [页面与组件通信](#page-component-communication) 方法同样适用于父组件与子组件通信。 ### 页面调用组件方法 @page-call-component-method #### 使用 `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` 导出的方法 #### 调用 `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 ::: #### 内置组件的方法调用或设置属性 @call-builtin-component-method 使用 `this.$refs` 获取组件并as转换为组件对应的element类型,通过 `.`操作符 调用组件方法或设置属性。 **语法** ```(this.$refs['组件ref属性值'] as Uni[xxx]Element).foo();``` **内置组件的element类型规范** Uni`组件名(驼峰)`Element 如: `