一.样例介绍

本篇Codelab基于input组件、label组件和dialog组件,实现表单页面的输入、必填校验和提交:

1. 为input组件设置不同类型(如:text,email,date等),完成表单页面。

2. 对表单页面中的用户名、电子邮件、爱好输入框进行必填校验。

3. 使用弹框选择性别、爱好。

相关概念

●input组件:交互式组件,包括单选框,多选框,按钮和单行文本输入框。

●label组件:为input、button、textarea组件定义相应的标注,点击该标注时会触发绑定组件的点击效果。

●dialog组件:自定义弹窗容器。

完整示例

gitee源码地址

二.环境搭建

我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。

软件要求

●DevEcoStudio版本:DevEcoStudio3.1Release及以上版本。

●HarmonyOSSDK版本:APIversion9及以上版本。

硬件要求

●设备类型:华为手机或运行在DevEcoStudio上的华为手机设备模拟器。

●HarmonyOS系统:3.1.0DeveloperRelease及以上版本。

环境搭建

1. 安装DevEcoStudio,详情请参考下载和安装软件。

2. 设置DevEcoStudio开发环境,DevEcoStudio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

●如果可以直接访问Internet,只需进行下载HarmonyOSSDK操作。

●如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。

1. 开发者可以参考以下链接,完成设备调试的相关配置:

●使用真机进行调试

●使用模拟器进行调试

HarmonyOS实现表单页面的输入,必填校验和提交

三.代码结构解读

本篇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">
        <imageclass="image"src="{{urls.user}}"></image>
        <div class="input-label">
            <imagesrc="{{urls.required}}"></image>
            <label class="label"target="user">{{$t('strings.user')}}</label>
        </div>
        <div class="input-div">
            <inputclass="input"id="user"type="text"placeholder="{{$t('strings.user')}}"onchange="inputChange"
ontranslate="translate"></input>
        </div>
    </div>
    <div class="input-area">
        <imagesrc="{{urls.email}}"></image>
        <div class="input-label">
            <imagesrc="{{urls.required}}"></image>
            <label class="label"target="email">{{$t('strings.email')}}</label>
        </div>
        <div class="input-div">
            <inputclass="input"id="email"type="email"placeholder="{{$t('strings.email')}}"
onchange="inputChange">
            </input>
        </div>
    </div>
    <div class="input-area">
        <imagesrc="{{urls.date}}"></image>
        <div class="input-label">
            <label class="label"target="date">{{$t('strings.birthday')}}</label>
        </div>
        <div class="input-div">
            <inputclass="input"id="date"type="date"placeholder="{{$t('strings.date')}}"onchange="inputChange">
            </input>
        </div>
    </div>
    <div class="input-area">
        <imagesrc="{{urls.height}}"></image>
        <div class="input-label">
            <label class="label"target="height">{{$t('strings.height_holder')}}</label>
        </div>
        <div class="input-div">
            <inputclass="input"id="height"type="number"placeholder="{{$t('strings.height')}}"
onchange="inputChange"></input>
        </div>
    </div>
    <div class="input-area">
        <imagesrc="{{urls.gender}}"></image>
        <div class="input-label">
            <label class="label"target="gender">{{$t('strings.gender')}}</label>
        </div>
        <div class="input-div"onclick="openGender">
            <inputclass="inputselect"id="gender"type="text"placeholder="{{$t('strings.gender')}}"
softkeyboardenabled="false"
value="{{genderObj[gender]}}"></input>
            <imagesrc="{{urls.spinner}}"></image>
        </div>
    </div>
    <div class="input-area">
        <imagesrc="{{urls.hobby}}"></image>
        <div class="input-label">
            <imagesrc="{{urls.required}}"></image>
            <label class="label"target="hobbies">{{$t('strings.hobbies')}}</label>
        </div>
        <div class="input-div"onclick="openHobby">
            <inputclass="inputselect"id="hobbies"type="text"placeholder="{{$t('strings.hobby')}}"
softkeyboardenabled="false"value="{{hobbies.join(',')}}"></input>
            <imagesrc="{{urls.spinner}}"></image>
        </div>
    </div>
    <buttontype="capsule"onclick="buttonClick">{{$t('strings.submit')}}</button>
    ...
</div>

效果如图所示:

HarmonyOS实现表单页面的输入,必填校验和提交

点击性别输入框弹出性别单选框,点击爱好输入框弹出爱好多选框。

<!-- index.hml-->
<div class="container">
    ...
    <dialogid="genderDialog">
        <div class="gender-dialog">
            <text>{{$t('strings.gender_select')}}</text>
            <div>
                <text>{{$t('strings.gender_male')}}</text>
                <inputif="{{gender===0}}"class="radio"type="radio"checked="true"name="radio"
value="{{$t('strings.gender_male')}}"onchange="onRadioChange"></input>
                <inputif="{{gender===1}}"class="radio"type="radio"checked="false"name="radio"
value="{{$t('strings.gender_male')}}"onchange="onRadioChange"></input>
            </div>
            <dividervertical="false"></divider>
            <div>
                <text>{{$t('strings.gender_female')}}</text>
                <inputif="{{gender===0}}"class="radio"type="radio"checked="false"name="radio"
value="{{$t('strings.gender_female')}}"></input>
                <inputif="{{gender===1}}"class="radio"type="radio"checked="true"name="radio"
value="{{$t('strings.gender_female')}}"></input>
            </div>
            <div class="button">
                <textonclick="closeGender">{{$t('strings.cancel')}}</text>
                <dividervertical="true"></divider>
                <textonclick="confirmGender">{{$t('strings.determined')}}</text>
            </div>
        </div>
    </dialog>
    <dialogid="hobbyDialog">
        <div class="hobby-dialog">
            <text>{{$t('strings.hobby')}}</text>
            <div>
                <text>{{$t('strings.hobby_swim')}}</text>
                <inputclass="checkbox"type="checkbox"checked="{{hobbies.indexOf(hobbiesOjb[0])!==-1}}"
value="{{hobbiesOjb[0]}}"onchange="checkboxOnChange"></input>
            </div>
            <div>
                <text>{{$t('strings.hobby_fitness')}}</text>
                <inputclass="checkbox"type="checkbox"checked="{{hobbies.indexOf(hobbiesOjb[1])!==-1}}"
value="{{hobbiesOjb[1]}}"onchange="checkboxOnChange"></input>
            </div>
            <div>
                <text>{{$t('strings.hobby_soccer')}}</text>
                <inputclass="checkbox"type="checkbox"checked="{{hobbies.indexOf(hobbiesOjb[2])!==-1}}"
value="{{hobbiesOjb[2]}}"onchange="checkboxOnChange"></input>
            </div>
            <div>
                <text>{{$t('strings.hobby_basketball')}}</text>
                <inputclass="checkbox"type="checkbox"checked="{{hobbies.indexOf(hobbiesOjb[3])!==-1}}"
value="{{hobbiesOjb[3]}}"onchange="checkboxOnChange"></input>
            </div>
            <div>
                <text>{{$t('strings.hobby_reading_book')}}</text>
                <inputclass="checkbox"type="checkbox"checked="{{hobbies.indexOf(hobbiesOjb[4])!==-1}}"
value="{{hobbiesOjb[4]}}"onchange="checkboxOnChange"></input>
            </div>
            <div class="button">
                <textonclick="closeHobby">{{$t('strings.cancel')}}</text>
                <dividervertical="true"></divider>
                <textonclick="confirmHobby">{{$t('strings.determined')}}</text>
            </div>
        </div>
    </dialog>
</div>

效果如图所示:

HarmonyOS实现表单页面的输入,必填校验和提交

五.后台逻辑处理

用户名、电子邮箱、出生日期、身高输入框中值发生变化时,会在data对象中实时更新。

//index.js
export default {
data:{
...
user:'',
email:'',
date:'',
height:'',
...
},
  ...
  //实时保存输入框内容
inputChange(event) {
letidName=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() {
letthat=this;
letcopyHobbies=Object.create(Object.getPrototypeOf(this.hobbiesTemp));
Object.getOwnPropertyNames(this.hobbiesTemp).forEach((items)=>{
letitem=Object.getOwnPropertyDescriptor(that.hobbiesTemp,items);
Object.defineProperty(copyHobbies,items,item);
})
this.hobbies=copyHobbies;
this.closeHobby();
},
  ...
  //选择爱好
checkboxOnChange(event) {
letcurrentVal=event.currentTarget.attr.value;
if(event.checked){
this.hobbiesTemp.push(currentVal);
} else {
this.hobbiesTemp=this.hobbiesTemp.filter(item=>{
returnitem!==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组件的使用。