從微信小程序到鴻蒙JS開發(fā)【04】-list組件
https://harmonyos.51cto.com/#zz
1、可滾動區(qū)域
在許多場景中,頁面會有一塊區(qū)域是可滾動的,比如這樣一個簡單的每日新聞模塊:


上面的新聞類型是一塊可橫向滾動的區(qū)域,下方新聞列表是一塊可豎向滾動的區(qū)域。在微信小程序中,使用scroll-view組件即可實現。那么在鴻蒙js組件中,想要實現可滾動的區(qū)域,則是使用list組件。list僅支持豎向滾動,橫向滾動要用tabs,將在下篇博客講解。
2、list + list-item
這里以本地新聞模塊為例,數據請求自天行數據接口(https://www.tianapi.com/apiview/154)。

上方為一個搜索框,下方是新聞列表。搜索框給了固定高度,那么怎樣讓新聞列表能夠占滿屏幕剩余部分呢?只需將父容器設置flex布局,list設置flex: 1即可。list下直接放list-item,在總高度超出list的高度后,即可上下滾動。
hml:
- <!-- 本地新聞 -->
- <div>
- <div class="searchView">
- <image src="{{ searchIcon }}"></image>
- <input placeholder="搜你想看的"></input>
- </div>
- <list class="localView">
- <block for="{{ localNews }}">
- <list-item class="newsItem">
- <div class="newsContent">
- <text>
- {{ $item.title }}
- </text>
- <div class="newsDesc">
- <text>
- {{ $item.source }}
- </text>
- <text>
- {{ $item.ctime }}
- </text>
- </div>
- </div>
- </list-item>
- </block>
- </list>
- </div>
- <!-- 本地新聞end -->
css:
- /*本地新聞*/
- .searchView {
- width: 100%;
- height: 140px;
- background-color: #f0f0f0;
- display: flex;
- align-items: center;
- }
- .searchView>image {
- margin: 0 40px 0 40px;
- height: 60px;
- width: 60px;
- }
- .searchView>input {
- margin-right: 40px;
- }
- .localView {
- width: 100%;
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- .localContent {
- margin-left: 20px;
- }
- .newsItem {
- width: 100%;
- height: 240px;
- border-bottom: 1px solid #bbbbbb;
- display: flex;
- align-items: center;
- }
- .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:
- searchLocalNews() {
- let url = 'http://api.tianapi.com/areanews/index?key=xxxx&areaname=江蘇';
- if (this.searchWord) {
- url = url + '&word' + this.searchWord;
- }
- fetch.fetch({
- url: url,
- responseType: 'json',
- success: res => {
- let data = JSON.parse(res.data);
- this.localNews = data.newslist;
- }
- })
- },
新聞列表可滾動,且不會影響搜索框的位置。

3、list + list-item-group + list-item
list組件的子元素還可以是list-item-group,顧名思義應是分組列表項,list-item作為list-item-group的子元素。隨便寫一點看一看:
- <div>
- <list class="manageList">
- <list-item-group class="list-item-group">
- <list-item class="list-item">
- <text>
- <span>分組1 子項1</span>
- </text>
- </list-item>
- <list-item class="list-item">
- <text>
- <span>分組1 子項2</span>
- </text>
- </list-item>
- <list-item class="list-item">
- <text>
- <span>分組1 子項3</span>
- </text>
- </list-item>
- </list-item-group>
- <list-item-group class="list-item-group">
- <list-item class="list-item">
- <text>
- <span>分組2 子項1</span>
- </text>
- </list-item>
- <list-item class="list-item">
- <text>
- <span>分組2 子項2</span>
- </text>
- </list-item>
- <list-item class="list-item">
- <text>
- <span>分組2 子項3</span>
- </text>
- </list-item>
- </list-item-group>
- </list>
- </div>
- .manageList{
- height: 100%;
- width: 100%;
- }
- .list-item-group{
- width: 100%;
- height: 450px;
- }
- .list-item{
- width: 100%;
- height: 150px;
- display: flex;
- justify-content: center;
- align-items: center;
- border-bottom: 1px solid gray;
- }
- .list-item>text{
- line-height: 100px;
- }
可以看出,list-item-group是可折疊的列表分組,且默認是折疊的。點擊右側小箭頭可展開列表,如果list-item-group給了高度,則折疊和展開后這一塊區(qū)域的高度不變。在折疊時,展示第一個list-item的內容。
那么如果每一個list-item-group中l(wèi)ist-item數目不固定,在展開后的布局就會很難看。如下:

其實不定義list-item-group的高度即可,折疊高度為list-item的高度,展開后高度自適應增長,超出list高度可以滾動,功能還是很強大的。更改css后的效果如下:

這種分組的列表,可以制作一個簡單的后臺管理系統(tǒng)菜單界面。這里我將菜單數據文件、圖片文件放入nginx服務器的目錄中,再通過內網穿透訪問資源。注意數據的格式,list-item-group和list-item之間存在父級標簽關系,故數據中也應存在父級關系。list-item-group展示的內容是其下第一個list-item,這里用一個兩重for循環(huán)實現:


manage.json:
- {
- "manageList": [
- {
- "name": "組織管理",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/org.png",
- "subList": [
- {
- "name": "查詢組織",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/search.png"
- },
- {
- "name": "添加組織",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/add.png"
- },
- {
- "name": "刪除組織",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/delete.png"
- }
- ]
- },
- {
- "name": "人員管理",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/person.png",
- "subList": [
- {
- "name": "查詢人員",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/search.png"
- },
- {
- "name": "添加人員",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/add.png"
- },
- {
- "name": "批量導入人員",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/add.png"
- },
- {
- "name": "刪除人員",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/delete.png"
- },
- {
- "name": "修改人員",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/update.png"
- }
- ]
- },
- {
- "name": "卡片管理",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/card.png",
- "subList": [
- {
- "name": "開卡",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/add.png"
- },
- {
- "name": "退卡",
- "icon": "http://milkytea.free.idcfengye.com/images/christools/icon/delete.png"
- }
- ]
- }
- ]
- }
hml:
- <!-- 管理 -->
- <div>
- <list class="manageList">
- <block for="{{ manageList }}">
- <list-item-group class="list-item-group">
- <list-item class="list-item">
- <image src="{{ $item.icon }}"></image>
- <text>{{ $item.name }}</text>
- </list-item>
- <block for="{{ (index, value) in $item.subList }}">
- <list-item class="list-item">
- <image src="{{ value.icon }}"></image>
- <text>{{ value.name }}</text>
- </list-item>
- </block>
- </list-item-group>
- </block>
- </list>
- </div>
- <!-- 管理end -->
js:
- getManageList() {
- let url = "http://milkytea.free.idcfengye.com/text/manage.json";
- fetch.fetch({
- url: url,
- responseType: 'json',
- success: res => {
- let data = JSON.parse(res.data);
- this.manageList = data.manageList;
- }
- })
- }
https://harmonyos.51cto.com/#zz