# 组件 我们可以对一段要复用的js/uts逻辑代码进行封装,抽出function、module等形式。 那么涉及UI的复用时,该如何抽象? 这就是vue的组件机制,把视图template、script、style都封装到独立的uvue组件文件中,在其他需要的地方使用组件的名称进行引用。 每个组件,包括如下几个部分:以组件名称为标记的开始标签和结束标签、组件内容、组件属性、组件属性值。 - 组件名称由尖括号包裹,称为标签,它有开始标签和结束标签。结束标签的`<`后面用`/`来表示结束。结束标签也称为闭合标签。如下面示例的``是开始标签,``是结束标签。 - 在开始标签和结束标签之间,称为组件内容。如下面示例的`content` - 开始标签上可以写属性,属性可以有多个,多个属性之间用空格分割 - 每个属性通过`=`赋值 组件还可以封装方法、事件、插槽,提供了组件的生命周期,提供了组件和页面的互通信机制,满足了各种高级需求。 ## 创建及引用组件 @create-and-import-component ### easycom 传统vue组件,需要安装、引用、注册,三个步骤后才能使用组件。`easycom` 将其精简为一步。 只要组件安装在项目的 `components` 目录下或 `uni_modules/插件 id/components/插件 id/插件 id.uvue` 目录下,并符合 `组件名称/组件名称.(vue|uvue)` 目录结构。就可以不用引用、注册,直接在页面中使用。 - 比如 [uni-loading](https://ext.dcloud.net.cn/plugin?id=15980),它导入到项目后,存放在了目录 /uni_modules/uni-loading/components/uni-loading/uni-loading.uvue 同时它的组件名称也叫 uni-loading,所以这样的组件,不用在 script 里注册和引用。如下: ```html ``` 这里出现了`uni_module`的概念,简单说下,它是uni-app的一种包管理方案。 `uni_module`其实不止服务于组件,它可以容纳组件、script库、页面、项目等所有DCloud插件市场所支持的种类。 在HBuilderX中点右键可方便的更新插件,插件作者也可以方便的上传插件。 uni_module有详细的专项文档,请另行查阅[uni_module规范](https://uniapp.dcloud.net.cn/plugin/uni_modules.html)。 如果你的组件不满足easycom标准的目录规范,还有一种办法是在[pages.json](../collocation/pagesjson.md#pages-easycom)里声明自己的目录规则,以便编译器查找到你的组件。自定义easycom路径规则的详细教程[详见](https://uniapp.dcloud.net.cn/collocation/pages.html#easycom) #### easycom组件的类型规范 @easycom-component-type 组件标签名首字母大写,`驼峰+ComponentPublicInstance`,如: `` 类型为:TestComponentPublicInstance `` 类型为:UniDataCheckboxComponentPublicInstance ### 手动引入组件 @manual-import-component 不符合 easycom 规范的组件,则需要手动引入: ```vue ``` #### 手动引入组件的类型规范 @manual-import-component-type 类型为:ComponentPublicInstance ## 使用及通信 @use-and-communication ### 页面与页面通信 @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 > 在调用组件方法的时候如报错 `error: Reference has a nullable type` 则需要使用 `?.` 操作符(如:a?.b?.())。 easycom组件,用法和内置组件一样。也是使用 `this.$refs` 获取组件并转换为组件的类型,通过 `.`操作符 调用组件方法或设置属性。 **语法** ```(this.$refs['组件ref属性值'] as 驼峰ComponentPublicInstance)?.foo?.();``` 示例 [详情]() ::: preview > 选项式 API > 组合式 API ::: ##### 调用 `uni_modules easycom` 组件方法 @call-uni-modules-easycom-component-method 使用 `ref` 属性拿到组件实例,调用 `easycom` 组件方法时不需要使用 `$callMethod` 方法,直接使用点操作符即可 `.` > 在调用组件方法的时候如报错 `error: Reference has a nullable type` 则需要使用 `?.` 操作符(如:a?.b?.())。 示例 [详情]() ::: 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 如: `