阅读(1556) (11)

百度智能小程序 一站式互动

2020-08-11 17:42:01 更新

one-stop-interaction 一站式互动组件

基础库 3.180.3 开始支持,低版本需做兼容处理

解释: 一站式互动组件,为开发者提供一整套包含评论发布器、评论列表及详情、点赞、收藏、转发功能的互动 bar 能力,互动 bar 支持自定义,此外还提供数据存储、数据内容审核、用户接收百度 APP 消息通知的一站式服务。

使用了原 smart-sc 动态库引入的方式,请迁移到如下新的动态库方式接入。

使用方法

  1. 在项目中声明引用 swan-interaction 动态库
    在 app.json 文件配置的 dynamicLib 字段中增加对 swan-interaction 的引用,具体格式在使用动态库文档中查看。
        "dynamicLib": {
            // 'myDynamicLib' 是个可自定义的别名。
            "myDynamicLib": {
                // provider 是要引用的动态库的名字,在此为 'swan-interaction'。
                "provider": "swan-interaction"
            }
        }
    
  2. 创建一个带评论功能的页面,并在页面中声明引用 comment-list 组件。
    动态库中的组件与其他自定义组件类似,都需要在 page 中使用。所以首先需要创建一个 page,page 路径可自定义,推荐路径为 pages/list/index(即在小程序页面目录 pages 下创建 list 文件夹,并在文件夹下创建 index.js、index.swan、index.css、index.json 页面文件)。
    页面中引用动态库组件的方式是:在页面的 json 配置的 usingSwanComponents 字段中声明组件引用。
    {
        "navigationBarTitleText": "评论列表",
        "usingSwanComponents": {
            "comment-list": "dynamicLib://myDynamicLib/comment-list"
        }
    }

    在页面中放入列表组件,传入必要的参数,组件详情配置请参考 comment-list 评论列表组件

    <view>
        <view class="article-header">
            <text class="title" selectable="true">{{header.title}}</text>
            <view class="source">
                <image s-if="!!header.avatar" src="{{header.avatar}}"/>
                <view class="info">
                    <text class="author">{{header.author}}</text>
                    <text class="time">{{header.time}}</text>
                </view>
            </view>
        </view>
        <view class="article-content">
            <block s-for="{{content.items}}" s-for-index="eleIndex">
                <block s-if="{{item.type === 'text'}}">
                    <view class="content-p" data-index="{{eleIndex}}">
                        <text selectable="true">{{item.data}}</text>
                    </view>
                </block>
                <block s-elif="{{item.type === 'image'}}">
                    <image
                        class="content-img"
                        src="{{item.data.src}}"
                        original-src="{{item.data.src}}"
                        mode="widthFix"
                        preview="true"
                        lazy-load="true"/>
                </block>
            </block>
        </view>
        <view>欢迎使用智能小程序动态库
        欢迎使用智能小程序动态库
        欢迎使用智能小程序动态库</view>
        <image src="https://b.bdstatic.com/miniapp/images/demo-dog.png" rel="external nofollow"  rel="external nofollow" 
            class="img"></image>
        <view>欢迎使用智能小程序动态库
        欢迎使用智能小程序动态库
        欢迎使用智能小程序动态库</view>
    
        <!-- 评论列表组件 -->
        <comment-list class="list"
            comment-param="{{commentParam}}"
            detail-path="{{detailPath}}"
            toolbar-config="{{toolbarConfig}}"
            bindclickcomment="clickComment"
            bindunlogin="triggerLogin"
        ></comment-list>
    </view>
    Page({
        data: {
            commentParam: {},
            header: {
                title: '心疼!中国自行车女将卷入摔车事故 腹部扎入3厘米木刺坚持完赛',
                avatar: 'https://b.bdstatic.com/miniapp/images/demo-dog.png',
                author: '百度智能小程序',
                time: '2020年04月14日'
            },
            content: {
                items: [
                    {
                        type: 'text',
                        data: '测试文字'
                    }
                ]
            },
            detailPath: '/pages/detail/index?params1=abd',
            // 底部互动 bar 的配置
            toolbarConfig: {
                // 若 moduleList 中配置有 share 模块,默认是有,则该属性为必填,title 必传
                share: {
                    title: '心疼!中国自行车女将卷入摔车事故 腹部扎入3厘米木刺坚持完赛'
                }
            }
        },
    
        onLoad(query) {
            this.setData({
                commentParam: {
                    snid: '10070000311753961',
                    path: '/pages/comment/index?snid=test_snid57',
                    title: '测试文章标题',
                    content: '测试文章内容',
                    images: ['https://b.bdstatic.com/miniapp/images/demo-dog.png']
                }
            });
        },
    
        onReady() {
            // 用于实现页面间的跳转
            requireDynamicLib('myDynamicLib').listenEvent();
        },
    
        clickComment(e) {
        },
    
        triggerLogin(e) {
            swan.login({
                success: res => {
                    swan.request({
                        url: 'https://spapi.baidu.com/oauth/jscode2sessionkey',
                        method: 'POST',
                        header: {
                            'content-type': 'application/x-www-form-urlencoded'
                        },
                        data: {
                            code: res.code,
                            'client_id': '', // AppKey
                            sk: '' // AppSecret
                        },
                        success: res => {
                            if (res.statusCode === 200) {
                                const commentParam = this.data.commentParam;
                                this.setData({
                                    commentParam: {
                                        ...commentParam,
                                        openid: res.data.openid
                                    }
                                }, () => {
                                    // 我们建议将参数设为全局变量,方便取用
                                    getApp().globalData.commentParam = this.data.commentParam;
                                });
                            }
                        }
                    });
                }
            });
        }
    });
    .article-header {
        padding: 0 17px;
    }
    
    .article-header .title {
        display: block;
        font-size: 24px;
        line-height: 1.5;
        font-weight: 700;
    }
    
    .article-header .source {
        margin-top: 24px;
        display: flex;
        align-items: flex-start;
    }
    
    .article-header .source image {
        width: 35px;
        height: 35px;
        border-radius: 100%;
        margin-right: 8px;
        background-color: #eef1f4;
        background-size: 16px 16px;
        background-repeat: no-repeat;
        background-position: center center;
        background-image: url(../common/assets/logo-default.png);
    }
    
    .article-header .info {
        display: flex;
        flex-direction: column;
        justify-content: center;
        height: 35px;
    }
    
    .article-header .info .author {
        font-size: 16px;
        line-height: 1;
        display: block;
        color: #000;
        margin-bottom: 7px;
    }
    
    .article-header .info .time {
        display: block;
        color: #999;
        font-size: 12px;
        line-height: 1;
    }
    
    .article-content {
        color: #000;
        font-size: 19px;
        line-height: 1.58;
        letter-spacing: 2.84;
        margin-bottom: 30px;
    }
    
    .article-content .content-img {
        width: 100%;
        margin-top: 30px;
        vertical-align: bottom;
        background-color: #eef1f4;
        background-size: 32px 32px;
        background-repeat: no-repeat;
        background-position: center center;
        background-image: url(../common/assets/logo-default.png);
    }
    
    .article-content .content-p {
        margin: 24.5px 17px -5.5px 17px;
        text-align: justify;
        word-break: break-all;
    }
    
  3. 创建一个评论详情页面,并在页面中声明引用 comment-detail 组件。
    动态库中的组件与其他自定义组件类似,都需要在 page 中使用。所以首先需要创建一个 page,page 路径可自定义,推荐路径为 pages/detail/index(即在小程序页面目录 pages 下创建 detail 文件夹,并在文件夹下创建 index.js、index.swan、index.css、index.json 页面文件)。

    页面中引用动态库组件的方式是:在页面的 json 配置的 usingSwanComponents 字段中声明组件引用。

    {
        "navigationBarTitleText": "评论详情",
        "usingSwanComponents": {
            "comment-detail": "dynamicLib://myDynamicLib/comment-detail"
        }
    }
    在页面中放入详情组件,传入必要的参数,组件详情配置请参考 comment-list 评论列表组件。       
    <comment-detail
        comment-param="{{commentParam}}"
        srid="{{srid}}"
        need-like-btn="{{true}}"
        binddelete="detailDelete"
        bindunlogin="triggerLogin"
    ></comment-detail>
    Page({
        data: {
            srid: '',
            commentParam: {}
        },
        onLoad(options) {
            if (options) {
                this.setData({
                    srid: options.srid
                });
            }
    
            const param = getApp().globalData.commentParam;
    
            if (param && Object.keys(param).length) {
                this.setData({
                    'commentParam': param
                });
            }
            else {
                this.setData({
                    commentParam: {
                        snid: '10070000311753961',
                        path: '/pages/comment/index?snid=test_snid57',
                        title: '测试文章标题'
                    }
                });
            }
        },
        triggerLogin(e) {
            swan.login({
                success: res => {
                    swan.request({
                        url: 'https://spapi.baidu.com/oauth/jscode2sessionkey',
                        method: 'POST',
                        header: {
                            'content-type': 'application/x-www-form-urlencoded'
                        },
                        data: {
                            code: res.code,
                            'client_id': '', // AppKey
                            sk: '' // AppSecret
                        },
                        success: res => {
                            if (res.statusCode === 200) {
                                const commentParam = this.data.commentParam;
                                this.setData({
                                    commentParam: {
                                        ...commentParam,
                                        openid: res.data.openid
                                    }
                                }, () => {
                                    // 我们建议将参数设为全局变量,方便取用
                                    getApp().globalData.commentParam = this.data.commentParam;
                                });
                            }
                        }
                    });
                }
            });
        }
    });
    

图片示例

评论列表支持折叠

对于部分开发者,在评论列表下方希望放入广告等推荐区域,故评论列表支持折叠使用。使用方法如下:

  1. 创建一个带评论功能的页面,并在页面中声明引用 comment-list 组件。
    在页面中放入列表组件,传入必要的可折叠参数,组件详情配置请参考 comment-list 评论列表组件
    <view>
        <view class="article-header">
            <text class="title" selectable="true">{{header.title}}</text>
            <view class="source">
                <image s-if="!!header.avatar" src="{{header.avatar}}"/>
                <view class="info">
                    <text class="author">{{header.author}}</text>
                    <text class="time">{{header.time}}</text>
                </view>
            </view>
        </view>
    
        <view class="article-content">
            <block s-for="{{content.items}}" s-for-index="eleIndex">
                <block s-if="{{item.type === 'text'}}">
                    <view class="content-p" data-index="{{eleIndex}}">
                        <text selectable="true">{{item.data}}</text>
                    </view>
                </block>
                <block s-elif="{{item.type === 'image'}}">
                    <image
                        class="content-img"
                        src="{{item.data.src}}"
                        original-src="{{item.data.src}}"
                        mode="widthFix"
                        preview="true"
                        lazy-load="true"/>
                </block>
            </block>
        </view>
    
        <!-- 评论列表支持折叠 -->
        <comment-list class="list"
            comment-param="{{commentParam}}"
            detail-path="{{detailPath}}"
            is-folded="{{true}}"
            fold-num="{{foldNum}}"
            toolbar-config="{{toolbarConfig}}"
            view-more-path="{{viewMorePath}}"
            bindclickcomment="clickComment"
            bindunlogin="triggerLogin"
            bindviewmore="viewMore"
        ></comment-list>
        <div class="comment-list-folded-bottom-margin"></div>
    
        <view class="list-after">
            <view>欢迎使用智能小程序动态库
            欢迎使用智能小程序动态库
            欢迎使用智能小程序动态库</view>
            <image src="https://b.bdstatic.com/miniapp/images/demo-dog.png" rel="external nofollow"  rel="external nofollow" 
                class="img"></image>
            <view>欢迎使用智能小程序动态库
            欢迎使用智能小程序动态库
            欢迎使用智能小程序动态库</view>
        </view>
    </view>
    Page({
        data: {
            commentParam: {},
            header: {
                title: '心疼!中国自行车女将卷入摔车事故 腹部扎入3厘米木刺坚持完赛',
                avatar: 'https://b.bdstatic.com/miniapp/images/demo-dog.png',
                author: '百度智能小程序',
                time: '2020年04月14日'
            },
            content: {
                items: [
                    {
                        type: 'image',
                        data: {
                            src: 'https://b.bdstatic.com/miniapp/images/demo-dog.png'
                        }
                    },
                    {
                        type: 'text',
                        data: '测试文字'
                    }
                ]
            },
            // 评论详情页面路径
            detailPath: '/pages/detail/index?params1=abd',
            // 全部评论页面路径
            viewMorePath: '/pages/all-list/index',
            // 折叠展示最大评论条数
            foldNum: 5.
            // 底部互动 bar 的配置
            toolbarConfig: {
                // 若 moduleList 中配置有 share 模块,默认是有,则该属性为必填,title 必传
                share: {
                    title: '心疼!中国自行车女将卷入摔车事故 腹部扎入3厘米木刺坚持完赛'
                }
            }
        },
    
        onLoad(query) {
            this.setData({
                commentParam: {
                    snid: '10070000311753961',
                    path: '/pages/comment/index?snid=test_snid57',
                    title: '测试文章标题',
                    content: '测试文章内容',
                    images: ['https://b.bdstatic.com/miniapp/images/demo-dog.png']
                }
            });
        },
    
        onReady() {
            // 用于实现页面间的跳转
            requireDynamicLib('myDynamicLib').listenEvent();
        },
    
        triggerLogin(e) {
            swan.login({
                success: res => {
                    swan.request({
                        url: 'https://spapi.baidu.com/oauth/jscode2sessionkey',
                        method: 'POST',
                        header: {
                            'content-type': 'application/x-www-form-urlencoded'
                        },
                        data: {
                            code: res.code,
                            'client_id': '', // AppKey
                            sk: '' // AppSecret
                        },
                        success: res => {
                            if (res.statusCode === 200) {
                                const commentParam = this.data.commentParam;
                                this.setData({
                                    commentParam: {
                                        ...commentParam,
                                        openid: res.data.openid
                                    }
                                }, () => {
                                    getApp().globalData.commentParam = this.data.commentParam;
                                });
                            }
                        }
                    });
                }
            });
        },
    
        clickComment(e) {
        },
    
        viewMore() {
            swan.showToast({
                title: 'click success'
            });
        }
    });
    {
        "navigationBarTitleText": "折叠列表页",
        "usingSwanComponents": {
            "comment-list": "dynamicLib://myDynamicLib/comment-list"
        }
    }
    .article-header {
        padding: 0 39.8rpx;
    }
    
    .article-header .title {
        display: block;
        font-size: 56rpx;
        line-height: 1.5;
        font-weight: 700;
    }
    
    .article-header .source {
        margin-top: 56rpx;
        display: flex;
        align-items: flex-start;
    }
    
    .article-header .source image {
        width: 82rpx;
        height: 82rpx;
        border-radius: 100%;
        margin-right: 18.7rpx;
        background-color: #eef1f4;
        background-size: 37.4rpx 37.4rpx;
        background-repeat: no-repeat;
        background-position: center center;
        background-image: url(../common/assets/logo-default.png);
    }
    
    .article-header .info {
        display: flex;
        flex-direction: column;
        justify-content: center;
        height: 82rpx;
    }
    
    .article-header .info .author {
        font-size: 37.4rpx;
        line-height: 1;
        display: block;
        color: #000;
        margin-bottom: 16.4rpx;
    }
    
    .article-header .info .time {
        display: block;
        color: #999;
        font-size: 28rpx;
        line-height: 1;
    }
    
    .article-content {
        color: #000;
        font-size: 44.5rpx;
        line-height: 1.58;
        letter-spacing: 2.84;
        margin-bottom: 70.2rpx;
    }
    
    .article-content .content-img {
        width: 100%;
        margin-top: 70.2rpx;
        vertical-align: bottom;
        background-color: #eef1f4;
        background-size: 74.9rpx 74.9rpx;
        background-repeat: no-repeat;
        background-position: center center;
        background-image: url(../common/assets/logo-default.png);
    }
    
    .article-content .content-p {
        margin: 57.3rpx 39.8rpx -12.9rpx 39.8rpx;
        text-align: justify;
        word-break: break-all;
    }
    
    .list-after {
        padding: 30rpx 18rpx 90rpx;
    }
    
    .comment-list-folded-bottom-margin {
        height: 14.4rpx;
        background-color: #f5f5f5;
    }
  2. 创建一个展示全部评论的页面,并在页面中声明引用 comment-list 组件。
    我们建议全部评论的页面,互动 bar 仅保留评论发布。组件配置请参考 comment-list 评论列表组件
    <comment-list
        comment-param="{{commentParam}}"
        detail-path="{{detailPath}}"
        toolbar-config="{{toolbarConfig}}"
        bindclickcomment="clickComment"
        bindunlogin="triggerLogin"
    ></comment-list>
    Page({
        data: {
            commentParam: {},
            toolbarConfig: {
                moduleList: []
            },
            detailPath: '/pages/detail/index?params1=abd'
        },
    
        onInit() {
            this.isOnInitCalled = true;
            this.init();
        },
    
        onLoad() {
            // 兼容不支持 onInit 的版本
            if (!this.isOnInitCalled) {
                this.init();
            }
        },
    
        init() {
            const commentParam = getApp().globalData.commentParam;
            if (commentParam && Object.keys(commentParam).length) {
                this.setData({
                    commentParam
                });
            }
            else {
                this.setData({
                    commentParam: {
                        snid: '10070000311753961',
                        path: '/pages/comment/index?snid=test_snid57',
                        title: '测试文章标题'
                    }
                });
    
            }
        },
    
        onReady() {
            // 用于实现页面间的跳转
            requireDynamicLib('myDynamicLib').listenEvent();
        },
    
        triggerLogin(e) {
            swan.login({
                success: res => {
                    swan.request({
                        url: 'https://spapi.baidu.com/oauth/jscode2sessionkey',
                        method: 'POST',
                        header: {
                            'content-type': 'application/x-www-form-urlencoded'
                        },
                        data: {
                            code: res.code,
                            'client_id': '', // AppKey
                            sk: '' // AppSecret
                        },
                        success: res => {
                            if (res.statusCode === 200) {
                                const commentParam = this.data.commentParam;
                                this.setData({
                                    commentParam: {
                                        ...commentParam,
                                        openid: res.data.openid
                                    }
                                }, () => {
                                    getApp().globalData.commentParam = this.data.commentParam;
                                });
                            }
                        }
                    });
                }
            });
        },
    
        clickComment(e) {
        }
    });
    {
        "navigationBarTitleText": "全部评论",
        "usingSwanComponents": {
            "comment-list": "dynamicLib://myDynamicLib/comment-list"
        }
    }
  3. 创建一个评论详情页面,并在页面中声明引用 comment-detail 组件。

Bug&Tip

  • Tip:使用 Mars 等第三方框架开发小程序时,可能存在 setData 的异步延时,如在评论详情页 srid 作为单独参数传入没有生效,可作为 commentParam 中的字段传入。
  • Tip: 原有一站式互动组件 smart-sc 因性能问题,对用户流量产生影响,为避免影响线上已接入用户,本次新的一站式互动组件采用新的动态库。
  • Tip:原有一站式互动组件的部分 bug,如点赞状态失效等,已在新一站式组件中修复。
  • Tip:新的一站式互动组件,通用性更强,除了页面级别,也支持浮层的使用。
  • Tip: 在 onLoad 和 onReady 生命周期内引入 requireDynamicLib(‘myDynamicLib’).listenEvent() 来实现页面的跳转。