百度智能小程序 信息流

2020-09-03 16:16 更新

feed 信息流

解釋: 信息流組件,可配置下拉刷新、列表加載、上滑加載功能,適用于列表信息展示,并可放置在頁面的任何部分;組件包含手勢下拉以及 api 調(diào)用兩種使用方式。在信息流列表頁中,可根據(jù)不同場景配置刷新形式:下拉刷新適用于在頁面中瀏覽過程中有內(nèi)容更新時,手動觸發(fā);自動刷新適用于返回頁面后有內(nèi)容更新時,自動觸發(fā)。也可在局部模塊配置刷新能力。詳情查看刷新加載

屬性說明

屬性名 類型 必填 默認值 說明
theme String 主題配置,默認淺色;深色主題請指定 dark 。
loadingHeight Number 64 加載、話術(shù)區(qū)域高度,會根據(jù)屏幕寬度適配,適配基于組件內(nèi)方法import {upx2dpx} from'@smt-ui/component/src/common/utils/px';(單位為 px)。
pullToRefresh Boolean false 是否開啟手勢下拉刷新;默認只能通過組件 api 調(diào)起。
lowerThreshold Number 150 觸發(fā) scrolltolower 事件的閾值(單位 px)。
text String 建議最多顯示 18 個漢字,超出內(nèi)容截斷 加載成功時的展示話術(shù)。
refresh EventHandle 手勢滑動觸發(fā)加載時,響應(yīng)該 onRefresh 事件;通過調(diào)用 api 加載,不會觸發(fā)該事件。
startRefresh EventHandle 手動調(diào)用該 api ,觸發(fā)加載。
stopRefresh EventHandle 手動調(diào)用該 api ,停止加載,并彈出加載提示(對應(yīng)屬性 text);可使用 await 等待關(guān)閉動畫結(jié)束。
closeLoading EventHandle 手動調(diào)用該 api ,立即關(guān)閉加載,不彈出加載提示;例如接口異常,建義直接關(guān)閉加載(小球交替一次大約為 500ms ,調(diào)用前可加延時避免關(guān)閉太快)。
smt-feed-container externalClass 組件整體 class 名
smt-feed-loading externalClass 加載區(qū)域 class 名
smt-feed-content externalClass false 滾動區(qū)域 class 名,用于設(shè)置 ios 回彈背景。
smt-refresh-circle-left externalClass 加載中左側(cè)小球 class 名
smt-refresh-circle-right externalClass 加載中右側(cè)小球 class 名
ext-cls-content externalClass 滾動區(qū)域 class 名
smt-refresh-result-container externalClass 加載話術(shù)外框 class 名
ext-cls-result-text externalClass 加載話術(shù)文字 class 名

示例 

在開發(fā)者工具中打開


代碼示例 1:下拉刷新

<smt-feed
    class="smt-feed pull-down-refresh"
    pull-to-refresh
    bind:refresh="onRefresh"
    bind:scrolltolower="scrollToLower"
    text="{{PullText}}"
>
    <view class="list">
        <view class="{{'list-item ' + (val === 1 ? 'first' : '')}}"
            s-for="val in list"
            style="border-bottom: solid 1px #e0e0e0;"
            key="{{val}}"
        >
            <view class="left">
                <view class="row begin"></view>
                <view class="row center"></view>
                <view class="row end"></view>
            </view>
            <view class="right"></view>
        </view>
    </view>
    <smt-spin status="{{status}}" bind:tap="reload"></smt-spin>
</smt-feed>
{
    "component": true,
    "usingComponents": {
        "smt-feed": "@smt-ui/component/src/feed",
        "smt-spin": "@smt-ui/component/src/spin"
    }
}
import {selComponent, syncSetData} from '@smt-ui/component/src/common/utils';

Component({
    properties: {
        first: {
            type: Boolean,
            value: true
        }
    },

    data: {
        status: 1,
        text: '不超過18個字',
        list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
        count: 0
    },

    methods: {
        fetchData(ms = 1200) {
            const data = {
                code: 0,
                data: Array.from({length: Math.random() * 10 + 10 | 0}, (_, i) => i)
            };
            return new Promise(r => setTimeout(() => r(data), ms));
        },
        async previewRefresh() {
            const refresh = await selComponent(this, '.pull-down-refresh');
            refresh.startRefresh();
            const {data: list} = await this.fetchData();
            await new Promise(r => setTimeout(r, 300));
            await syncSetData(this, {
                status: 1,
                list: list || this.data.list,
                text: list ? `為你推薦${list.length}條更新` : '暫時沒有更新,休息一下'
            });
            refresh.stopRefresh();
        },

        async onRefresh() {
            const refresh = await selComponent(this, '.pull-down-refresh');
            const {data: list} = await this.fetchData();
            await new Promise(r => setTimeout(r, 300));
            await syncSetData(this, {
                status: 1,
                count: 0,
                list: list || this.data.list,
                text: list ? `為你推薦${list.length}條更新` : '暫時沒有更新,休息一下'
            });
            refresh.stopRefresh();
        },

        async scrollToLower() {
            const {data: list} = await this.fetchData();
            const fail = this.data.count === 3;
            const end = this.data.count === 5;
            if (fail || end) {
                this.setData({
                    status: fail ? 3 : 2
                });
                return;
            }
            await syncSetData(this, {
                list: list.concat(this.data.list || []),
                count: ++this.data.count
            });
        },

        async reload() {
            if (this.data.status !== 0 && this.data.status !== 3) {
                return;
            }
            await syncSetData(this, {status: 1, count: ++this.data.count});
            this.scrollToLower();
        }
    },

    ready() {
        this.data.first && this.previewRefresh();
        this.triggerEvent('previewend');
    }
});
.smt-feed {
    height: 100%;
    display: block;
    background: #fff;
}

.feed-container {
    box-sizing: border-box;
    height: calc(100vh - 0.65rem);
}
.list-item {
    background: #eee;
    height: 60.39rpx;
    margin-bottom: 12.08rpx;
}

代碼示例 2:自動刷新

<smt-feed
    class="smt-feed auto-refresh"
    text="{{text}}"
>
    <view class="list">
        <view class="{{'list-item ' + (val === 1 ? 'first' : '')}}"
            s-for="val in list"
            style="border-bottom: solid 1px #e0e0e0;"
            key="{{val}}"
        >
            <view class="left">
                <view class="row begin"></view>
                <view class="row center"></view>
                <view class="row end"></view>
            </view>
            <view class="right"></view>
        </view>
    </view>
    <smt-spin
        status="{{status}}"
        bind:tap="clickToLoad"
    >
    </smt-spin>
</smt-feed>
{
    "component": true,
    "usingComponents": {
        "smt-feed": "@smt-ui/component/src/feed",
        "smt-spin": "@smt-ui/component/src/spin"
    }
}
import {selComponent, syncSetData} from '@smt-ui/component/src/common/utils';

Component({
    data: {
        status: 1,
        text: '不超過18個字',
        list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
        count: 0
    },

    methods: {
        fetchData(ms = 1200) {
            const data = {
                code: 0,
                data: Array.from({length: Math.random() * 10 + 10 | 0}, (_, i) => i)
            };
            return new Promise(r => setTimeout(() => r(data), ms));
        },
        async autoRefresh() {
            const clkRefresh = await selComponent(this, '.auto-refresh');
            const autoLoad = async () => {
                clkRefresh.startRefresh();
                const {code, data: list} = await this.fetchData();
                if (code !== 0) {
                    swan.showToast({title: '網(wǎng)絡(luò)錯誤', mask: true, icon: 'none'});
                    clkRefresh.closeLoading();
                    return;
                }
                await new Promise(r => setTimeout(r, 300));
                await syncSetData(this, {
                    status: 0,
                    list: list || this.data.list,
                    text: list ? `為你推薦${list.length}條更新` : '暫時沒有更新,休息一下'
                });
                await clkRefresh.stopRefresh();
                await new Promise(r => setTimeout(r, 500)); // 加載完一輪等500ms
            };
            autoLoad();
        },

        async clickToLoad() {
            if (this.data.status === 2) {
                return;
            }
            await syncSetData(this, {status: 1});
            const {data: list} = await this.fetchData();
            await new Promise(r => setTimeout(r, 300));
            const fail = this.data.count === 3;
            const end = this.data.count === 5;
            if (fail || end) {
                this.setData({
                    count: ++this.data.count,
                    status: fail ? 3 : 2
                });
                return;
            }
            await syncSetData(this, {
                list: list.concat(this.data.list || []),
                status: 0,
                count: ++this.data.count
            });
        }
    },

    ready() {
        this.autoRefresh();
    }
});
.smt-feed {
    height: 100%;
    display: block;
    background: #fff;
}

.feed-container {
    box-sizing: border-box;
    height: calc(100vh - 0.65rem);
}
.list-item {
    background: #eee;
    height: 60.39rpx;
    margin-bottom: 12.08rpx;
}

代碼示例 3:局部刷新

<view class="placeholder"></view>
<smt-feed
    class="smt-feed pull-down-refresh"
    pull-to-refresh
    bind:refresh="onRefresh"
    bind:scrolltolower="scrollToLower"
    text="{{text}}"
>
    <view class="list">
        <view class="{{'list-item ' + (val === 1 ? 'first' : '')}}"
            s-for="val in list"
            style="border-bottom: solid 1px #e0e0e0;"
            key="{{val}}"
        >
            <view class="left">
                <view class="row begin"></view>
                <view class="row center"></view>
                <view class="row end"></view>
            </view>
            <view class="right"></view>
        </view>
    </view>
    <smt-spin status="{{status}}" bind:tap="reload"></smt-spin>
</smt-feed>
{
    "component": true,
    "usingComponents": {
        "smt-feed": "@smt-ui/component/src/feed",
        "smt-spin": "@smt-ui/component/src/spin"
    }
}
import {selComponent, syncSetData} from '@smt-ui/component/src/common/utils';

Component({
    properties: {
        first: {
            type: Boolean,
            value: true
        }
    },

    data: {
        status: 1,
        text: '不超過18個字',
        list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
        count: 0
    },

    methods: {
        fetchData(ms = 1200) {
            const data = {
                code: 0,
                data: Array.from({length: Math.random() * 10 + 10 | 0}, (_, i) => i)
            };
            return new Promise(r => setTimeout(() => r(data), ms));
        },
        async previewRefresh() {
            const refresh = await selComponent(this, '.pull-down-refresh');
            refresh.startRefresh();
            const {data: list} = await this.fetchData();
            await new Promise(r => setTimeout(r, 300));
            await syncSetData(this, {
                status: 1,
                list: list || this.data.list,
                text: list ? `為你推薦${list.length}條更新` : '暫時沒有更新,休息一下'
            });
            refresh.stopRefresh();
        },

        async onRefresh() {
            const refresh = await selComponent(this, '.pull-down-refresh');
            const {code, data: list} = await this.fetchData();
            if (code !== 0) {
                swan.showToast({title: '網(wǎng)絡(luò)錯誤', mask: true, icon: 'none'});
                refresh.closeLoading();
                return;
            }
            await new Promise(r => setTimeout(r, 300));
            await syncSetData(this, {
                status: 1,
                count: 0,
                list: list || this.data.list,
                text: list ? `為你推薦${list.length}條更新` : '暫時沒有更新,休息一下'
            });
            refresh.stopRefresh();
        },

        async autoRefresh() {
            if (this.data.activeName === '自動刷新') {
                const clkRefresh = await selComponent(this, '.auto-refresh');
                const autoLoad = async () => {
                    clkRefresh.startRefresh();
                    const {code, data: list} = await this.fetchData();
                    if (code !== 0) {
                        swan.showToast({title: '網(wǎng)絡(luò)錯誤', mask: true, icon: 'none'});
                        clkRefresh.closeLoading();
                        return;
                    }
                    await syncSetData(this, {
                        status: 0,
                        list: list || this.data.list,
                        text: list ? `為你推薦${list.length}條更新` : '暫時沒有更新,休息一下'
                    });
                    await new Promise(r => setTimeout(r, 300)); // 1500ms 之后再關(guān)閉: 手動關(guān)閉不需要等小球轉(zhuǎn)3圈
                    await clkRefresh.stopRefresh();
                    await new Promise(r => setTimeout(r, 500)); // 加載完一輪等500ms
                    this.data.activeName === '自動刷新' && await autoLoad();
                };
                autoLoad();
            }
        },

        async scrollToLower() {
            const {data: list} = await this.fetchData();
            const fail = this.data.count === 3;
            const end = this.data.count === 5;
            if (fail || end) {
                this.setData({
                    status: fail ? 3 : 2
                });
                return;
            }
            await syncSetData(this, {
                list: list.concat(this.data.list || []),
                count: ++this.data.count
            });
        },

        async reload() {
            if (this.data.status !== 0 && this.data.status !== 3) {
                return;
            }
            await syncSetData(this, {status: 1, count: ++this.data.count});
            this.scrollToLower();
        }
    },

    ready() {
        this.data.first && this.previewRefresh();
        this.triggerEvent('previewend');
    }
});
.smt-feed {
    display: block;
    height: calc(100% - 1.52rem);
    background: #fff;
}

.feed-container {
    box-sizing: border-box;
    height: calc(100vh - 0.65rem);
}
.placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 1.52rem;
    padding: .1rem .17rem;
    background-color: #fff;
}

.placeholder::before {
    content: "";
    flex: 1;
    height: 100%;
    border-radius: .03rem;
    background-color: #e0e0e0;
}
.list-item {
    background: #eee;
    height: 60.39rpx;
    margin-bottom: 12.08rpx;
}

Bug&Tip

  • Tip:和 scroll-view 一樣,信息流組件作為局部滾動組件,必須在它的父級或本身指定高度。
  • Tip:當同時啟用下拉刷新和上滑加載且請求不穩(wěn)定時,可使用 CancelToken 取消先前的請求。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號