企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
>[success] # 组件开发 1. 从`v1.6.3`开始, 小程序开始支持自定义组件开发, 也让我们更加方便的在程序中使用组件化 >[info] ## 创建组件 1. 自定义组件由 **json wxml wxss js** 4个文件组成。 2. 先需要在 `json `文件中进行自定义组件声明(将`component` 字段设为 `true `可这一组文件设为自定义组件) 3. 在`wxml`中编写属于我们组件自己的模板 4. 在`wxss`中编写属于我们组件自己的相关样式 5. 在`js`文件中, 可以定义数据或组件内部的相关逻辑 6. 页面引用自定义组件需要在`对应页面.json` 文件的`usingComponents` 字段配置,`key `为组件名,`value`为地址 ~~~ { "usingComponents": { "section-info": "/components/section-info/section-info", "test-style": "/components/test-style/test-style", "tab-control": "/components/tab-control/tab-control" } } ~~~ 7. 全局在`app.json`的`usingComponents`声明某个组件,那么**所有页面和组件可以直接使用该组** 8. **自定义组件也是可以引用自定义组件的**,引用方法类似于页面引用自定义组件的方式(使用`usingComponents `字段) 9. 自定义组件和页面所在项目根目录名 不能以 **wx-** 为前缀,否则会报错 >[danger] ##### 组件案例 * 在组件的json文件声明`component `字段 为true ![](https://img.kancloud.cn/d8/c0/d8c0db3a5b414d3c3d643a37a4f93a1c_682x250.png) * 像编写页面一样编写组件 ![](https://img.kancloud.cn/d3/a7/d3a7fa076a690295994c0817d6969b4f_603x246.png) * 如果只是指定页面用在指定页面的`index.json` `usingComponents` 编写组件导入 ![](https://img.kancloud.cn/e8/da/e8da039e7d21693f599330857cb9cc7d_794x368.png) * 导入后就可以直接在对应页面使用 ![](https://img.kancloud.cn/35/bd/35bd074b4fc344ca79ac98a5ca28899e_613x313.png) >[info] ## 组件的样式 1. 组件内的class样式,只对组件wxml内的节点生效, 对于引用组件的Page页面不生效 2. 组件内不能使用**id选择器、属性选择器、标签选择器**,就正常使用class 选择器就好 >[danger] ##### 组件和页面样式影响 1. 外部使用`class`的样式,只对外部`wxml`的`class`生效,对组件内是不生效的 2. 外部使用了`id`选择器、**··** 3. 外部使用了**标签选择器,会对组件内产生影响** 4. 通过设置`Component`对象中,可以传入一个`options`属性个`styleIsolation`(隔离)属性 * `isolated `表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(默认取值) * `apply-shared` 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面; * `shared `表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置 了 ![](https://img.kancloud.cn/29/aa/29aa997540d0b5bed776ca47777131bb_711x512.png) >[info] ## 组件的通信 1. 很多情况下,组件内展示的内容(数据、样式、标签),并不是在组件内写死的,而且可以由使用者来决定 ![](https://img.kancloud.cn/1d/5e/1d5eae4b40cb8b06e9561dc4bd47a1de_954x336.png) ~~~js Component({ options: { styleIsolation: "shared" }, /** * 组件的属性列表 */ properties: { }, /** * 组件的初始数据 */ data: { }, /** * 组件的方法列表 */ methods: { } }) ~~~ >[danger] ##### 向组件传递数据 - properties 1. 通过**从外部传递数据给我们的组件**,使用`properties`属性 2. 通过type 设置类型支持类型,String、Number、Boolean、Object、Array、null(不限制类型) 3. 可以通过`value`设置默认值 ![](https://img.kancloud.cn/73/5b/735bb45a680523c8700509083cacadb0_634x474.png) ![](https://img.kancloud.cn/07/3e/073e7655d2ba2163148d288d629383ab_644x396.png) * 页面展示 ![](https://img.kancloud.cn/38/72/38722226705b6b1a0d56cc43974ef463_417x94.png) >[danger] ##### 向组件传递样式 - externalClasses 1. 有时候,我们不希望将样式在组件内固定不变,而是外部可以决定样式 2. 在`Component`对象中,定义`externalClasses`属性 ![](https://img.kancloud.cn/84/33/84333d9774229545703fd9437e6f5799_358x150.png) 3. 在组件内的`wxml`中使用`externalClasses`属性中的class ![](https://img.kancloud.cn/b3/48/b3488112c7bb31b96704a0cf9fb5f5cc_737x125.png) 4. 在页面中传入对应的`class`,并且给这个`class`设置样式 ![](https://img.kancloud.cn/47/06/47060073a9a4ca1ef2dae349406b247d_282x56.png) >[danger] ##### 组件向外传递事件 – 自定义事件 1. 在组件的 js 文件的method 属性中定义方法 2. 将方法传递触发父组件 和 vue 类似但不同是从 `emit `变成`triggerEvent` 3. 父组件绑定暴露出的方法 和 vue 类似但不同从 `on` 变成了`bind:` 4. 接受传参过来值使用`event.detail` ![](https://img.kancloud.cn/e1/97/e197db511becb60c7decd8c8d3258174_863x310.png) ![](https://img.kancloud.cn/16/8d/168d7c43e7adacbf1a10728ff5e98204_962x325.png) ![](https://img.kancloud.cn/e8/53/e853d46fac68a0791dc9ec2089a1d494_1092x498.png) ![](https://img.kancloud.cn/b0/61/b0615bbc548fa0b42b6c234a297a5bb2_922x331.png) >[info] ## 综合案例 >[danger] ##### 组件 部分 * 定义组件 ~~~ { "component": true, "usingComponents": {} } ~~~ ~~~ // componets/tab/tab.js Component({ /** * 组件的属性列表 */ properties: { titles:{ type:Array, value:[] } }, /** * 组件的初始数据 */ data: { currentIndex:0 }, /** * 组件的方法列表 */ methods: { onItemTap(event){ const {index} = event.currentTarget.dataset this.setData({currentIndex:index}) // 将值暴露出去 this.triggerEvent('changeIndex',index) } } }) ~~~ ~~~html <!--componets/tab/tab.wxml--> <view class="tab"> <block wx:for="{{titles}}" wx:key="item"> <view class="tab-item" bindtap="onItemTap" data-index="{{index}}"> <text class="tab-item-text {{ index==currentIndex? 'active':''}}">{{item}}</text> </view> </block> </view> ~~~ ~~~ .tab{ display: flex; line-height: 32px; height: 32px; } .tab-item{ flex: 1; text-align: center; } .tab-item-text{ padding: 5px; } .tab-item-text.active{ border-bottom: 2px solid yellowgreen; } ~~~ >[danger] ###### 使用 ~~~ Page({ /** * 页面的初始数据 */ data: { titles:["数学","语文","英语","物理"], }, changeIndex(event){ console.log("区域title发生了点击", event.detail); } }) ~~~ ~~~html <tabs titles="{{titles}}" bind:changeIndex="changeIndex"></tabs> ~~~ * 注册 ~~~ { "usingComponents": { "tabs":"/componets/tab/tab" } } ~~~