一. 样例介绍
本篇Codelab基于input组件、label组件和dialog组件,实现表单页面的输入、必填校验和提交:
1.
为input组件设置不同类型(如:text,email,date等),完成表单页面。
2.
对表单页面中的用户名、电子邮件、爱好输入框进行必填校验。
3.
使用弹框选择性别、爱好。
相关概念
●
input组件
:交互式组件,包括单选框,多选框,按钮和单行文本输入框。
●
label组件
:为input、button、textarea组件定义相应的标注,点击该标注时会触发绑定组件的点击效果。
●
dialog组件
:自定义弹窗容器。
完整示例
gitee源码地址
二. 环境搭建
我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。
软件要求
●
DevEco Studio
版本:DevEco Studio 3.1 Release及以上版本。
●
HarmonyOS SDK
版本:API version 9及以上版本。
硬件要求
●
设备类型:华为手机或运行在DevEco Studio上的华为手机设备模拟器。
●
HarmonyOS系统:3.1.0 Developer Release及以上版本。
环境搭建
1.
安装DevEco Studio,详情请参考
下载和安装软件
。
2.
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:
●
如果可以直接访问Internet,只需进行
下载HarmonyOS SDK
操作。
●
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考
配置开发环境
。
1.
开发者可以参考以下链接,完成设备调试的相关配置:
●
使用真机进行调试
●
使用模拟器进行调试
三.代码结构解读
本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在源码下载或gitee中提供。
├──entry/src/main/js // 代码区
│ └──MainAbility
│ ├──common
│ │ ├──constant
│ │ │ └──commonConstants.js // 公共常量
│ │ └──images // 图片资源目录
│ ├──i18n
│ │ ├──en-US.json // 英文国际化
│ │ └──zh-CN.json // 中文国际化
│ ├──pages
│ │ └──index
│ │ ├──index.css // 表单页面样式
│ │ ├──index.hml // 表单页面
│ │ └──index.js // 表单页面逻辑
│ └──app.js // 程序入口
└──entry/src/main/resource // 应用静态资源目录
四. 页面设计
页面包括用户名、电子邮箱、出生日期、身高、性别、爱好输入框和提交按钮,点击提交按钮进行必填校验。
<!-- index.hml -->
<div class="container">
...
<div class="user-area">
<image class="image" src="{{ urls.user }}"></image>
<div class="input-label">
<image src="{{ urls.required }}"></image>
<label class="label" target="user">{{ $t(strings.user) }}</label>
</div>
<div class="input-div">
<input class="input" id="user" type="text" placeholder="{{ $t(strings.user) }}" onchange="inputChange"
ontranslate="translate"></input>
</div>
</div>
<div class="input-area">
<image src="{{ urls.email }}"></image>
<div class="input-label">
<image src="{{ urls.required }}"></image>
<label class="label" target="email">{{ $t(strings.email) }}</label>
</div>
<div class="input-div">
<input class="input" id="email" type="email" placeholder="{{ $t(strings.email) }}"
onchange="inputChange">
</input>
</div>
</div>
<div class="input-area">
<image src="{{ urls.date }}"></image>
<div class="input-label">
<label class="label" target="date">{{ $t(strings.birthday) }}</label>
</div>
<div class="input-div">
<input class="input" id="date" type="date" placeholder="{{ $t(strings.date) }}" onchange="inputChange">
</input>
</div>
</div>
<div class="input-area">
<image src="{{ urls.height }}"></image>
<div class="input-label">
<label class="label" target="height">{{ $t(strings.height_holder) }}</label>
</div>
<div class="input-div">
<input class="input" id="height" type="number" placeholder="{{ $t(strings.height) }}"
onchange="inputChange"></input>
</div>
</div>
<div class="input-area">
<image src="{{ urls.gender }}"></image>
<div class="input-label">
<label class="label" target="gender">{{ $t(strings.gender) }}</label>
</div>
<div class="input-div" onclick="openGender">
<input class="input select" id="gender" type="text" placeholder="{{ $t(strings.gender) }}"
softkeyboardenabled="false"
value="{{ genderObj[gender] }}"></input>
<image src="{{ urls.spinner }}"></image>
</div>
</div>
<div class="input-area">
<image src="{{ urls.hobby }}"></image>
<div class="input-label">
<image src="{{ urls.required }}"></image>
<label class="label" target="hobbies">{{ $t(strings.hobbies) }}</label>
</div>
<div class="input-div" onclick="openHobby">
<input class="input select" id="hobbies" type="text" placeholder="{{ $t(strings.hobby) }}"
softkeyboardenabled="false" value="{{ hobbies.join(,) }}"></input>
<image src="{{ urls.spinner }}"></image>
</div>
</div>
<button type="capsule" onclick="buttonClick">{{ $t(strings.submit) }}</button>
...
</div>
效果如图所示:
点击性别输入框弹出性别单选框,点击爱好输入框弹出爱好多选框。
<!-- index.hml -->
<div class="container">
...
<dialog id="genderDialog">
<div class="gender-dialog">
<text>{{ $t(strings.gender_select) }}</text>
<div>
<text>{{ $t(strings.gender_male) }}</text>
<input if="{{ gender === 0 }}" class="radio" type="radio" checked="true" name="radio"
value="{{ $t(strings.gender_male) }}" onchange="onRadioChange"></input>
<input if="{{ gender === 1 }}" class="radio" type="radio" checked="false" name="radio"
value="{{ $t(strings.gender_male) }}" onchange="onRadioChange"></input>
</div>
<divider vertical="false"></divider>
<div>
<text>{{ $t(strings.gender_female) }}</text>
<input if="{{ gender === 0 }}" class="radio" type="radio" checked="false" name="radio"
value="{{ $t(strings.gender_female) }}"></input>
<input if="{{ gender === 1 }}" class="radio" type="radio" checked="true" name="radio"
value="{{ $t(strings.gender_female) }}"></input>
</div>
<div class="button">
<text onclick="closeGender">{{ $t(strings.cancel) }}</text>
<divider vertical="true"></divider>
<text onclick="confirmGender">{{ $t(strings.determined) }}</text>
</div>
</div>
</dialog>
<dialog id="hobbyDialog">
<div class="hobby-dialog">
<text>{{ $t(strings.hobby) }}</text>
<div>
<text>{{ $t(strings.hobby_swim) }}</text>
<input class="checkbox" type="checkbox" checked="{{ hobbies.indexOf(hobbiesOjb[0]) !== -1 }}"
value="{{ hobbiesOjb[0] }}" onchange="checkboxOnChange"></input>
</div>
<div>
<text>{{ $t(strings.hobby_fitness) }}</text>
<input class="checkbox" type="checkbox" checked="{{ hobbies.indexOf(hobbiesOjb[1]) !== -1 }}"
value="{{ hobbiesOjb[1] }}" onchange="checkboxOnChange"></input>
</div>
<div>
<text>{{ $t(strings.hobby_soccer) }}</text>
<input class="checkbox" type="checkbox" checked="{{ hobbies.indexOf(hobbiesOjb[2]) !== -1 }}"
value="{{ hobbiesOjb[2] }}" onchange="checkboxOnChange"></input>
</div>
<div>
<text>{{ $t(strings.hobby_basketball) }}</text>
<input class="checkbox" type="checkbox" checked="{{ hobbies.indexOf(hobbiesOjb[3]) !== -1 }}"
value="{{ hobbiesOjb[3] }}" onchange="checkboxOnChange"></input>
</div>
<div>
<text>{{ $t(strings.hobby_reading_book) }}</text>
<input class="checkbox" type="checkbox" checked="{{ hobbies.indexOf(hobbiesOjb[4]) !== -1 }}"
value="{{ hobbiesOjb[4] }}" onchange="checkboxOnChange"></input>
</div>
<div class="button">
<text onclick="closeHobby">{{ $t(strings.cancel) }}</text>
<divider vertical="true"></divider>
<text onclick="confirmHobby">{{ $t(strings.determined) }}</text>
</div>
</div>
</dialog>
</div>
效果如图所示:
五. 后台逻辑处理
用户名、电子邮箱、出生日期、身高输入框中值发生变化时,会在data对象中实时更新。
// index.js
export default {
data: {
...
user: ,
email: ,
date: ,
height: ,
...
},
...
// 实时保存输入框内容
inputChange(event) {
let idName = event.target.id;
if (idName === CommonConstants.USER) {
this.user = event.value;
} else if (idName === CommonConstants.EMAIL) {
this.email = event.value;
} else if (idName === CommonConstants.DATE) {
this.date = event.value;
} else if (idName === CommonConstants.HEIGHT) {
this.height = event.value;
}
},
...
}
通过自定义弹框选择性别、爱好。在弹框中点击取消按钮关闭当前弹框,点击确定按钮先设置所选值再关闭弹框。
// index.js
export default {
data: {
...
genderObj: [],
genderTemp: 0,
gender: 0,
hobbiesOjb: [],
hobbiesTemp: [],
hobbies: []
},
...
// 打开性别弹框
openGender() {
this.$element(genderDialog).show();
},
// 重新选择性别
onRadioChange(event) {
if (event.checked) {
this.genderTemp = 0;
} else {
this.genderTemp = 1;
}
},
// 关闭性别弹框
closeGender() {
this.$element(genderDialog).close();
},
// 性别弹框中点击“确定”
confirmGender() {
this.gender = this.genderTemp;
this.closeGender();
},
// 打开爱好弹框
openHobby() {
this.$element(hobbyDialog).show();
},
// 关闭爱好弹框
closeHobby() {
this.$element(hobbyDialog).close();
},
// 在爱好弹开中点击“确定”
confirmHobby() {
let that = this;
let copyHobbies = Object.create(Object.getPrototypeOf(this.hobbiesTemp));
Object.getOwnPropertyNames(this.hobbiesTemp).forEach((items) => {
let item = Object.getOwnPropertyDescriptor(that.hobbiesTemp, items);
Object.defineProperty(copyHobbies, items, item);
})
this.hobbies = copyHobbies;
this.closeHobby();
},
...
// 选择爱好
checkboxOnChange(event) {
let currentVal = event.currentTarget.attr.value;
if (event.checked) {
this.hobbiesTemp.push(currentVal);
} else {
this.hobbiesTemp = this.hobbiesTemp.filter(item => {
return item !== currentVal;
});
}
},
...
}
点击提交按钮对表单进行提交前,先对用户名、密码、电子邮件、爱好进行必填校验,再通过正则表达式对出生日期进行“yyyy-mm-dd”格式校验、对身高进行整数或浮点数校验。
// index.js
export default {
...
// 表单提交验证
buttonClick() {
if (this.user === ) {
this.showPrompt(this.$t(strings.user_check_null));
return;
}
if (this.email === ) {
this.showPrompt(this.$t(strings.email_check_null));
return;
}
if (this.hobbies.length === 0) {
this.showPrompt(this.$t(strings.hobby_check_null));
return;
}
if ((this.date !== ) && (!this.checkDateInput(this.date))) {
this.showPrompt(this.$t(strings.date_not_format));
return;
}
if ((this.height !== ) && (!this.checkHeight(this.height))) {
this.showPrompt(this.$t(strings.height_not_format));
return;
}
this.showPrompt(this.$t(strings.success));
},
...
// 表单验证结果
showPrompt(msg) {
prompt.showToast({
message: msg,
duration: CommonConstants.DURATION
});
},
...
}
总结
您已经完成了本次Codelab的学习,并了解到以下知识点:
1.
input组件的使用。
2.
label组件的使用。
3.
dialog组件的使用。