## :-: [微信小程序自定义组件](https://www.jianshu.com/p/6c7b597e50c5) ## 使用自定义组件 应用场景: 当我们在设计我们项目的时候会发现在不同的页面中,有时候会用到相同的功能模块,此时我们就可以将这些相同的部分提取出来并且单独设为一个"页面",然后在要应用到它的地方引用就可以了,以上就是我对自定义组件的个人理解,具体做法请阅读以下内容. #### 1.创建自定义组件 在上面我介绍了,自定义组件其实就像是一个页面,所以我们在编写它的时候也应该像设计页面一样,具备`json` `wxml` `wxss` `js`这四个文件. 在这里博主就以编写案例的形式向大家介绍自定义组件. **一. 前期准备** 1.首先,新建一个名为`wxcomponent`的项目, 2.在pages文件夹下创建一个`components`文件夹用来盛放我们所有的自定义组件. 3.在components文件夹下创建一个`cpt`的文件夹用来盛放`cpt`这个自定义组件,并分别创建好对应的配置文件,如下图: ![](//upload-images.jianshu.io/upload_images/7190596-d5fe5e702094147b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/974/format/webp) component.png **二. 自定义组件声明** 要在`cpt.json`中进行自定义组件声明,也就是告诉开发者这是一个组件: ~~~ { "component": true } ~~~ **三. 设计组件结构** 在 wxml 文件中编写组件模版,在 wxss 文件中加入组件样式: cpt.wxml文件 ~~~ <!-- 这是自定义组件的内部WXML结构 --> <view class="inner"> {{innerText}} <button bindtap='customMethod'>点击</button> <slot></slot> </view> ~~~ cpt.wxss文件 ~~~ /* 这里的样式只应用于这个自定义组件 */ .inner { color: red; } ~~~ 这里的`暂时可以不用管它. 并且自定义组件在设计结构的时候是不应该使用给便签加上id或者使用属性选择器和标签名选择器的. 这是因为组件就是被我们那里重用的,而页面中只能允许有一个id. **四: 注册组件** 在自定义组件的`js`文件中,需要使用 Component() 来注册组件,并提供组件的属性定义、内部数据和自定义方法,如在cpt.js中: ~~~ Component({ properties: { // 这里定义了innerText属性,属性值可以在组件使用时指定 innerText: { type: String, value: 'default value', } }, data: { // 这里是一些组件内部数据 someData: 1 }, methods: { // 这里是一个自定义方法 customMethod: function () { console.log('customMethod') } } }) ~~~ **五: 使用自定义组件** 这里我为了简便一点,就直接用自带的logs页面来进行自定义组件的调用吧. 首先,你应该在你要用组件的那个页面中引用声明.也就是在`.json`文件. 如在`logs.json`中: ~~~ { "navigationBarTitleText": "查看启动日志", "usingComponents": { "component-tag-name": "../components/cpt/cpt" } } ~~~ 接下来我们就可以在页面中像使用其他组件一样的使用自定义组件了. 比如我在logs.wxml中使用: ~~~ <!--logs.wxml--> <view class="container log-list"> <!-- 以下是对一个自定义组件的引用 --> <component-tag-name inner-text="Some text"></component-tag-name> </view> ~~~ 跳转到logs页面如下图的效果: ![](//upload-images.jianshu.io/upload_images/7190596-f5497dc0816737ee.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/284/format/webp) result.png **六: 使用slot** 在上面的例子中,在cpt.wxml中写入了标签,在引用cpt这个组件时我们要是不在组件的标签中写入其他的内容,是不会显示标签的 也就是说如果我们把上面logs.wxml改动一下: ~~~ <!--logs.wxml--> <view class="container log-list"> <!-- 以下是对一个自定义组件的引用 --> <component-tag-name inner-text="Some text"> <view>这里是插入到组件slot中的内容</view> </component-tag-name> </view> ~~~ 此时查看logs页面: ![](//upload-images.jianshu.io/upload_images/7190596-23727aceb1f287ef.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/285/format/webp) slot.png 并且`<slot></slot>`的位置在哪里也是由你在设计cpt组件时决定的 上面的例子中我是将`slot`放在`button`之下: ~~~ <!-- 这是自定义组件的内部WXML结构 --> <view class="inner"> {{innerText}} <button bindtap='customMethod'>点击</button> <slot></slot> </view> ~~~ 你也可以将它放在其他位置来达到不同的效果. **七: 使用多个slot** 正常情况下,一个组件中只有一个`slot`,但有时候我们的自定义组件可能不止使用一个`slot`,别怕,我们的微信小程序也是可以允许你这样的. 需要使用多slot时,可以在组件js中声明启用 1.在cpt.json(你自定义组件的json文件)中声明 ~~~ Component({ options: { multipleSlots: true // 在组件定义时的选项中启用多slot支持 }, properties: { /* ... */ }, methods: { /* ... */ } }) ~~~ 2.此时,可以在这个组件的wxml中使用多个slot,以不同的 name 来区分: ~~~ <!-- 这是自定义组件的内部WXML结构 --> <view class="inner"> <slot name="header"></slot> <-- 一定要记得使用name属性 --> {{innerText}} <button bindtap='customMethod'>点击</button> <slot name="footer"></slot> </view> ~~~ 3.使用时,用 slot 属性来将节点插入到不同的slot上。 ~~~ <!--logs.wxml--> <view class="container log-list"> <!-- 以下是对一个自定义组件的引用 --> <component-tag-name inner-text="Some text"> <view slot="header">头部的内容</view> <view slot="footer">底部的内容</view> </component-tag-name> </view> ~~~ ### 后语 微信小程序中自定义组件的用法还有很多,比如组件生命周期,事件等等,更多的内容可以参考[官方文档](https://link.jianshu.com?t=https://mp.weixin.qq.com/debug/wxadoc/dev/framework/custom-component/). 作者:LinDaiDai\_霖 链接:https://www.jianshu.com/p/6c7b597e50c5 来源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。