1. 程式人生 > >微信小程式開發--初級實踐

微信小程式開發--初級實踐

微信小程式開發,快捷方便,容易上手,學習成本不高,但是好的程式設計師必須要經常開發來積攢經驗才為上策。在我的微信小程式入門篇中,筆者把微信小程式的demo通讀了一遍,可以說收穫良多,很多東西只有在自己理解的情況下才能牢牢記住,通過現有的知識做出能力範圍內可以實現的東西,這對於開發者來說是最好的實踐。因此筆者在這裡特別推出一個初級教程,而其中的知識基本上都是在demo中就可以獲得的,只要你通讀了我之前的文章,我相信你也能開發出一個簡單的小程式。
好了,廢話不多說,先上小程式示例的效果圖:

這裡寫圖片描述

由於demo能學到的有限,筆者暫時能想出來的例項就是類似這樣的應用,不過技術都是一步一步增長的,從小做起,然後才能強大。

前期準備:

1.準備好圖片,百度搜索多的是。
2.準備好json格式內容,我們的內容是以json形式儲存的。

這裡筆者給大家一份自己寫的json,僅供參考:

[  
        {"url":"http://www.huizhou.cn/food/rdtj/201211/W020121126369710784664.jpg",  
         "name":"豬肉",  
         "price":"32.4"},  
        {"url":"http://www.sc115.com/wenku/uploads/allimg/131201/214G63238-0.jpg",  
        "name
":"水果", "price":"17.5"}, {"url":"http://img1.gtimg.com/jiangsu/pics/hv1/78/113/1901/123641418.jpg", "name":"蔬菜", "price":"10.2"}, {"url":"http://image.enmuo.com/CMS/2011/12/12/1/CMS_111212141009773_0E_400x267.jpg", "name":"玩具", "price":"50.1"}, {"url
":"http://pic.58pic.com/58pic/15/68/58/80Q58PIC2Yz_1024.jpg", "name":"電腦", "price":"4500.2"} ]

大家以這樣的格式寫就好,內容自定。
做好前期準備,就正式進入敲程式碼階段。
首先建立專案,然後將專案中沒有用的東西刪除掉:
1.utils的資料夾刪除,此專案用不到;
2.pages中的logs資料夾刪除,此專案用不到;
3.app.js中刪除無用程式碼,留下一個空白的onLaunch方法和空白的globalData物件,app.json中刪除”pages/logs/logs”,”navigationBarTitleText”改為我們的“小型超市購物”,app.wxss中我們將padding改為50rpx 0;
4.index的每一個檔案都清空;
我們先從app.js檔案著手,此時你的程式碼應該和我的一樣:

App({  
  onLaunch: function () {  

  },  

  globalData:{  
  }  
})  

很空,且讓我們慢慢新增。在這裡,我希望複習一下之前demo中運用的傳值方法,記得demo中有個方法是:

getUserInfo:function(cb)  

很多讀者應該都記得,而且對於新手來說這個方法不好用,很難理解,因此我們在這裡再複習一遍,自己來使用它(cb這個引數筆者現在才知道全稱應該是callback,回傳值)。
我們現在也寫一個方法,名為getItem,用來獲取我們商品的列表資料:

getItem : function (callback) {  
},  

這個方法就是獲取我們的商品資料的,在這裡,我們仿照demo中的寫法,在globalData中設定一個值(有一些讀者可能會想的比較明白,可能事後會發現這個值根本用不到,只不過我們是為了模仿demo的寫法才用的這個值):

globalData:{  
    items:null   
  }  

在這裡我們有個空的items,這個就是我們的商品資料,然後我們再模仿getUserInfo中的寫法:

if (this.globalData.items) {  
      typeof callback == "function" && callback(this.globalData.items)  
    }  
    else {  
      this.globalData.items = [  
        {"url":"http://www.huizhou.cn/food/rdtj/201211/W020121126369710784664.jpg",  
         "name":"豬肉",  
         "price":"32.4"},  
        {"url":"http://www.sc115.com/wenku/uploads/allimg/131201/214G63238-0.jpg",  
        "name":"水果",  
        "price":"17.5"},  
        {"url":"http://img1.gtimg.com/jiangsu/pics/hv1/78/113/1901/123641418.jpg",  
        "name":"蔬菜",  
        "price":"10.2"},  
        {"url":"http://image.enmuo.com/CMS/2011/12/12/1/CMS_111212141009773_0E_400x267.jpg",  
        "name":"玩具",  
        "price":"50.1"},  
        {"url":"http://pic.58pic.com/58pic/15/68/58/80Q58PIC2Yz_1024.jpg",  
        "name":"電腦",  
        "price":"4500.2"}  
    ]  
    typeof callback == "function" && callback(this.globalData.items)  
    }  

因為我們的items此時為空的,所以第一個if我們是走不進去的,然後在else中我們直接設定了items,用我們前期準備的json賦值給它,它就成了一個數組,陣列中包含物件。在這之後我們回傳這個值給callback的引數,讓其能夠獲取我們的商品資料。
到這裡,我們的app的程式碼都碼好了,很簡單,這裡的邏輯只是讓app公開一個方法回撥,拿到我們設定的json(這裡又可以舉一反三,用請求同理)。接下來我們就要開始處理index檔案了。
在檔案中我們輸入page,系統自動會給我們拼接上Page({…})程式碼,回車即可:

Page({  
  data:{  
    String1  
  },  
  onLoad:function(options){  
    // 生命週期函式--監聽頁面載入  
    String2  
  },  
  onReady:function(){  
    // 生命週期函式--監聽頁面初次渲染完成  
    String3  
  },  
  onShow:function(){  
    // 生命週期函式--監聽頁面顯示  
    String4  
  },  
  onHide:function(){  
    // 生命週期函式--監聽頁面隱藏  
    String5  
  },  
  onUnload:function(){  
    // 生命週期函式--監聽頁面解除安裝  
    String6  
  },  
  onPullDownRefresh: function() {  
    // 頁面相關事件處理函式--監聽使用者下拉動作  
    String7  
  },  
  onReachBottom: function() {  
    // 頁面上拉觸底事件的處理函式  
    String8  
  },  
  onShareAppMessage: function() {  
    // 使用者點選右上角分享  
    return {  
      title: 'title', // 分享標題  
      desc: 'desc', // 分享描述  
      path: 'path' // 分享路徑  
    }  
  }  
})  

內容很多,我們將多餘程式碼刪除,只留下:

Page({  
  data:{  
    String1  
  },  
  onLoad:function(options){  
    // 生命週期函式--監聽頁面載入  
    String2  
  }  
})  

在這裡我們不需要options這個引數(這個引數後面會用到),刪除即可。
現在來說一下邏輯,我們需要在這個首頁顯示的是一個列表,因此我要拿到資料來展示,而資料在app的例項中我們寫了一個方法叫做getItem來獲取,為了儲存這個資料,我們需要一個變數來儲存它,既然如此,我們先在data中設定一個儲存用的變數:

data: {  
    items:[]  
  },  

為什麼是陣列?我們的json和getItem返回的本來就是一個數組,所以我們建立一個數組去儲存它。
之後我們就要去獲取它,很簡單在onLoad方法中,我們去呼叫app的getItem方法,因此別忘了先獲取app例項:

var app = getApp()  

然後在onLoad中呼叫:

onLoad: function () {  
    var that = this  
    app.getItem(function(item){  
      that.setData({  
        items:item,  
      })  
    })  
  },  

這個方法很眼熟,跟demo中幾乎一樣吧。記得getItem的引數我們已經定義為了function,所以在這裡我們需要傳入一個function,其次既然它符合了function,別忘了我們後面還有回撥用的callback(this.globalData.items)方法,所以我們要用一個引數去接收它,我在這裡用了item(在實際開發中使用items更好,這裡是方便讀者區分)。在我們的獲取到商品資料的同時,我們使用setData將它傳輸給我們index中的items變數進行儲存,這樣我們就可以在wxml中獲取我們的資料了。
來到wxml中,我們需要一個大容器來展示資料:

<view class="container">  
</view>  

這個容器是根據container的樣式,而container是儲存在app.wxss中,如果你不知道具體內容,可以回去看一下。既然有了容器,我們就需要展示。我們的目的是展示一個列表,我之前的文章說了,block是我們將來經常用到的東西,在這裡我們正好使用它:

<block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">  
</block>  

因為我們的items是一個數組,所以我們得需要用for語句去顯示它,我們這裡的用法與demo中無二,這樣我們就能獲取到items中每一個數據。其次,我希望每一條資料為一大塊,而且需要有一定的間隔如:

我們首先要用一個view來承載一行一行的格子:

<block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">  
<view>  
</view>   
</block>  

當然,這麼簡單是無法達成我們要的效果的,需要修改樣式,在index.wxss中新增一個樣式:

.item {  
    display: flex;  
    background-color: white;  
    flex-direction: row;  
    align-items: flex-start;  
    margin: 20rpx auto;  
    padding: 5rpx;  
    box-sizing: border-box;  
    border: 1px solid #d0d0d0;  
    border-radius: 2px;  
    width: 90%;  
}  

這個是我們整個一行的樣式,如此一來我們就基本達到我們的效果,然後把樣式表加入wxml中的view:

<block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">  
<view class="item">  
</view>   
</block>  

這步完成,大的框架已經搭好了,我們現在新增資料。首先新增商品名稱,我希望序列號和商品名稱顯示在左上角:

<block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">  
<view class="item">  
<text>{{index + 1}}.{{item.name}}</text>  
</view>   
</block>  

然後,我們需要新增我們的商品圖片,沒有圖片顧客怎麼瀏覽商品呢:

<block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">  
<view class="item">  
<text>{{index + 1}}.{{item.name}}</text>  
<image src="{{item.url}}" mode="aspectFit"></image>  
</view>   
</block>  

現在看起來整個顯示不夠美觀,商品名和圖片緊貼在一起,圖片太大,沒事,我們新增樣式就行:

.p{  
    padding-right:10rpx;  
}  
.image{  
    box-sizing: border-box;  
    border: 1px solid #d0d0d0;  
    width: 100px;  
    height: 80px;   
    background-color: 'white';  
}  

然後將樣式加入:

<block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">  
<view class="item">  
<text class='p'>{{index + 1}}.{{item.name}}</text>  
<image class='image' src="{{item.url}}" mode="aspectFit"></image>  
</view>   
</block>  

好了,看上去美觀多了是不是?最後我們把價格新增:

<block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">  
<view class="item">  
<text class='p'>{{index + 1}}.{{item.name}}</text>  
<image class='image' src="{{item.url}}" mode="aspectFit"></image>  
<text>{{item.price}}</text>  
</view>   
</block>  

這樣子整體效果還不是特別好,我們繼續新增樣式:

.price{  
    line-height: 80px;  
    width: 50%;  
    text-align: center;  
}  

加入樣式:

<block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">  
<view class="item">  
<text class='p'>{{index + 1}}.{{item.name}}</text>  
<image class='image' src="{{item.url}}" mode="aspectFit"></image>  
<text class='price'>{{item.price}}</text>  
</view>   
</block>  

差不多了,我們的長相看的過去了,現在我的需求變成了點選每一行進去可以看詳情,所以我們得新建一個頁面來顯示詳情,新增item的檔案,.js .wxss .wxml建立好。
記得需要在app.json中配置我們的新頁面,不然無法顯示和新增頁面:

"pages":[  
    "pages/index/index",  
    "pages/item/item"  
  ],  

我們等等處理item檔案,我們先來新增點選處理,來到index.js中,我們新增一個點選方法:

itemTap: function (event){  
  }  

我現在的需求是點選哪一行,哪一行的內容就要傳到第二個頁面,這樣該如何實現呢?這個方法在demo中並沒有體現,但是官方文件中有說明,在這裡你們可以直接看我程式碼,在index.wxml中新增itemTap:

<block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">  
<view bindtap="itemTap" data-item="{{item}}" class="item">  
<text class='p'>{{index + 1}}.{{item.name}}</text>  
<image class='image' src="{{item.url}}" mode="aspectFit"></image>  
<text class='price'>{{item.price}}</text>  
</view>  
</block>  

為了獲取我們點選到的資料,我們需要用到data-這個語句,這個語句data-之後是我們自定義的key,然後=之後是我們的value,這樣我們就可以在js中以key-value的形式獲取我們的資料,我們在這裡傳過去的是一個物件。
在index.js中我們修改點選事件的程式碼:

itemTap: function (event){  
    var item = event.currentTarget.dataset.item  
    wx.navigateTo({  
      url: '../item/item?name=' + item.name + '&url=' + item.url + '&price=' + item.price,  
    })  
  }  

event這個引數有哪些變數,我怎麼知道里面有currentTarget這個變數?這裡有個小技巧,先console.log(event),執行一遍,然後在除錯中看console資訊,你就能知道event裡面包含哪些變數。總之我們拿到了我們的資料,之後我們跳轉到新的頁面。在這裡我們看到與demo中不同的程式碼?name=’+之後的程式碼,在這裡筆者走了很多彎路,本來想要正向傳值,但是系統又拿不到item的例項,後來我通過搜尋別人大神和官方文件,我才知道微信小程式傳值是以類似get方法的url拼接傳值,真是有點意想不到。
這裡傳值在哪裡接收呢,哈哈,這就要用到我們之前刪除的options引數(往上拉,你會看到我說的引數)。
來到item.js,建立Page({…})程式碼:

Page({  
  data:{  
    String1  
  },  
  onLoad:function(options){  
    // 生命週期函式--監聽頁面載入  
    String2  
  }  
})  

看到了麼,options引數,這裡就能接收之前頁面傳過來的內容,它本身就是一個物件,因此我們直接建立一個物件去接收它:

Page({  
  data: {  
      item:{}  
  },  
  onLoad: function (options) {  
     this.setData({  
        item:options,  
      })  
 }  
})  

這樣我們就獲取了商品資料,然後我希望標題也能夠變成商品的名字,雖然demo中沒有用到這個方法,不過很幸運,系統正好給了這樣一個介面:

wx.setNavigationBarTitle({  
        title: options.name,  
      })  

哈哈,簡單,我們已經處理好所有的邏輯了,現在就來展示吧,item.wxml中:

<view class="container item">  
<image class="image" src="{{item.url}}" mode="aspectFit"></image>  
<text class="title">{{item.name}}</text>  
<text class="price">{{item.price}}</text>  
</view>  

item.wxss中:

.item {  
  align-items: center;    
  box-sizing: border-box;  
  border: 1px solid lightgrey;  
  border-radius: 5px;  
  margin: 0rpx 10rpx;  
  padding: 100rpx 0rpx 10rpx 10rpx;  
  background-color: lightcyan;  
}  
.image {  
    width: 100%;  
}  
.title {  
    border-bottom: 1px solid lightgray;  
    width: 80%;  
    line-height: 100px;  
    text-align: center;  
}  
.price {  
   line-height: 80px;  
   text-align: right;  
   width: 80%;  
   font-family: "YouYuan";  
   font-size: 30px;  
   font-weight: bold;  
   font-style:oblique;  
}  

在這裡關於wxml中的程式碼和wxss中的程式碼我就不多加闡述,因為我希望讀者你自己去顯示,用不同的方法來顯示內容~