萧潇墨 2018-08-28 02:42 采纳率: 75%
浏览 3958
已采纳

今日头条小程序版是怎么开发出来的

今天看来下今日头条版的小程序,不知道他们是怎么开发出来的,感觉不是原生的纯小程序开发,应该是用了什么框架,有没有知道?

  • 写回答

2条回答

  • sunny_pei 2018-08-28 03:16
    关注

    今日头条App的Topbar是一个典型的频道管理和切换组件,在微信小程序上也实现了类似的效果。

    我们先看具体效果好了 ↓↓↓

    wx-topbar-1

    wx-topbar-2

    wx-topbar-3

    这个项目(wx-topbar)已经放在GitHub上了——点此前往,欢迎学习交流。

    接下来,简要说一下实现思路。

    先看视图层,Topbar横向滚动对应的WXML代码如下:



    {{ navbarArray[item].text }}


    空白







    scroll-view负责Topbar中各个频道的呈现,所有频道的相关数据都存储在navbarArray这个对象数组里,而数组navbarShowIndexArray里存储了要显示频道在数组navbarArray中的索引。

    不难猜测,频道是否选中高亮,与数组navbarArray有关;频道是否显示,与数组navbarShowIndexArray有关。

    点击某个频道名称,就会触发对应频道的切换操作。

    view.navbar-arrow-down对应的是右上角的向下箭头,可采用fixed定位类型,点击后弹出管理频道的Modal.



    显示频道





    {{ navbarArray[item].text }}

    上移



    隐藏频道





    {{ navbarArray[item].text }}

    上移



    在这个管理频道的Modal里,通过改变数组navbarShowIndexArray来控制频道是否显示和显示顺序,同时,需要另外一个数组navbarHideIndexArray来存储隐藏的频道。

    Modal显示的时候,Topbar需要被另一个写有“频道设置”字样的Bar覆盖。


    频道设置




    然后,我们来看逻辑层的实现。初始化的部分data如下:

    data: {
    navbarArray: [{
    text: '推荐',
    type: 'navbar-item-active'
    }, {
    text: '热点',
    type: ''
    }, {
    text: '视频',
    type: ''
    }, {
    text: '图片',
    type: ''
    }, {
    text: '段子',
    type: ''
    }, {
    text: '社会',
    type: ''
    }, {
    text: '娱乐',
    type: ''
    }, {
    text: '科技',
    type: ''
    }, {
    text: '体育',
    type: ''
    }, {
    text: '汽车',
    type: ''
    }, {
    text: '财经',
    type: ''
    }, {
    text: '搞笑',
    type: ''
    }],
    navbarShowIndexArray: Array.from(Array(12).keys()),
    navbarHideIndexArray: [],
    channelSettingShow: '',
    channelSettingModalShow: '',
    channelSettingModalHide: true
    }
    navbar-item-active是一个可使频道高亮的Class,navbarShowIndexArray初始化的结果是一个0到11的数组,刚好是数组navbarArray的所有元素的索引。显然,初始化的结果是所有频道都将显示。

    为了实现频道个性化配置的保存,navbarShowIndexArray还需要通过小程序的数据缓存API储存起来。

    storeNavbarShowIndexArray: function() {
    wx.setStorage({
    key: 'navbarShowIndexArray',
    data: this.data.navbarShowIndexArray
    });
    }
    切换频道的函数如下:

    switchChannel: function(targetChannelIndex) {
    this.getArticles(targetChannelIndex);

    let navbarArray = this.data.navbarArray;
    navbarArray.forEach((item, index, array) => {
        item.type = '';
        if (index === targetChannelIndex) {
            item.type = 'navbar-item-active';
        }
    });
    this.setData({
        navbarArray: navbarArray,
        currentChannelIndex: targetChannelIndex
    });
    

    }
    这样,频道的管理和简单切换我们就实现了。

    但是,到此为止,频道的切换只能通过点击对应Topbar中频道那一小块区域来实现,要是在正文区域左滑和右滑也能切换频道就好了。

    一个容易想到的思路是,在正文区域绑定touch事件,通过坐标判断滑动方向,然后使Topbar中当前频道的上一个或下一个频道高亮,同时,控制Topbar横向滚动合适的偏移长度,以确保切换后的频道能出现在视图区域。

    onTouchstartArticles: function(e) {
    this.setData({
    'startTouchs.x': e.changedTouches[0].clientX,
    'startTouchs.y': e.changedTouches[0].clientY
    });
    },
    onTouchendArticles: function(e) {
    let deltaX = e.changedTouches[0].clientX - this.data.startTouchs.x;
    let deltaY = e.changedTouches[0].clientY - this.data.startTouchs.y;
    if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {
    let deltaNavbarIndex = deltaX > 0 ? -1 : 1;
    let currentChannelIndex = this.data.currentChannelIndex;
    let navbarShowIndexArray = this.data.navbarShowIndexArray;
    let targetChannelIndexOfNavbarShowIndexArray = navbarShowIndexArray.indexOf(currentChannelIndex) + deltaNavbarIndex;
    let navbarShowIndexArrayLength = navbarShowIndexArray.length;
    if (targetChannelIndexOfNavbarShowIndexArray >= 0 && targetChannelIndexOfNavbarShowIndexArray <= navbarShowIndexArrayLength - 1) {
    let targetChannelIndex = navbarShowIndexArray[targetChannelIndexOfNavbarShowIndexArray];
    if (navbarShowIndexArrayLength > 6) {
    let scrollNavbarLeft;
    if (targetChannelIndexOfNavbarShowIndexArray < 5) {
    scrollNavbarLeft = 0;
    } else if (targetChannelIndexOfNavbarShowIndexArray === navbarShowIndexArrayLength - 1) {
    scrollNavbarLeft = this.rpx2px(110 * (navbarShowIndexArrayLength - 6));
    } else {
    scrollNavbarLeft = this.rpx2px(110 * (targetChannelIndexOfNavbarShowIndexArray - 4));
    }
    this.setData({
    scrollNavbarLeft: scrollNavbarLeft
    });
    }
    this.switchChannel(targetChannelIndex);
    }
    }
    }

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?