从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

原创
02/06 17:07
阅读数 2.9K

目录:

1、tabs, tab-bar, tab-content

2、tabs的事件处理

3、tabs实现的每日新闻

1、tabs, tab-bar, tab-content

上章说到,鸿蒙的list组件仅能支持竖向滚动,无法实现横向滚动。如果需要作出可横向滚动的顶部菜单栏,鸿蒙提供了tabs组件。tabs配合两个子元素组件tab-bar和tab-content,即可很轻松地实现顶部菜单+内容切换效果。

tab-bar的子元素为text,tab-content的子元素为div。

hml:

<div class="container">
    <tabs class="tabs">
        <tab-bar>
            <block for="{{ tabBar }}">
                <text>
                    {{ $item.name }}
                </text>
            </block>
        </tab-bar>
        <tab-content>
            <block for="{{ tabBar }}">
                <div style="background-color: {{ $item.color }}; height: 500px;">
                    <text style="font-size: 50px;">
                        {{ $idx }}
                    </text>
                </div>
            </block>
        </tab-content>
    </tabs>
</div>

css:

.container {
    width: 100%;
    height: 1200px;
    display: flex;
    flex-direction: column;
}
.tabs{
    width: 100%;
    height: 100%;
}

js:

export default {
    data: {
        tabBar: [{name: '推荐', color: '#1296db'},
                 {name: '最新', color: '#e20a0b'},
                 {name: '最热', color: '#cdcdcd'}]
    }
}

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

由效果可看出,tab-bar组件是顶部的菜单栏,自带了动态样式。tab-content组件是下方的内容部分,会根据点击的菜单切换到对应的内容部分。tab-bar和tab-content是根据索引值一一对应的。这里还发现,哪怕tab-content给了height: 500px的样式,还是会占满整个tabs的高度。

tabs的属性index用于指定默认选中的菜单索引项,vertical指定是否为竖向菜单栏。这里设置为竖向后可以看出,tab-bar变为占满一列,tab-content的height样式起作用,宽度则占满tabs。

<tabs class="tabs" index="1" vertical="true">

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

多放几个菜单项,并设置tab-bar的属性mode="fixed",则菜单项无法滑动,均布占满整行。

<tabs class="tabs" index="0" vertical="false">
    <tab-bar mode="fixed">

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

mode="scrollable",就有横向滚动效果了,且点击菜单项后整个菜单栏会有适应移动效果。

<tab-bar mode="scrollable">

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

tab-content属性scrollable-"true",菜单对应内容就可以竖向滚动了,和list效果类似。

<tab-content scrollable="true">

2、tabs的事件处理

如想捕获菜单项变化的事件并进行处理,需在tabs标签中通过onchange进行绑定。在传入的事件对象中,index则为选中菜单项的索引值。这里使用prompt模块的showToast()进行调试。

<tabs class="tabs" index="0" vertical="false" onchange="changeTab">
import prompt from '@system.prompt';
export default {
    data: {
        tabBar: [
            ...
        ]
    },
    changeTab(event) {
        prompt.showToast({
            message: '你点击了第' + event.index + '项。'
        })
    }
}

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

这个onchange事件捕获的条件比较苛刻,注意:

tabs

    tab-bar

        text

    tab-content

        div

以上组件都必须存在,且tab-bar中text的数量和tab-content中div的数量需一致。

或者也可以在text上通过onclick绑定事件,就没有以上的严苛触发条件。

<div class="container">
    <tabs class="tabs" index="0" vertical="false">
        <tab-bar mode="scrollable">
            <block for="{{ tabBar }}">
                <text onclick="clickTab($idx)">
                    {{ $item.name }}
                </text>
            </block>
        </tab-bar>
        ......
import prompt from '@system.prompt';
export default {
    data: {
        tabBar: [......]
    },
    clickTab(idx) {
        prompt.showToast({
            message: '你点击了第' + idx + '项。'
        })
    }
}

 

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

当然,弊端也很明显。tab-bar文字下的蓝色线条并没有跟随移动,tab-content也没有随之改变,只是事件可以捕获到。这种用法适用于只希望保留tab-bar的部分,自定义动态样式,可以省略tab-content以及其中的div。哪一种方式更好,还得看需求。

3、tabs实现的每日新闻

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻

这里运用了整套tabs组件,从聚合数据新闻头条接口(https://www.juhe.cn/docs/api/id/235)请求数据,实现了一个简单的每日新闻模块。因为鸿蒙的页面布局如果高度超过手机总高度就会有滑动效果,tab-bar和自定义的底部菜单都是固定的,因此也用不着list组件了。代码如下:

hml:

        <!-- 每日新闻 -->
        <div>
            <tabs class="newsTabs" onchange="changeNewsType">
                <tab-bar>
                    <block for="{{ newsTitles }}">
                        <text>
                            <span>{{ $item.name }}</span>
                        </text>
                    </block>
                </tab-bar>
                <tab-content>
                    <block for="{{ newsTitles }}">
                        <div class="newsView">
                            <block for="{{ newsList }}">
                                <div class="newsItem">
                                    <image src="{{ $item.thumbnail_pic_s }}" class="newsImg"></image>
                                    <div class="newsContent">
                                        <text>
                                            {{ $item.title }}
                                        </text>
                                        <div class="newsDesc">
                                            <text>
                                                {{ $item.author_name }}
                                            </text>
                                            <text>
                                                {{ $item.date }}
                                            </text>
                                        </div>
                                    </div>
                                </div>
                            </block>
                        </div>
                    </block>
                </tab-content>
            </tabs>
        </div>
        <!-- 每日新闻end -->

css:

/*每日新闻*/
.newsTabs {
    width: 100%;
    height: 100%;
}
.newsView {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
}
.newsItem {
    width: 100%;
    height: 240px;
    border-bottom: 1px solid #bbbbbb;
    display: flex;
    align-items: center;
}
.newsImg {
    margin-left: 20px;
    width: 200px;
    height: 200px;
}
.newsContent {
    display: flex;
    flex-direction: column;
    margin-right: 20px;
    margin-left: 20px;
}
.newsContent>text {
    margin-top: 20px;
    height: 140px;
    font-size: 34px;
    color: #333333;
}
.newsDesc {
    height: 60px;
    line-height: 60px;
    display: flex;
    justify-content: space-between;
}
.newsDesc>text {
    font-size: 28px;
    color: #777777;
}

js:

    data: {
        newsTitles: [
            {
                name: '头条',
                value: 'top'
            },
            {
                name: '社会',
                value: 'shehui'
            },
            {
                name: '国内',
                value: 'guonei'
            },
            {
                name: '国际',
                value: 'guoji'
            },
            {
                name: '娱乐',
                value: 'yule'
            },
            {
                name: '体育',
                value: 'tiyu'
            },
            {
                name: '军事',
                value: 'junshi'
            },
            {
                name: '科技',
                value: 'keji'
            },
            {
                name: '财经',
                value: 'caijing'
            },
            {
                name: '时尚',
                value: 'shishang'
            }
        ],
        newsList: [],
    },
    changeNewsType(event) {
        let type = this.newsTitles[event.index].value;
        fetch.fetch({
            url: 'http://v.juhe.cn/toutiao/index?key=xxxxx&type=' + type,
            responseType: 'json',
            success: res => {
                let data = JSON.parse(res.data);
                this.newsList = data.result.data;
            }
        })
    },

作者:Chris.

想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部