codecamp

百度智能小程序 信息流

feed 信息流

解释: 信息流组件,可配置下拉刷新、列表加载、上滑加载功能,适用于列表信息展示,并可放置在页面的任何部分;组件包含手势下拉以及 api 调用两种使用方式。在信息流列表页中,可根据不同场景配置刷新形式:下拉刷新适用于在页面中浏览过程中有内容更新时,手动触发;自动刷新适用于返回页面后有内容更新时,自动触发。也可在局部模块配置刷新能力。详情查看刷新加载

属性说明

属性名 类型 必填 默认值 说明
theme String 主题配置,默认浅色;深色主题请指定 dark 。
loadingHeight Number 64 加载、话术区域高度,会根据屏幕宽度适配,适配基于组件内方法import {upx2dpx} from'@smt-ui/component/src/common/utils/px';(单位为 px)。
pullToRefresh Boolean false 是否开启手势下拉刷新;默认只能通过组件 api 调起。
lowerThreshold Number 150 触发 scrolltolower 事件的阈值(单位 px)。
text String 建议最多显示 18 个汉字,超出内容截断 加载成功时的展示话术。
refresh EventHandle 手势滑动触发加载时,响应该 onRefresh 事件;通过调用 api 加载,不会触发该事件。
startRefresh EventHandle 手动调用该 api ,触发加载。
stopRefresh EventHandle 手动调用该 api ,停止加载,并弹出加载提示(对应属性 text);可使用 await 等待关闭动画结束。
closeLoading EventHandle 手动调用该 api ,立即关闭加载,不弹出加载提示;例如接口异常,建义直接关闭加载(小球交替一次大约为 500ms ,调用前可加延时避免关闭太快)。
smt-feed-container externalClass 组件整体 class 名
smt-feed-loading externalClass 加载区域 class 名
smt-feed-content externalClass false 滚动区域 class 名,用于设置 ios 回弹背景。
smt-refresh-circle-left externalClass 加载中左侧小球 class 名
smt-refresh-circle-right externalClass 加载中右侧小球 class 名
ext-cls-content externalClass 滚动区域 class 名
smt-refresh-result-container externalClass 加载话术外框 class 名
ext-cls-result-text externalClass 加载话术文字 class 名

示例 

在开发者工具中打开


代码示例 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: '网络错误', 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: '网络错误', 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: '网络错误', 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 之后再关闭: 手动关闭不需要等小球转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:当同时启用下拉刷新和上滑加载且请求不稳定时,可使用 CancelToken 取消先前的请求。


百度智能小程序 关注引导蒙层
百度智能小程序 信息流子项
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

百度智能小程序开发文档

百度智能小程序 组件

百度智能小程序 地图

百度智能小程序 画布

百度智能小程序 API

百度智能小程序 界面

百度智能小程序 关注小程序引导组件

百度智能小程序 自定义组件

百度智能小程序 媒体

百度智能小程序 设备

百度智能小程序 拨打电话

百度智能小程序 内存警报

百度智能小程序 手机联系人

百度智能小程序 用户截屏事件

百度智能小程序 第三方平台

百度智能小程序 开放接口

百度智能小程序 百度收银支付

百度智能小程序 分包预下载

百度智能小程序 数据分析

百度智能小程序 服务端

百度智能小程序 云开发

百度智能小程序 初始化

百度智能小程序 云函数

百度智能小程序 服务端初始化

百度智能小程序 服务器获取上下文

百度智能小程序 服务端云函数

百度智能小程序 开发教程

百度智能小程序 功能开发

百度智能小程序 基本原理

百度智能小程序 小程序自动化

百度智能小程序 视频教程

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }