V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
coolfish
V2EX  ›  程序员

分享我用 cnode 社区 api 做微信小应用的入门过程

  •  
  •   coolfish · 2016-09-27 17:33:58 +08:00 · 4315 次点击
    这是一个创建于 2981 天前的主题,其中的信息可能已经有所发展或是发生改变。

    微信应用号入门实践之 cnode 社区版

    首先感谢 cnode 社区提供的 api ,本次实现了简单的 cnode 社区应用号制作。 实现了数据的读取、展示, 实现了简单的布局, 实现了下一页功能。 首页列表 内容详情

    下面就说说我做这个的过程,不足之处,请多多指教,只愿为进步。

    1.创建项目

    首先,在官网下载工具,下载地址 我的是选择 mac 版本 0.9.092300 。

    然后跟着官方的简版教程 创建一个项目。

    注:现在官方的工具支持无 appid 创建项目。

    1.打开开发者工具,选择“添加项目”

    2.选择无 appid ,填写地址,创建项目

    3.创建成功,看到默认的 Demo 项目页面

    2.配置

    默认的项目里已经没有关于 tabBar 的配置信息,所以为了学习,我把这个配置进行了修改。

    首先关于配置的说明同样来自于官方

    注意:官方的代码有些字段是不一样的,小心被坑。

    {
      "pages":[
        "pages/index/index",
        "pages/logs/logs"
      ],
      "window":{
        "backgroundTextStyle":"light",
        "navigationBarBackgroundColor": "#fff",
        "navigationBarTitleText": "WeChat",
        "navigationBarTextStyle":"black"
      },
      "tabBar":{
        "list": [{
          "pagePath": "pages/index/index",
          "text": "首页"
        }, {
          "pagePath": "pages/logs/logs",
          "text": "日志"
        }]
      }
    }
    
    

    增加了 tabBar, 查看调试 看界面是如此的简陋,为此针对 tabBar 参考官方说明进行了简单的美化。

     "tabBar":{
        "color":"#272636",
        "selectedColor":"#80bd01",
        "backgroundColor":"#fff",
        "borderStyle":"white",
        "list":[{
          "pagePath":"pages/index/index",
          "text":"首页",
          "iconPath":"images/tabBar/my.png",
          "selectedIconPath":"images/tabBar/my_hl.png"
        },{
          "pagePath":"pages/index/index",
          "text":"我的",
          "iconPath":"images/tabBar/list.png",
          "selectedIconPath":"images/tabBar/list_hl.png"
        }]
      }
    

    效果如图 最后根据文档,对默认页面的窗口表现进行了修改

      "window":{
        "backgroundTextStyle":"black",
        "backgroundColor":"#fff",
        "navigationBarBackgroundColor":"#000",
        "navigationBarTitleText":"CNODE 应用号版",
        "navigationBarTextStyle":"white",
        "enablePullDownRefresh":"true"
      },
    

    效果如图 整体配置文件为

    {
      "pages":[
        "pages/index/index",
        "pages/logs/logs"
      ],
      "window":{
        "backgroundTextStyle":"black",
        "backgroundColor":"#fff",
        "navigationBarBackgroundColor":"#000",
        "navigationBarTitleText":"CNODE 应用号版",
        "navigationBarTextStyle":"white",
        "enablePullDownRefresh":"true"
      },
      "tabBar":{
        "color":"#272636",
        "selectedColor":"#80bd01",
        "backgroundColor":"#fff",
        "borderStyle":"white",
        "list":[{
          "pagePath":"pages/index/index",
          "text":"首页",
          "iconPath":"images/tabBar/my.png",
          "selectedIconPath":"images/tabBar/my_hl.png"
        },{
          "pagePath":"pages/index/index",
          "text":"我的",
          "iconPath":"images/tabBar/list.png",
          "selectedIconPath":"images/tabBar/list_hl.png"
        }]
      }
    }
    

    3.制作首页列表

    根据官方要求,我在 pages 文件夹内创建了 topics 文件夹,并创建了对应了 topics.js 、 topics.wxml 、 topics.wxss 三个文件。

    1.注册页面

    首先在配置文件里注册这个 topics,

      "pages":[
        "pages/topics/topics",
        "pages/index/index",
        "pages/logs/logs"
      ],
    

    并且制定 tabBar 点击跳到对应的 topics 页面

      "tabBar":{
        "color":"#272636",
        "selectedColor":"#80bd01",
        "backgroundColor":"#fff",
        "borderStyle":"white",
        "list":[{
          "pagePath":"pages/topics/topics",
          "text":"首页",
          "iconPath":"images/tabBar/my.png",
          "selectedIconPath":"images/tabBar/my_hl.png"
        },{
          "pagePath":"pages/index/index",
          "text":"我的",
          "iconPath":"images/tabBar/list.png",
          "selectedIconPath":"images/tabBar/list_hl.png"
        }]
      }
    
    注意:我发现注册页面的顺序会影响到默认显示 tabBar 的顺序,所以我把"pages/topics/topics"放到了"pages/index/index"的前面

    然后编写 topics.js

    Page({
      data: {
        title: '首页列表'
      },
      onLoad: function () {
        console.log('onLoad by topics');
      }
    });
    

    以及 topics.wxml 文件

    <view class="topics-main">
      测试首页列表界面
    </view>
    

    和 topics.wxss 文件

    .topics-main {
      background: #f60;
      height: 100%;
    }
    

    最后效果如图

    2.创建请求

    根据文档请求数据,在 util 文件夹内创建一个 api.js 文件,专门进行数据请求处理。

    'use strict';
    var HOST_URI = 'https://cnodejs.org/api/v1';
    
    var GET_TOPICS = '/topics';
    var GET_TOPIC_BY_ID = '/topic/';
    
    function obj2uri (obj) {
        return Object.keys(obj).map(function (k) {
            return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]);
        }).join('&');
    }
    
    module.exports = {
        // 获取列表数据
        getTopics: function (obj) {
            return HOST_URI + GET_TOPICS + '?' + obj2uri(obj);
        },
        // 获取内容页数据
        getTopicByID: function (id, obj) {
            return HOST_URI + GET_TOPIC_BY_ID + id + '?' + obj2uri(obj);
        }
    };
    

    修改 topics.js

    var Api = require('../../utils/api.js');
    
    Page({
      data: {
        title: '首页列表'
      },
      onLoad: function () {
        console.log('onLoad by topics');
        this.fetchData();// 获取数据
      },
      fetchData: function (data) {
        // 处理参数
        if (!data) data = {};
        if (!data.page) data.page = 1;
        wx.request({
          url: Api.getTopics(data),
          success: function (res) {
            console.log(res);
          }
        });
      }
    });
    

    效果如图 成功拿到了数据。

    3.完善首页列表

    拿到了数据,也能修改界面,那么就直接完善这个首页吧

    代码就不放了,直接上图 我认为这里值得说的大概只有 loading 、循环、传参、下一页和页面跳转了。

    1.loading

      <loading hidden="{{hidden}}">
        加载中...
      </loading>
    

    在 topics.wxml 中写官方提供的 loading 组件,根据在 topics.js 中对 hidden 值的修改,来触发 loading 。

    2.循环数据,展示列表

    文档提供了列表渲染

    通过wx:for实现列表的渲染。

    注意: 默认数组的当前项的下标变量名默认为 index ,数组当前项的变量名默认为 item 。
    <block wx:for="{{postsList}}">
      <view class="posts-item" index="{{index}}" id="{{item.id}}" catchtap="redictDetail">
        <view class="author">
          <image class="author-avatar" src="{{item.author.avatar_url}}"></image>
          <view class="author-name">{{item.author.loginname}}</view>
          <view class="posts-tag hot" wx:if="{{item.top === true}}">置顶</view>
          <view class="posts-tag" wx:if="{{item.good === true}}">精华</view>
          <view class="posts-last-reply">{{item.last_reply_at}}</view>
        </view>
        <view class="posts-title">{{item.title}}</view>
        <view class="bar-info">
          <view class="bar-info-item">
            <image class="bar-info-item-icon" src="/images/icon/reply.png"></image>
            <view class="bar-info-item-number">{{item.reply_count}}</view>
          </view>
          <view class="bar-info-item">
            <image class="bar-info-item-icon" src="/images/icon/visit.png"></image>
            <view class="bar-info-item-number">{{item.visit_count}}</view>
          </view>
        </view>
      </view>
    </block>
    

    附上一个没有样式的列表展现

    3.传参,实现 tab 切换

    根据 cnode 的 api 可以知道通过 tab 不同的值,获得到不同标签下的内容列表。

    所以 在页面的最上面 tab 栏中

      <view class="top-bar">
        <view class="top-bar-item" id="all" catchtap="onTapTag">全部</view>
        <view class="top-bar-item" id="good" catchtap="onTapTag">精华</view>
        <view class="top-bar-item" id="share" catchtap="onTapTag">分享</view>
        <view class="top-bar-item" id="ask" catchtap="onTapTag">问答</view>
        <view class="top-bar-item" id="job" catchtap="onTapTag">招聘</view>
      </view>
    

    将 id 进行定义,通过获取 id 拿到对应的 tab 类型。

    其中catchtap是事件绑定。

    bind 事件绑定不会阻止冒泡事件向上冒泡, catch 事件绑定可以阻止冒泡事件向上冒泡。

    在 topics.js 获取

      onTapTag: function (e) {
        var self = this;
        var tab = e.currentTarget.id;
        // 这里就能获取到不同的 tab 值了
        self.setData({
          tab: tab
        });
        if (tab !== 'all') {
          this.fetchData({tab: tab});
        } else {
          this.fetchData();
        }
      },
    

    4.下一页的实现

    根据文档,组件的视图容器中有scroll-view这个可滚动视图区域。

    注意:使用竖向滚动时,需要给<scroll-view/>一个固定高度。
    <scroll-view class="posts-list" style="height:100%" scroll-y="true" bindscrolltolower="lower">
      <block wx:for="{{postsList}}">
        ...
      </block>
    </scroll-view>
    

    topics.js 文件

      lower: function (e) {
        var self = this;
        // 修改当前页码
        self.setData({
          page: self.data.page + 1
        });
        // 判断当前页的 tab 值 进行请求数据
        if (self.data.tab !== 'all') {
          this.fetchData({tab: self.data.tab, page: self.data.page});
        } else {
          this.fetchData({page: self.data.page});
        }
      }
    

    5.跳页的实现

    posts-item中已经进行了事件绑定。利用wx.navigateTo实现页面的跳转。

    注意:一个应用同时只能打开 5 个页面,当已经打开了 5 个页面之后, wx.navigateTo 不能正常打开新页面。
    redictDetail: function (e) {
      console.log('我要看详情');
      var id = e.currentTarget.id,
          url = '../detail/detail?id=' + id;
          // 这里的 detail 是需要创建对应的文件,以及页面注册的
      wx.navigateTo({
        url: url
      })
    },
    

    4.实现详情页

    同样的原理,创建 detail 文件,并注册,获取数据,并美化页面。

    5.总结

    • 微信小应用页面的脚本逻辑在是在 JsCore 中运行, JsCore 是一个没有窗口对象的环境,所以不能再脚本中使用 window ,也无法在脚本中操作组件
    • 同样不能用 jquery
    • 也不能操作 dom
    • 部分标签不支持,比如 h1-h6 会编译报错。
    • 暂时没找到解决富文本详情页显示的办法。
    • 整体下来,感觉开发简单,限制很多。
    • 写过 react 的看这个确实比较简单。

    放上我的 github 地址 https://github.com/coolfishstudio/wechat-webapp-cnode

    最后感谢: cnode 社区和博卡君

    附上 博卡君的教程

    全球首个微信应用号开发教程!通宵吐血赶稿,每日更新!

    博卡君的应用号(小程序)开发教程首发第二弹!( 0923 )

    第三弹!全球首个微信应用号开发教程!通宵吐血赶稿,每日更新!

    第四弹!全球首个微信应用号开发教程!通宵吐血赶稿,每日更新!

    15 条回复    2016-10-07 11:00:57 +08:00
    fhefh
        1
    fhefh  
       2016-09-27 18:00:08 +08:00
    nice mark~~~
    cheetah
        2
    cheetah  
       2016-09-27 19:06:00 +08:00
    感谢分享
    cenxun
        3
    cenxun  
       2016-09-27 19:20:26 +08:00
    赞一个
    zonghua
        4
    zonghua  
       2016-09-27 19:35:20 +08:00
    博卡君吐血吐了四天

    博主可不可以描述一下流畅度
    coolfish
        5
    coolfish  
    OP
       2016-09-27 22:43:16 +08:00   ❤️ 1
    @zonghua 没法在真机测试 但是在模拟器中还是可以的
    fhefh
        6
    fhefh  
       2016-09-27 23:00:44 +08:00
    demo 写了好多 就是不知道真机体验如何 囧
    wangxiaoer
        7
    wangxiaoer  
       2016-09-28 08:48:58 +08:00
    这种社区形式的小应用有什么意义呢?跟浏览器直接访问有啥优势,广告过滤?
    coolfish
        8
    coolfish  
    OP
       2016-09-28 12:13:24 +08:00
    @fhefh 应该会不错 毕竟是大厂
    coolfish
        9
    coolfish  
    OP
       2016-09-28 12:14:52 +08:00
    @wangxiaoer 我觉得这种应用 最大的优势在于他们说的 无需安装 广告不可能 因为没有外链 但是微信有微信广告平台
    wangxiaoer
        10
    wangxiaoer  
       2016-09-28 13:40:08 +08:00
    无需安装这个有点拿去跟 APP 比也就算了,跟网站也想比这个?
    LiuXuFei
        11
    LiuXuFei  
       2016-09-28 14:42:07 +08:00
    没有内测的,“ URL 域名不合法,请在 mp 后台配置后重试”,有这个错误如何解决的?
    LiuXuFei
        12
    LiuXuFei  
       2016-09-28 14:54:45 +08:00
    解决
    coolfish
        13
    coolfish  
    OP
       2016-09-28 15:13:09 +08:00
    @wangxiaoer 和网站比的话 一个是离线功能 一个是入口
    ChunlinLi
        14
    ChunlinLi  
       2016-09-29 01:14:17 +08:00
    有点困了, 结果看这个被中途冒出的绿青蛙吓了一条。。。。
    mingyun
        15
    mingyun  
       2016-10-07 11:00:57 +08:00
    mark
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1671 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 16:48 · PVG 00:48 · LAX 08:48 · JFK 11:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.