本来计划去年年末开始更新博客,因为前段时间工作上有些变动,所以又往后拖延了(其实大部分还是懒)。作为一个新人Android开发,养成一个总结的习惯还是蛮好的。言归正传,前段时间公司要求开发一个小程序,我作为新人当一个劳动力顶了上去。半年前跟着公司团队做了个Vue项目,这算是第一次接触前端知识,这次是第二次接触前端,学习起来比一起顺利很多。其中微信小程序的组件化是遇到的第一个坎,下面就来聊一聊。
在小程序的列表展示,如果请求参数为空,那么显示空白的页面不太友好。
因为有多处列表页面有这个需求,但如果每个页面一个个加的话代码冗余性略大,不符合之前所学到的要代码保持简洁的规范。秉持着在写代码上要“偷懒”的思想,我想到了将此功能用Android中常用的组件化的形式实现。因为js还在学习阶段,中间的历程还是蛮头疼的,就这玩意整了我一下午。
下面是组件的文件结构
在微信小程序中,组件化在官方文档中也有,官方称为自定义组件1。
首先需要新建一个页面来设置自定义组件,其主要组成大体是这个样子:图片
自定义组件跟页面类似,由js,json,wxml,wxss 组成,需要在它的json页面中进行自定义组件的声明
{
"component": true
}
wxml内为组件模板,和普通页面写法一样,在这里写一个空页面的模板
<import src="../empty/template/EmptyTemplate.wxml" />
<view class='empty-show-layout' style='height :{{height}}'>
<template is="empty-template" data="{{...msgEmptyLayoutData}}" wx:if="{{emptyType == msgEmpty}}" />
<template is="empty-template" data="{{...infoEmptyLayoutData}}" wx:if="{{emptyType == infoEmpty}}" />
view>
<block wx:if="{{emptyType == content}}">
<view class='empty-content' wx:if="{{emptyType == content}}">
<slot>slot>
view>
block>
wxss为组件样式
.empty-show-layout {
width: 100%;
position: relative;
}
.empty-layout {
width: 100%;
height: 90%;
position: absolute;
margin: auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 666;
}
.empty-img {
width: 120rpx;
height: 120rpx;
}
.empty-text {
margin-top: 10rpx;
font-size: 32rpx;
color: #000;
}
.empty-content {
position: absolute;
width: 100%;
height: 100%;
}
js中,需要使用Component来注册组件,Component内的数据是可以从外部传入的。Component构造器主要由properties,data,methods组成。
properties为组件的属性值,也就是可以传入的数据,属性格式为:
properties: {
showText: {
type: String,
value: 'default value',
}
type为数据类型,value就是需要传输数据的名字了。
data为组件的内部数据,进行一些赋值操作,这跟普通页面一样。method为组件的方法,比如组件上面的点击事件。
在属性上,我最近看到了模块化(module.exports),所以就用了下。通过exports属性可以对外共享本模块内的属性或函数,类似于kotlin里面的全局变量,所以单独建立一个js文件来写这个module。我根据自己的需求是这样写的:
module.exports = {
// 消息页面空
msgEmpty: -1,
// 信息页面空
infoEmpty: 0,
content: 2,
};
这个模块我后面又加了两个属性,来补一个大坑,这个后面会说。
因为这个空页面复用率会比较高,我用了template创建样式模板,上面组件模板中也有写调用样式模板。
<template name="empty-template">
<view class='empty-layout'>
<image src="{{src}}" mode='aspectFit' class='empty-img' />
<text class="empty-text">{{prompt}}text>
view>
template>
这里附上完整js代码
var EmptyConstant = require("../empty/constant/EmptyConstant.js");
Component({
properties: {
emptyType: {
type: Number,
value: EmptyConstant.content
},
height:{
type: String,
value: EmptyConstant.emptyHeight
}
},
data: {
msgEmpty: EmptyConstant.msgEmpty,
infoEmpty: EmptyConstant.infoEmpty,
content: EmptyConstant.content,
msgEmptyLayoutData: {
emptyType: EmptyConstant.msgEmpty,
height:EmptyConstant.emptyHeight,
src: "../empty/res/image/msgEmpty.png",
prompt: "暂无消息",
},
infoEmptyLayoutData: {
emptyType: EmptyConstant.infoEmpty,
height: EmptyConstant.emptyHeight,
src: "../empty/res/image/infoEmpty.png",
prompt: "暂无地址",
},
},
methods: {
}
})
到这里,自定义组件就构建完成了。
下面就来看看刚刚这个空页面怎么使用。
在需要使用自定义组件的json文件中注册
"usingComponents": {
"empty-layout": "../../empty/empty"
}
然后在wxml里面用自定义组件在显示空页面的地方包起来。
<empty-layout emptyType="{{emptyType}}" height="{{height}}">
<view>自己的内容view>
empty-layout>
在上面的模块化中我存储了一个值emptyType,这个表示当前页面状态, msgEmpty是消息列表为空,infoEmpty为信息列表为空,content为正常页面,这个值在wxml里面赋值,在这里赋的什么值在自定义组件的js里面拿到的就是什么值。这个值需要在所在页面的js里面控制,
var Empty = require("../../empty/constant/EmptyConstant.js");
data: {
emptyType: Empty.content,
},
onLoad: function(options) {
this.setData({
emptyType: Empty.infoEmpty,
})
},
这样页面就会直接显示空页面,可以根据具体的业务需求去控制是否显示。
这里在页面展示上有一个大坑,在上面可能也注意到了,我在wxml调用自定义组件的时候多赋了一个值height,这个是我后面加上去的。因为在组件的wxss中的.empty-show-layout中加入 height: 100%的话,会在页面存在列表数据时出现布局被累加的情况,看起来就像是各个列表信息项的间距变大。
因为page的样式里面height: 100%,组件中的样式为了保证空白页正常显示也必须要设置成height: 100%,这样会导致在不需要空白页的时候会在上面+100%的高度,成为上面那个样子。当然,如果page高度不设置100%的话会导致空白页显示不全的情况,整个view的高度为0。所以,我们要想办法动态控制组件中样式的高度。js直接控制css是没办法了,所以我们通过传值的方式将高度传到wxml中进行动态控制。在上面组件的wxml代码中也写明了style控制。那么我们在模板中加入两个属性。
module.exports = {
// 消息页面空
msgEmpty: -1,
// 信息页面空
infoEmpty: 0,
content: 2,
//正常页面高度
height:"0%",
//空页面高度
emptyHeight: "100%",
};
然后在使用组件的页面中多赋一个值,来控制样式高度,这样组件化空页面的效果就完美解决了。
作为一个小鲜肉级别的程序员第一次写这种总结性的文章,如果有不合适的地方欢迎指正,以后我会坚持下去。不管博客还是开源库,一步步积累才是对自己最好的进步。
自定义组件 ↩︎