背景描述
由于公司项目的需求,项目中会遇到各种各样的表单,但是表单样式几乎都是统一的,考虑将所有的样式输入或者展示组件封装入自定义form组件内,form组件自己处理是否全部的必填项填写完毕,生成对应的respontBody,检验用户的输入负责是否符合规范,具体每个子页面的展示和单独的数据源处理是单独的js去处理。由于之前做移动端开发,做过类似的封装所以做了一下封装尝试,效果还错。
代码思路讲解
1.先构建自己的form组件
通过Behavior共用代码路由到配置项js文件
{
'title': '车系', // 标题
'require': true, //是否必填项
'value': -1,//组件的值后面会转为数据
'type': 'picker', //组件类型,标识时那种组件
'subType': 'seclector', //组件的次级分类
'placeholder': '请选择',
'regular': '',//校验规则
'error': '',//错误提示
'apiKey': 'dartment',//上传接口时候的key
'index': 5,//在表单中的下标
'hidden': false,//是否隐藏
'options': [
],//数据源
},
//当个picker组件form.wxml的样式示例
<!-- picker组件分为date和配置项选择 -->
<view wx:elif="{{item.type === 'picker'}}">
<view wx:if="{{item.subType === 'date'}}">
<picker mode="date" start="{{item.startDate}}" end="{{item.endDate}}" bindchange="pickerVauleChange" id="{{index}}">
<view class="picker-back {{item.value ? 'normal-font' : 'gray-font'}}">
<view class="we-picker-flex">
<text class="cell-title">{{item.title}}</text>
<i class="red-font-picker" hidden="{{item.require}}">*</I>
</view>
<view class="picker {{item.value ? 'normal-font' : 'gray-font'}}">{{item.value ? item.value :item.placeholder}}
<i class="csyfont csyxiayiye i"></I>
</view>
</view>
</picker>
</view>
<view wx:else>
<picker mode="selector" range="{{item.options}}" bindchange="pickerVauleChange" range-key="label" id="{{index}}" value="{{item.value}}">
<view class="picker-back">
<view class="we-picker-flex">
<text class="cell-title">{{item.title}}</text>
<i class="red-font-picker" hidden="{{item.require}}">*</I>
</view>
<view class="picker {{item.value > -1 ? 'normal-font' : 'gray-font'}}">{{item.options[item.value] ? item.options[item.value].label :item.placeholder}}
<i class="csyfont csyxiayiye i"></I>
</view>
</view>
</picker>
</view>
</view>
效果如下:
2.通过behaviors引入共用的代码和共用属性
代码示例:
Component({
options: {
addGlobalClass: true // 等价于styleIsolation: 'apply-shared'
},
behaviors: [require('../../behavior/route/route.js')], // 引入公共代码
externalClasses: ['my-class'],
properties: {
extraData: {
type: Object,
value: {}, //其他的子页面需要的数据类型
observer: '__extraData'
},
saveData: {
type: Boolean,
value: false,
observer: '__saveRequest'//父类发起了保存操作,会顺序讲item.value和item.apiKey相结合并触发提交
},
extraInput: {
type: Array,
value: [],
observer: '__exraInput'
}
},
data: {
datasource: [],//数据源
emptyAry: [], //所有重要的下标
allInput: false,//是否全部填写完毕
ativeIndex: 0,
vaild: [],//需要校验规则,输入是否合法
requestData: {} //需要默认传的值
},
}
3.rout.js到底做了什么?
module.exports = Behavior({
properties:{
// 指定单独操作组件的数据源的文件夹名称
behaviorCode:String,
// 文件名称
behaviorModel:{
type:String,
value:''
}
},
data:{
behaviorSite:''
},
attached:function(){
let code = this.data.behaviorCode || this.data.behaviorModel
this.setData({
behaviorSite: require('../../behavior/' + this.data.behaviorModel + '/' + code + '.js')//引入指定文件
})
},
methods:{
}
})
4.引用自定form的时候,通过behaviorCode和behaviorModel绑定操作当前的form的js文件
<cs-form behaviorModel="repectionnew" behaviorCode="repectionnew" bind:allInput="allslected" saveData="{{saveData}}" ></cs-form>
5.在form里面对绑定的js操作
5.1 获取数据源
this.data.behaviorSite.datasource(this, function (res) {
if (res) {
if (!util.isNull(that.data.datasource)) {
util.log("form:" + 'behaviorSite.datasource')
that.getEmptyAry(that.data.datasource)
}
} else {
that.getEmptyAry(that.data.datasource)
}
})
5.2面对需要调的单独方法
只需要调用指定的js暴露出来的方法就好