#夏日挑战赛#FFHJS自定义组件:DIY一个随点随用的键盘!

Posted 开源基础软件社区官方

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#夏日挑战赛#FFHJS自定义组件:DIY一个随点随用的键盘!相关的知识,希望对你有一定的参考价值。

本文正在参加星光计划3.0–夏日挑战赛

ArkUI自定义组件实战开发:如何快速拥有一个私人定制的软键盘?

前言

平时在Devco Studio调试代码的过程中经常需要输入的操作,像一些根据用户输入来处理数据的模块,然而相信不少的开发伙伴们都苦于预览器previewer中没有自带的输入法键盘,要么运行真机模拟器,要么自己在代码中初始化数据,不太自由和方便。
因此,在看完文档的自定义组件开发后,我决定写一个类似输入法键盘的自定义组件,随点随用。
这个夏天,我要实现输入自由!(来自前端开发人的高呼)
官方文档:
https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-custom-basic-usage-0000001281361086

效果展示

代码实现

代码结构

编写自定义组件的事件

理论解释:

liteKeyboard.js代码中,自定义组件接口会提供三个基本的接口函数:

这里只需使用data和props,(computed用于数据预处理,详情可以去官方文档看)

props

有两种书写方式

props:
     textType:
         default : defaultValue   
     
 //---第一种
props : [textType] //---第二种

第一种的方式可以给props规定的属性设置默认值(通过关键词default)

props使用演示

liteKeyboard.js

props: 
    isValid:
        default: true
    ,
,

index.hml

<element name="liteKeyboard" src="../../common/component/liteKeyboard.hml"></element>
<div class="container">
    <litekeyboard is-valid="false" @text-type="textClick"></litekeyboard>
</div>

这里的is-valid属性即是上面设置的isValid,is-valid的值将作为参数传递给isValid
注意: 驼峰命名法的 prop 名,在外部父组件传递参数时需要使用短横线分隔命名形式,即当属性isValid在父组件引用时需要转换为is-value。

data

类似pages页面的data:,功能除了初始化hml绑定的数据,还可以用来接收父组件(即调用它的组件)的参数
因为自定义组件的数据是单向性的(父传子),子组件即liteKeyboard.js不能直接修改父组件传来的值
引用官方文档:

理论结束,实战开始

大体思路:

对于数字键盘点击输入的数字用字符数组存储,点击事件触发时将字符数组作为参数text传递,再index.js用e.detail.text获取,并在自定义事件中与把所有需要输入的文本框数据进行绑定。

先写好键盘的样式

对于这种规则的宫格布局,采用grid来布局是不错的方法
liteKeyboard.hml

<div class="container">
    <div class="keyboardCot">
        <div class="grid-container">
            <div class="grid-item" id="1" @click="click">
                <text class="keyboard">1</text>
            </div>
            <div class="grid-item" id="2" @click="click">
                <text class="keyboard">2</text>
            </div>
            <div class="grid-item" id="3" @click="click">
                <text class="keyboard">3</text>
            </div>
            <div class="grid-item" id="4" @click="click">
                <text class="keyboard">4</text>
            </div>
            <div class="grid-item" id="5" @click="click">
                <text class="keyboard">5</text>
            </div>
            <div class="grid-item" id="6" @click="click">
                <text class="keyboard">6</text>
            </div>
            <div class="grid-item" id="7" @click="click">
                <text class="keyboard">7</text>
            </div>
            <div class="grid-item" id="8" @click="click">
                <text class="keyboard">8</text>
            </div>
            <div class="grid-item" id="9" @click="click">
                <text class="keyboard">9</text>
            </div>
            <div class="grid-item" id="." @click="click">
                <text class="keyboard">.</text>
            </div>
            <div class="grid-item" id="0" @click="click">
                <text class="keyboard">0</text>
            </div>
            <div class="grid-item" id="x" @click="click">
                <image src="/common/images/ic_contacts_delete.png"></image>
            </div>
        </div>
    </div>
</div>

liteKeyboard.css

.container 
    flex-direction: column;
    justify-content: center;
    align-items: center;
    left: 0px;
    top: 0px;
    width: 100%;
    height: 100%;
    background-color: black;


.keyboardCot 
    top: 8%;
    height: 560px;
    width: 660px;
    justify-content: space-around;
    border-radius: 40px;


.grid-container 

    height: 100%;
    width: 100%;
    display: grid;
    grid-template-rows: 140px 140px 140px 140px;
    grid-template-columns: 220px 220px 220px;


.grid-item 
    background-color: rgba(41, 41, 41, 1);
    border-radius: 100px;
    width: 100%;
    height: 95%;
    margin: 5px;
    justify-content: space-around;
    align-content: space-around;
    align-items: center;


.grid-item:active 
    background-color: darkgray;


.keyboard 
    font-size: 60px;
    font-weight: 300;
    color: white;


.grid-item > image 
    height: 80px;
    width: 80px;

编写响应事件

liteKeyboard.js

export default 
    props: 
        isValid:
            default: true
        ,
    ,
    data() 
        return 
            inputText: [],//---存储键盘输入数据的字符数组
            bit: false,
            isValid: this.isValid //--- is-valid属性(是否需要数据合法性处理)
        
    ,

    click(e)  //----数字键盘点击事件
        let id = e.target.id
        if (this.isValid === false)  //---不用合法处理
            this.randomInput(id).then(texts => 
                this.$emit(textType, 
                    text: texts
                );
            )
        
        else if (this.isValid === true) 
            this.validInput(id).then(texts => 
                this.$emit(textType, 
                    text: texts
                );
            )
        
        else 
            console.info(`attribute "isValid" error , "isValid" only can be false | true`) //---限定is-valid只有两种参数false和true
        
    ,

    randomInput(id)  //---不需要合法性检查时
        return new Promise((res) => 
            if (id !== x) 
                this.inputText += `$id`
                res(this.inputText)
             else 
                if (this.inputText.length !== 0) 
                    this.inputText = this.inputText.slice(0, this.inputText.length - 1)
                
                res(this.inputText)
            
        )
    ,
    validInput(id)  //---合法性检查和处理
        return new Promise((res) => 
            let len = this.inputText.length
            if (id === .) 
                let a = this.inputText.indexOf(.)
                if (a !== -1)this.bit = true
                else this.bit = false
                if (this.bit || (len === 2 && this.inputText[0] === 0 && this.inputText[1] === .))res(this.inputText)
            
            if (len === 1) 
                if (this.inputText[0] === 0 && id !== . && id !== x)res(this.inputText)
            
            if (id === x) 
                console.info(x)
                if (len !== 0) 
                    this.inputText = this.inputText.slice(0, len - 1)
                    res(this.inputText)
                
            
            if (len <= 7) 
                if (id !== x) 
                    this.inputText += `$id`
                    res(this.inputText)
                
            
            res(this.inputText)
        )
    

父组件界面(配合dialog弹窗食用更佳!)

index.hml

<element name="liteKeyboard" src="../../common/component/liteKeyboard.hml"></element>
<div class="container">
    <div class="titleCot" onclick="showKeyboard">
        <div class="titleText">
            <text style="
                    flex-wrap : wrap;
                    justify-content : space-around;
                    height : 200px;
                    color : white;
                    font-size : 90px;" >inputText
            </text> <!--换成input文本框会与真机的输入法冲突。。-->
        </div>
    </div>

    <dialog style="width : 100%; height : 800px; position : fixed;" id="keyboard"> 
        <litekeyboard is-valid="false" @text-type="textClick"></litekeyboard>
    </dialog>

</div>
export default 
    data: 
        inputText:
    ,
    onInit() 
    ,
    textClick(e) //---自定义事件(点击)
        this.inputText = e.detail.text //---在这里进行数据绑定
        console.info(receive text = +this.inputText)
    ,
    showKeyboard() //---带输入文本框组件的点击事件
        this.$element(keyboard).show()//---当点击待输入的文本框时就拉起键盘
    ,
.container 
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    left: 0px;
    top: 0px;
    width: 100%;
    height: 100%;
    background-color: black;


.titleText 
    text-align: center;
    height: 200px;

.titleCot 
    position: absolute;
    width: 100%;
    height: 200px;
    align-content: space-around;
    background-color: gray;
    align-items: center;
    justify-content: space-around;

为了体现自定义组件特性和丰富liteKeyboard的功能,我加入了props属性:is-valid来根据实际是否需要对输入数据进行合法性检查,默认值为false不需要,这在对于一些规定数据类型为Number的场景比如金额输入很适用,相当于实现了像手机输入法的一些功能。当然,我们还可以借助props、computed来DIY更多的功能,充分开发自定义组件的特性,做出更高级的键盘。

待改进

上面编写的键盘不太实用,仅限绑定一个数据(即只能绑定一个文本输入框),如何应用到我们平时在previewer多数据输入场景的调试当中?那就需要加入更多的自定义组件特性功能,所以在下篇中进行了代码的改进:

JS自定义组件:DIY一个随点随用的键盘!(一)

总结

至此,一个属于你自己、随点随用的DIY键盘就诞生了。
总而言之,自定义组件的使用体验和封装效果很不错,耦合性可以有效的减少,对于前端UI的开发来说确实方便不少。当然,这次实战只是一个对自定义组件强大功能的简单试探,希望以后能用它创造出更丰富好用的组件!

附件链接:https://ost.51cto.com/resource/2219

想了解更多关于开源的内容,请访问:

51CTO 开源基础软件社区

https://ost.51cto.com/#bkwz

以上是关于#夏日挑战赛#FFHJS自定义组件:DIY一个随点随用的键盘!的主要内容,如果未能解决你的问题,请参考以下文章

#夏日挑战赛#OHOS构建自定义服务实战

#夏日挑战赛# HarmonyOS - 方舟开发框架ArkUI 流光按钮效果

#夏日挑战赛# HarmonyOS - 实现带日期效果的待办事项

#夏日挑战赛# HarmonyOS 实现一个手绘板

#夏日挑战赛#数据库学霸笔记,考试/面试快速复习~

#夏日挑战赛#FFHHarmonyOS手机遥控Dayu开发板相机