【原】小寫了一個cnode的小程序

     小程序剛出來的第一天,朋友圈被刷屏了,因此趁週末也小玩了一下小程序。其實發覺搭建一個小程序不難,只要給你一個demo,而後本身不斷的查看文檔,基本就能夠入門了,不過對於這種剛出來的東西,仍是挺多坑的,也就是文檔說的bug&tipscss

  本文只是搭建了cnode的首頁和詳情頁,其餘的什麼我的中心啊,搜索啊,都是同樣的道理,照葫蘆畫瓢,首頁和詳情頁會了,其餘的頁面也就會了,因此其餘頁面我就偷懶沒寫了。html

  爲何會想到模仿cnode呢,由於這個網站有公開的API文檔,調用起來方便。文檔地址在這裏:https://cnodejs.org/api前端

接下來,正式開始咱們的微信小程序之旅node

構建準備工做

構建過程我這裏直接列舉一些連接的方式,由於想把主要的篇幅用來寫程序的過程。react

一、首先你須要註冊一個微信小程序的開發平臺: 點這裏
git

二、其次你須要完善你的信息,來獲取AppID,若是沒有AppID的話,微信小程序的有些功能是用不了的,我的的話是沒法申請到的,要有企業的驗證信息,不過能夠看看這篇文章破解:點這裏github

三、須要下載一個微信開發者工具:點這裏json

四、前面的步驟準備好以後,開始構建咱們的項目,構建過程能夠看看這篇文章:點這裏小程序

正是開始搭建

這是咱們完成以後的視圖微信小程序

 

頁面分析:

    咱們能夠看到,頁面的頁腳有3個導航按鈕,分別是首頁、搜索、個人。

    首頁的話有5個tab切換,分別是所有、精華、分享、問答、招聘,當咱們點擊文章標題的時候,能夠跳轉到對應的詳情頁,按返回,能夠回到上一級頁面。上拉,能夠加載更多。接下來咱們就來完成這些功能。

小程序的開發文檔在這裏,能夠跟着文檔來看下面的代碼:文檔

咱們的目錄結構以下:

pages/

pages/index/index.wxml

pages/index/index.js

pages/index/index.wxss

pages/detail/detail.wxml

pages/detail/detail.js

pages/detail/detail.wxss

app.js

app.json

app.wxss

 

首先是使用app.json文件來對微信小程序進行全局配置,決定頁面文件的路徑、窗口表現、設置網絡超時時間、設置多 tab 等。

{
    "pages": [
        "pages/index/index",
        "pages/my/my",
        "pages/search/search",
        "pages/detail/detail"
    ],
    "window": {
        "navigationBarBackgroundColor":"#2b2e33",
        "navigationBarTextStyle": "white",
        "navigationBarTitleText": "cnode",
        "backgroundColor": "#fff",
        "backgroundTextStyle": "#dark"
    },
    "tabBar": {
        "color": "#74777e",
        "selectedColor": "#f06000",
        "borderStyle": "white",
        "backgroundColor": "#fff",
    "list": [{
        "pagePath": "pages/index/index",
        "iconPath": "image/wp.png",
        "selectedIconPath": "image/wpselect.png",
        "text": "首頁"
    }, {
        "pagePath": "pages/search/search",
        "iconPath": "image/ss.png",
        "selectedIconPath": "image/ssselect.png",
        "text": "搜索"
    },{
        "pagePath": "pages/my/my",
        "iconPath": "image/my.png",
        "selectedIconPath": "image/myselect.png",
        "text": "個人"
    }]
    },
    "networkTimeout": {
        "request": 10000,
        "connectSocket": 10000,
        "uploadFile": 10000,
        "downloadFile": 10000
    },
    "debug": true
}

     咱們在app.json中的pages來設置咱們的設置頁面路徑,數組的第一項表明小程序的初始頁面,咱們的首頁是初始頁,因此在page中的第一個。小程序中新增/減小頁面,都須要對 pages 數組進行修改。文件名不須要寫文件後綴,由於框架會自動去尋找路徑.json,.js,.wxml,.wxss的四個文件進行整合。

     在app.json中的list中,咱們歷來設置tab列表,也便是頁面中底部的導航欄,該list最少2個,最多5個。而且設置了對應頁面路徑、tab按鈕的文字、icon路徑,選中以後的圖片路徑等。

  其餘的配置內容能夠看看文檔,由於不可能全局介紹完,不然內容太多了。

 

     注意點:

  當咱們跳轉到詳情頁的時候,由於詳情頁是新增頁面,可是底部的導航欄是沒有詳情這個選項的,因此咱們須要在app.json中pages數組中增長詳情頁的路徑,可是在list數組中不須要增長,不然會報錯。

 

配置文件搞好了,接下來開始書寫咱們的首頁

一個小程序頁面由四個文件組成,分別是:js、wxml(至關於html)、wxss(至關於css)、json(頁面配置),這四個文件必須具備相同的路徑與文件名。

因此咱們首頁結構是:

pages/index/index.js

pages/index/index.wxml

pages/index/index.wxss

 

index.js以下:

/*
* @Author: xianyulaodi
* @Date:   2017-01-16 17:33:45
*/

//建立精選頁面對象
Page({

    data: {
        loading: false,
        loadtxt: '正在加載',
        currentTab: 'all',
        dataList:[],
        page:1,
        section: [
            {name : '所有',tab : 'all'},
            {name : '精華',tab : 'good'},
            {name : '分享',tab : 'share'},
            {name : '問答',tab : 'ask'},
            {name : '招聘',tab : 'job'}
        ]
    },
    /*
    *@param {Number} page      頁數
    *@param {String} tab       主題分類。目前有 ask share job good
    *@param {Number} limit     每一頁的主題數量
    *@param {String} mdrender  當爲 false 時,不渲染。默認爲 true,渲染出現的全部 markdown 格式文本。
    */
    onLoad: function(){
        var self=this;//這裏須要注意
        wx.request({
          url: 'https://cnodejs.org/api/v1/topics', 
          data: {
             'page':self.data.page,
             'tab':self.data.currentTab,
             'limit':10,
             'mdrender':true,
          },
          header: {
              'content-type': 'application/json'
          },
          success: function(rs) {
            var dataArr=rs.data.data;
            console.log(dataArr);
            var dataList=self.data.dataList;
            //合併數組,用於上拉加載更多,沒有append方法,我這種方法不是很好,由於到後面數組會很大
            var renderArr=self.data.page==1 ? dataArr : dataList.concat(dataArr);
            self.setData({
                loading: true,
                loadtxt: '數據加載完成',
                dataList: renderArr
            })
          }
        })
    },

    // 頁面上拉觸底事件的處理函數,用於上拉記載更多
    onReachBottom:function(e){
        var page=this.data.page;
        // 控制一下,最多顯示十頁的數據
        if(page<10){
            this.setData({ page: page+1 });
            this.onLoad();
        }
        return false;
        
    },
    handleTap: function(e){
        //console.log(e);
        let tab = e.currentTarget.id;
        if(tab){
            this.setData({ 
                currentTab: tab,
                page:1  //重置page爲1
            })
            this.onLoad();
        }
    },
    /*
    使用wx.navigateTo或者直接使用它的組件navigator要注意:
    在app.json裏面也須要pages裏面的配置裏要寫上跳轉的路徑,可是在app.json裏面不須要寫上這個跳轉的路徑。
    */
    goToDetail:function(e){
        var id=e.target.id;
        console.log(id);
        // wx.navigateTo,是保留當前頁面,調到應用內某個頁面,使用wx.navigateBack能夠返回
        wx.navigateTo({
          url: '../detail/detail?id='+id
        })
    }
})
View Code

代碼有點長,不過不要緊,咱們來分析一下:

  Page()函數用來註冊一個頁面。接受一個 object 參數,其指定頁面的初始數據、生命週期函數、事件處理函數等。

    Page()裏面有不少的參數,不過咱們只用到了其中的三個,onLoad和onReachBottom,data。

  onLoad是監聽頁面的加載,也就是說頁面一加載完成就會執行。 onReachBottom是頁面上拉觸底事件的處理函數,咱們這裏用來作上拉加載更多的操做,也就是上拉一次,請求的頁碼參數就加1;data是頁面初始數據。

     那麼獲取到的數據怎樣傳給頁面呢,能夠經過page()中的data參數,它是頁面的初始數據。若是你想改變初始數據,好比頁面請求完成了,能夠經過this.setData來對初始數據進行修改。

  還有對於請求參數的修改,咱們不是直接傳到onLoad裏面,而是經過this.setData()來對初始參數就行修改,從而達到修改參數目的,好比首頁上面的五個tab切換,後者是上拉加載更多的實現,都是經過這種方式來進行傳值的。

     除此以外,咱們還註冊了兩個事件,一個是handleTap,控制首頁(index頁)的tab切換,每次切換咱們要拿到該tab對應的tab值,從而拿到該tab對應的數據。在page定義中的相應事件處理函數,參數是event。咱們來看看下面的代碼:

 handleTap: function(event){
        console.log(event);
        let tab = event.currentTarget.id;
        if(tab){
            this.setData({ 
                currentTab: tab,
                page:1  //重置page爲1
            })
            this.onLoad();
        }
   }

咱們console.log(event)的內容以下:

 

咱們註冊的另外一個事件是goToDetail,用來跳轉到詳情頁,並傳入一個id過去:

 goToDetail:function(e){
        var id=e.target.id;
        // wx.navigateTo,是保留當前頁面,調到應用內某個頁面,使用wx.navigateBack能夠返回
        wx.navigateTo({
          url: '../detail/detail?id='+id
        })
    }

    這裏咱們調用小程序裏面提供的wx.navigateTo來跳轉到詳情頁,它會保留當前頁面,當你返回的時候能夠返回上一級頁面。也能夠這麼理解,wx.navigateTo至關於在當前頁面上方加了一層遮罩,這個遮罩就是你要跳轉頁面,當你點擊返回時,這層遮罩消失,所以你又回到了當前頁。

 

 接下來咱們介紹index.wxml

代碼以下:

  

<import src="../../common/template.wxml"/>

<view class="index">
    <view class="nav-scroll">
        <scroll-view class="scroll-view_H" scroll-x="true" style="width: 100%">
            <text wx:for="{{section}}" wx:key="tab" id="{{item.tab}}" catchtap="handleTap" class="nav-name {{item.tab == currentTab ? 'nav-hover' : ''}}">{{item.name}}</text>
        </scroll-view>
    </view>

    <view class="mod-item" wx:for="{{dataList}}" wx:key="{{index}}">
        <image src="{{item.author.avatar_url}}" class="image-item"></image>
        <view class="text" catchtap="goToDetail" id="{{item.id}}" >{{item.title}}</view> 
        <!-- 下面的寫法也能夠跳轉到詳情頁:
         <navigator class="text" url="../detail/detail?id={{item.id}}" open-type="navigate" hover-class="other-navigator-hover">
        {{item.title}}
        </navigator> -->
    </view>

    <template is="loadings" data="{{loading,loadtxt}}" />
    
</view>
View Code

      其實跟咱們的html差不錯,不過它又不是html,由於在這裏你不可使用html的語法,不然會報錯,而是要使用文檔中規定的那些標籤。能夠看看文檔中組件部分。

  咱們對裏面的內容進行分析:

      在WXML中,小程序提供了模板(template),能夠在模板中定義代碼片斷,而後在不一樣的地方調用。

      咱們的index.wxml中也引入了一個loading的模板,咱們來看看common/template.wxml裏面的內容

<!-- loading模板  -->
<template name="loadings">
    <view class="tips {{loading ? 'hide': ''}}">
        <image src="../../image/loading.gif" mode="aspectFit" />
        <text>{{loadtxt}}...</text>
    </view>
    <loading hidden="{{loading}}">
        {{loadtxt}}...
    </loading>
</template>

    咱們定義的是一個loading的模板,這樣的話在須要用到loading的地方均可以用到。不過有個前提,調用它的地方要提供和模板裏面同樣的數據結構。

如何使用呢,使用 is 屬性,聲明須要的使用的模板,而後將模板所須要的 data 傳入,如:

<template is="loadings" data="{{loading,loadtxt}}" />

   注意點:在模本里面的文件路徑是相應於引用它的頁面的路徑,若是圖片路徑被寫在一個js文件A裏,而B引用了這個js文件,那麼圖片的路徑必須是相對於B的相對路徑。因此,最好在公共的js文件裏使用絕對路徑。

    繼續咱們的頁面分析,頁面的數據那裏來的呢,來自於index.js的app()裏面的data參數裏,好比咱們的data裏面有section這個數組,能夠用來渲染首頁的tab切換,data裏面有dataList這個數組,用來渲染請求返回的數據。在組件上使用wx:for控制屬性綁定一個數組,便可使用數組中各項的數據重複渲染該組件。

  前面咱們也說了咱們handleTap和goToDetail兩個事件,怎樣綁定在頁面上呢,能夠用bindTapcatchTap的方式,不過catchTap不會冒泡,使用方法是這樣:

<view class="text" catchtap="goToDetail" id="{{item.id}}" >{{item.title}}</view> 

 

注意點:

當你的小程序能夠正常運行的時候,應該會有這樣的一個報錯;

 

 解決方法:打開小程序微信公衆平臺設置小程序開發設置,配置服務器合法域名(必須是https),以下圖

 

 

    這樣,咱們的首頁基本就完成了。由於css部分和正常的css同樣,沒啥好說的。分析一下首頁的代碼,發覺小程序有點借鑑react的思想,好比數據初始化還有一些page上提供的事件。若是你以前玩過react,入門起來會快不少。若是你有用騰訊的artTemplate這個js模板引擎的話,就更好理解一些。

 

接下來講一說詳情頁:

咱們在首頁中,經過wx.navigateTo跳轉到了詳情頁,並傳入了詳情頁須要的id

   goToDetail:function(e){
        var id=e.target.id;
        wx.navigateTo({
          url: '../detail/detail?id='+id
        })
    }

 

咱們來分析一下詳情頁的一些內容,首先來分析它的js,也就是pages/detail/detail.js

/*
* @Author: xianyulaodi
* @Date:   2017-01-16 17:33:45
*/

// 引入這個是爲了解析詳情頁的html
var WxParse = require('../../wxParse/wxParse.js');

Page({

    data:{
        title:'',
        loading: false,
        loadtxt: '正在加載',
        data:{}
    },
    onLoad: function(params){
        console.log(params); //這裏是上一個跳轉頁面傳過來的參數,能夠直接獲取
        var id=params.id;
        var self=this;//這裏須要注意
        wx.request({
          url: 'https://cnodejs.org/api/v1/topic/'+id, 

          header: {
              'content-type': 'application/json'
          },
          success: function(rs) {
            console.log(rs);
            var data=rs.data.data;
            var content=data.content;
            self.setData({
                loading: true,
                loadtxt: '數據加載完成',
                data: data
            });
            /**
            * WxParse.wxParse(bindName , type, data, target,imagePadding)
            * 1.bindName綁定的數據名(必填)
            * 2.type能夠爲html或者md(必填)
            * 3.data爲傳入的具體數據(必填)
            * 4.target爲Page對象,通常爲this(必填)
            * 5.imagePadding爲當圖片自適應是左右的單一padding(默認爲0,可選)
            * 可參考此文:https://weappdev.com/t/wxparse-version0-2-html-markdown/326 -->
            */
            WxParse.wxParse('content', 'html', content, self,5);
          }
        });
    },

})
View Code

咱們怎樣來拿到上一個頁面傳過來的值呢,咱們能夠在onLoad時間中寫一個參數,這個參數就是獲取url上傳過來的值,它是一個對象

onLoad: function(params){
        console.log(params); //這裏是上一個跳轉頁面傳過來的參數,能夠直接獲取
}

這是控制檯打印的內容,這樣的話,根據獲取的id,咱們就能夠傳給後臺請求到對應的詳情頁了。

     詳情頁和首頁的原理基本差很少,不過詳情頁content字段返回的是html結構,微信小程序暫時尚未富文本html、md解析組件。因此若是直接渲染content的話,會直接把html標籤頁顯示出來。

 那怎麼辦呢,咱們須要引入一個外部的歷來解析html的組件wxParse,連接地址在這裏:https://weappdev.com/t/wxparse-version0-2-html-markdown/326

這樣的話,html的富文本就能夠在頁面上正常顯示了。這樣,咱們的任務也就完成了

 

項目已上傳到github: https://github.com/xianyulaodi/cnodeLittleProgram

 

    總結:由於獲取的AppID是沒有交錢的,因此不能正常的發佈。不過能夠用來上手。整體下來, 小程序入門不難,大部分時間仍是看文檔爲主,最好的學習方式是把對着demo來看文檔,或者對着文檔來看demo,而後本身再模仿寫一個。能夠模板cnode,豆瓣,知乎日報這些,由於這些有開放的API能夠拿來用。

  不過怎麼說呢, 我的以爲,小程序仍是不能取代原生app的,除了剛出來那會被刷爆朋友圈以外,如今感受冷下來了,並且還有挺多坑沒有填完,因此不用急着去玩小程序,搞好咱們前端的基礎纔是最重要的。

相關文章
相關標籤/搜索