本次实战课题是--自定义组件之分页功能实例

@toc

一、分页组件效果展示

::: hljs-center

111.gif

:::

二、分页组件设计流程

::: hljs-center

2222.jpg

:::

三、自定义组件封装必备知识点

1,何谓自定义组件

组件是对数据和方法的简单封装。个人对组件的通俗理解是:对单独的某个通用功能点或UI显示模块的封装。

2,组件框架搭建步骤

此处以js为例:
第一步:在工程目录的common下新建一个包名;
第二步:在新建的包名目录下新建新的空文件(js\hml\css),每个文件具体做啥就不一一介绍了,三个文件的名字一定要一样,这个名字就是外部调用的名字了,非常重要。
第三步:js文件写好简单结构,页面数据,hml中写个div,div中加个text或button就可以了
第四步:将自己新建的组件在可展示的页面中调用并展示。
到这里自定义组件框架已搭建完毕,是不是还比较简单。后面就可以开始完善自己组件的功能了。

3,组件怎么调用

组件引入:

<element name='**pagingcomp**' src='../../common/component/**pagingcomp.hml**'></element>

注意:必须在需要引用的页面最上面调用,路径和name一定要写对,这里的name就是组件的文件的名字。
页面元素装载:

<**pagingcomp** class="threecomp"></**pagingcomp**>

注意:用法跟text、button一样,只是标签名字变成了组件名字。

4,组件怎么定义入参

组件的入参需用props定义:

/* 组件可接收的参数setTotalnum,setPageount
    使用时 setTotalnum 写成 set-totalnum
    setPageount 写成 set-pageount
    */
    props: ['setTotalnum','setPageount'],

注意:组件内部props定义的参数和data定义的参数用法一样,可以直接this.setTotalnum.

5,外部怎么传入参数

参数传入实例:

<pagingcomp class="threecomp" set-totalnum='121' set-pageount='10'></pagingcomp>

注意:set-totalnum,set-pageount为入参,写法一定要将驼峰法的变量拆开并全小写

6,组件怎么提供回调事件并绑定参数

分发回调事件(js代码):

this.$emit('yourFun', {startnum: this.startnum,endnum: this.endnum});

注意:yourFun是组件提供的回调方法名,{startnum: this.startnum,endnum: this.endnum}是参数,this.$emit()调用一次,就会立马相应一次关联的回调方法

7,外部如何绑定回调事件并获取参数

<pagingcomp class="threecomp" @your-fun="testFun"></pagingcomp>

注意:@your-fun="testFun"就是将外部方法testFun和组件内的yourFun进行关联,千万注意写法@your-fun,@ + 内部方法驼峰拆开全小写用‘-’连接

四、代码展示

pagingcomp.js

import document from '@ohos.document';
export default {
    /* 组件可接收的参数setTotalnum,setPageount
    使用时 setTotalnum 写成 set-totalnum
    setPageount 写成 set-pageount
    */
    props: ['setTotalnum','setPageount'],
    data: {
        value: "组件创建",
        //记录条数 外部可设置
        totalnum:101,
        //总页数,内部值
        totalpage:0,
        //开始页码 内部值
        startpage:1,
        //当前页码 内部值
        curpage:1,
        //每页显示记录的条数 外部可设置
        pagecount:5,
        //当前页显示的记录开始ID  传出参数
        startnum:0,
        //当前页显示的记录结束ID 传出参数
        endnum:0,
        //显示的页码按钮数
        itemnum:5,
        //对应页码按钮的状态值 显隐、显示值、样式
        itemlist:[{
            lshow:true,
            value:0,
            bgstyle:"three",
        }, {
            lshow:true,
            value:0,
            bgstyle:"three",
        },{
            lshow:true,
            value:0,
            bgstyle:"three",
        },{
            lshow:true,
            value:0,
            bgstyle:"three",
        },{
            lshow:true,
            value:0,
            bgstyle:"three",
        }],

    },

    /* 组件初始化 */
    onInit() {
        console.log("组件创建")
        this.setAttr();
    },

    /* 组件挂载时主动调用 */
    onAttached() {
        this.value = "组件挂载"
        console.log("组件挂载")
    },

    /* 组件摘除 */
    onDetached() {
        this.value = "2222"
        console.log("2222")
    },

    /* 页面显示时自动调用 */
    onPageShow() {
        this.checkCurPage();
        this.checkShow();
        this.calcItemNum();

        // 发布回调事件 事件ID “yourFun” 使用处需写成 "your-fun"
        this.$emit('yourFun', {startnum: this.startnum,endnum: this.endnum});
    },

    /* 处理传入参数 */
    setAttr(){
        if(typeof(this.setTotalnum) != 'undefined'){
            this.totalnum = this.setTotalnum;
        }

        if(typeof(this.setPageount) != 'undefined'){
            this.pagecount = this.setPageount;
        }
    },

    /* 检查当前页码的合法性 */
    checkCurPage(){
        this.totalpage = Math.ceil(this.totalnum / this.pagecount);
        if (this.curpage > this.totalpage)
        this.curpage = this.totalpage;

        if(this.totalpage <= 0){
            this.totalpage = 0;
            this.curpage = 0;
        }
    },

    /* 检查上一页和下一页中间的按钮显示情况 */
    checkShow(){
        for (var index = 0; index < 5; index++) {
            var isShow = this.startpage + index <= this.totalpage ? true : false;
            this.itemlist[index].lshow = isShow;
            this.itemlist[index].value = this.startpage + index;
            if(this.startpage + index == this.curpage)
            {
                this.itemlist[index].bgstyle = "threeChoose";
            } else {
                this.itemlist[index].bgstyle = "three";
            }
        }
    },

    /* 计算选中页的起始序号 */
    calcItemNum(){
        var nstart = (this.curpage - 1) * this.pagecount;
        nstart = (nstart < 0) ? 0 : nstart;
        var nend = this.curpage * this.pagecount;
        nend = nend > this.totalnum ? this.totalnum : nend;
        this.startnum = nstart + 1;
        this.endnum = nend;
        this.value = "显示ID范围:" + this.startnum + "-" + this.endnum;
    },

    /* 重设上一页和下一页中间的开始页码 */
    setStartNum(){
        if(this.curpage <= this.startpage || this.curpage >= this.startpage + this.itemnum - 1)
        {
            this.startpage = this.curpage - Math.floor(this.itemnum / 2);
            this.startpage = this.startpage < 1 ? 1 : this.startpage;
        }
    },

    /* 上一页按钮事件 */
    pageUp(){
        this.curpage -= 1;
        if(this.curpage < 1){
            this.curpage = 1;
        }
        this.setStartNum();
        this.checkShow();
        this.calcItemNum();
        this.$emit('yourFun', {startnum: this.startnum,endnum: this.endnum});
    },
    /* 下一页按钮事件 */
    pageDown(){
        this.curpage += 1;
        if(this.curpage > this.totalpage){
            this.curpage = this.totalpage;
        }
        this.setStartNum();
        this.checkShow();
        this.calcItemNum();
        this.$emit('yourFun', {startnum: this.startnum,endnum: this.endnum});
    },
    /* 首页按钮事件 */
    homePage(){
        this.curpage = 1;
        this.setStartNum();
        this.checkShow();
        this.calcItemNum();
        this.$emit('yourFun', {startnum: this.startnum,endnum: this.endnum});
    },
    /* 尾页按钮事件 */
    lastPage(){
        this.curpage = this.totalpage;
        this.setStartNum();
        this.checkShow();
        this.calcItemNum();
        this.$emit('yourFun', {startnum: this.startnum,endnum: this.endnum});
    },
    /* 上一页和下一页中间的按钮事件 */
    changeYeMa(e){
        this.curpage = e;
        this.setStartNum();
        this.checkShow();
        this.calcItemNum();
        this.$emit('yourFun', {startnum: this.startnum,endnum: this.endnum});
    },
}

pagingcomp.hml

<div class="item">
    <div class="test">
        <button class="one" onClick="homePage">首页</button>
        <button class="two" onClick="pageUp" value="pageUp">上一页</button>
        <div for="{{itemlist}}" >
            <button onClick="changeYeMa($item.value)" name="page" class="{{ $item.bgstyle}}" if="{{$item.lshow}}">{{$item.value}}</button>
        </div>
        <button class="two" onClick="pageDown" value="page_down">下一页</button>
        <button class="one" onClick="lastPage">尾页</button>
    </div>
</div>

pagingcomp.css

.item {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
}

.test{
    flex-direction: row;
    justify-content: flex-end;
    align-items: flex-start;
    font-size: 20px;
    width: 100%;
    height: 100%;
}

.one{
    width:15%;
    text-color:red;
    background-color:cornflowerblue
}

.two{
    width:20%;
    text-color:orange;
    background-color: cornflowerblue;
}

.three{
    width: 30px;
    align-content: center;
    background-color: black;
    border-color:chartreuse;
    border: 0.5px;
}

.threeChoose{
    width: 30px;
    align-content: center;
    background-color:red;
    border-color:chartreuse;
}

index.hml

<element name='pagingcomp' src='../../common/component/pagingcomp.hml'></element>
<div class="container">
    <text class="title">
        {{ $t('strings.hello') }} {{ title }}
    </text>
    <div class="text-style">
        <text >{{text}}</text>
    </div>
    <pagingcomp class="threecomp" @your-fun="testFun" set-totalnum='121' set-pageount='10'></pagingcomp>
</div>

index.js

export default {
    data: {
        title: "",
        text:"",
    },
    onInit() {
        this.title = this.$t('strings.world');
    },

    /* 自定义回调事件 */
    testFun(e){
        this.text = "显示ID范围:" + e.detail.startnum + "-" + e.detail.endnum;
        console.info(this.text);

    }
}

五、感谢大家阅读

最后感谢大家的阅读,为了能在harmonyos的道路上与时俱进,能和大家一同学习,++假如大家有知道的比较实用的Android插件且还未迁移到harmonyos上来的插件,请留言区告知插件名+插件源码路径地址++,本人想尝试插件移植并与大家分享!再次感谢大家。

想了解更多关于鸿蒙的内容,请访问:

51CTO和华为官方战略合作共建的鸿蒙技术社区

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

::: hljs-center

21_9.jpg

:::