小程序開發備忘

相關資料

小程序簡易教程
框架介紹
組件介紹
Api

PART1 構成

小程序包含一個描述總體程序的 app 和多個描述各自頁面的 page。
一個小程序主體部分由三個文件組成,必須放在項目的根目錄,以下:
文件 必需 做用
app.js 小程序邏輯(配置第一次打開時, 崩潰,後臺切換時須要作的邏輯處理)
app.json 小程序公共配置 (小程序有哪些頁面page, 窗口的背景/顏色, 超時設置等)
app.wxss 小程序公共樣式表
具體每一個頁面page是由由四個文件組成,分別是:
文件類型 必需 做用
js 頁面邏輯
wxml 頁面結構
json 頁面配置
wxss 頁面樣式表

好比整個小程序全部的page的路徑信息須要配置到app.json中,舉例以下:
{
  "pages": [ 
    "pages/login/login",
    "pages/index/index",
    "pages/order/order",
    "pages/solution/solution",
    "pages/personal/personal",
    "pages/navigation/navigation",
    "pages/solutionChart/solutionChart"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle": "black"
  }
}
"pages" #用於描述當前小程序全部頁面路徑,這是爲了讓微信客戶端知道當前你的小程序頁面定義在哪一個目錄。

用於指定小程序由哪些頁面組成,每一項都對應一個頁面的 路徑+文件名 信息。文件名不須要寫文件後綴,框架會自動去尋找對於位置的 .json, .js, .wxml, .wxss 四個文件進行處理。javascript

數組的第一項表明小程序的初始頁面(首頁)。小程序中新增/減小頁面,都須要對 pages 數組進行修改。html

如開發目錄爲:java

├── app.js #整個小程序的通用配置(配置第一次打開時, 崩潰,後臺切換時須要作的邏輯處理)
├── app.json #小程序公共配置 (小程序有哪些頁面page, 窗口的背景/顏色, 超時設置等)
├── app.wxss #小程序總體通用公共樣式表
├── pages #小程序具體的各個子頁面目錄
│   │── index #一個小程序page對應如下4個文件組成 │   │ ├── index.wxml #至關於web的html頁面 │   │ ├── index.js #控制頁面的邏輯 │   │ ├── index.json #配置本頁面的標題,背景等 │   │ └── index.wxss #頁面的個性化樣式
│   └── logs
│       ├── logs.wxml
│       └── logs.js
└── utils #用戶自定義用於存放工具類
└── images #用戶自定義存放圖片路徑

└── images #用戶自定義存放圖片路徑

則須要在 app.json 中寫web



{ "pages":[ "pages/index/index",//這裏對應的就是pages/index/index.wxml頁面 "pages/logs/logs" ] }
"window" #定義小程序全部頁面的頂部背景顏色,文字顏色定義等

PART2 邏輯層和視圖層

以數據綁定的程序爲例
index目錄就是一個具體的頁面, 下面有js,wxml,wxss等文件用來描述index.wxml這個頁面
app.json中的pages配置了index這個頁面
{
  "pages":[
    "index/index"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle":"black"
  }
}
打開 index.wxml頁面
<!--index.wxml-->
< view > {{text}} </ view >
< button bindtap = "changeText"> Change normal data </ button >
< view > {{num}} </ view >
< button bindtap = "changeNum"> Change normal num </ button >
< view > {{array[0].text}} </ view >
< button bindtap = "changeItemInArray"> Change Array data </ button >
< view > {{object.text}} </ view >
< button bindtap = "changeItemInObject"> Change Object data </ button >
< view > {{newField.text}} </ view >
< button bindtap = "addNewField"> Add new data </ button >

其中<view> 和<button>等分別是小程序提供的視圖組件和表單組件, 能夠理解爲html中的標籤
可直接使用並配置相關參數(事件,大小等屬性), 並由小程序渲染.

index.js 代碼以下
// pages/index/index.js
Page({

/**
* 頁面的初始數據
*/
data: {
array: ['當天', '本月', '近三月','近半年','本年'],
index: 0,
date: '2016-09-01',
time: '12:01',
barItem: [
{
name: '利潤彙總',
image: '../../images/menu1_unfocus.png',
selectedImage: '../../images/menu1_focus.png',
selected: false,
color: '#666666',
url: '/pages/solution/solution'
},
{
name: '每日營業狀況',
image: '../../images/menu3_unfocus.png',
selectedImage: '../../images/menu3_focus.png',
selected: true,
color:'#FF0000',
url: '/pages/index/index'
},
{
name: '運營支出',
image: '../../images/menu2_unfocus.png',
selectedImage: '../../images/menu2_focus.png',
selected: false,
color: '#666666',
url: '/pages/order/order'
},
// {
// name: '',
// image: '../../images/menu4_unfocus.png',
// selectedImage: '../../images/menu4_focus.png',
// selected: false,
// url: '/pages/personal/personal'
// },
],
successresponseData: [],
datalist:[]
},

//更新日期選型,刷新取值
bindPickerChange: function (e) {

var that = this;
console.log('picker發送選擇改變,攜帶值爲', e.detail.value)
this.setData({
index: e.detail.value
})
wx.request({
url: require('../../config').getnumUrl,
//url: 'http://localhost:8081/framework-protal/main/gas/getsale',
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded'
},

data: {
gasid: wx.getStorageSync('gasid'),
type: e.detail.value
},
success: function (res) {
console.log('success')
console.log(res.data)
that.setData({
numresponseData: res.data.response,
})
},
fail: function (res) {
console.log('fail')
}

})
wx.request({
url: require('../../config').getsaleUrl,
//url: 'http://localhost:8081/framework-protal/main/gas/getsale',
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded'
},
data: { gasid: wx.getStorageSync('gasid') },
success: function (res) {
console.log('success')
console.log(res.data)
that.setData({
responseData: res.data.response,
})
var gasnameArr = wx.getStorageSync('gasname');
var gasname;
if (gasnameArr.length != 0 && gasnameArr != undefined) {
gasname = gasnameArr.join(",");
if (gasname.length > 10) {
gasname = gasname.substring(0, 10) + "...";
}
}
that.setData({
gasname: gasname,
gasnameArr: wx.getStorageSync('gasname'),
})
},
fail: function (res) {
console.log('fail')
}

})




},
/**
* 生命週期函數--監聽頁面加載
*/
onLoad: function (options) {
let that =this;
var gasnameArr = wx.getStorageSync('gasname');
var gasname;
if (gasnameArr.length != 0 && gasnameArr != undefined) {
gasname = gasnameArr.join(",");
if (gasname.length > 10) {
gasname = gasname.substring(0, 10) + "...";
}
}
that.setData({
gasname: gasname,
gasnameArr: wx.getStorageSync('gasname')
})
/*wx.request({
url: require('../../config').getsaleUrl,
//url: 'http://localhost:8081/framework-protal/main/gas/getsale',
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded'
},

data: { gasid: wx.getStorageSync('gasid') },
success: function (res) {
console.log('success')
console.log(res.data)
that.setData({
responseData: res.data.response,
})
},
fail: function (res) {
console.log('fail')
}

}) */



wx.request({
url: require('../../config').getnumUrl,
//url: 'http://localhost:8081/framework-protal/main/gas/getsale',
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded'
},

data: {
gasid: wx.getStorageSync('gasid'),
type:0 //默認值爲當天
},
success: function (res) {
console.log('success')
console.log(res.data)
that.setData({
numresponseData: res.data.response,
})
},
fail: function (res) {
console.log('fail')
}

})


},
//加油站點擊事件
bindButtonTap: function (e) {
wx.redirectTo({
url: '/pages/personal/personal?userid=' + wx.getStorageSync('userid') + '&type=1',
})
},
/**
* 生命週期函數--監聽頁面初次渲染完成
*/
onReady: function () {
},

/**
* 生命週期函數--監聽頁面顯示
*/
onShow: function () {
},

/**
* 生命週期函數--監聽頁面隱藏
*/
onHide: function () {
},

/**
* 生命週期函數--監聽頁面卸載
*/
onUnload: function () {
},

/**
* 頁面相關事件處理函數--監聽用戶下拉動做
*/
onPullDownRefresh: function () {
},

/**
* 頁面上拉觸底事件的處理函數
*/
onReachBottom: function () {
},

/**
* 用戶點擊右上角分享
*/
onShareAppMessage: function () {
},

/**
* 菜單單擊
*/
onBarItemClick: function (e) {
let url = this.data.barItem[e.currentTarget.dataset.sno].url;
if (url == null || url == '') {
return;
}
wx.redirectTo({
url: url
})
},
/**
* 導航欄單擊
*/
onNavigation: function () {
wx.navigateTo({
url: '/pages/navigation/navigation'
})
},

onHotPro2: function(e) {
wx.navigateTo({
url: '/pages/groupLine/groupLine?id=' + e.currentTarget.id,
})
},

onHotPro3: function(e) {


wx.login({ //調用微信登陸接口
success: function (res) {
wx.setStorageSync("code", res.code)
let code = wx.getStorageSync("code")
//
wx.request({
url: 'http://172.16.16.145:8180/wxService/wx/queryProductDetail',
method: 'GET',

data: {
id: 3,
},
success: function (res) {
console.log('success')
console.log(res)
},
fail: function (res) {
console.log('fail')
}
});
},
fail: function () {

}
});





wx.navigateTo({
url: '/pages/flowPay/flowPay',
})
},

onCase1: function(e) {

wx.navigateTo({
url: '/pages/case/case?id=' + e.currentTarget.id,
})
},
//輸入搜索內容
searchmessage: function (e) {
this.setData({
searchmessage: e.detail.value
})
},
//點擊搜索
onsearch: function (e) {

wx.navigateTo({
url: '/pages/order/order?productName=' + this.data.searchmessage,
})
},
//點擊註冊
regist: function (e) {
wx.navigateTo({
url: '/pages/login/reg/reg',
})
}
})
index.js中的data屬性用於配置頁面第一次渲染使用的初始數據.
頁面加載時, data  將會以 JSON 字符串的形式由邏輯層傳至渲染層,所以 data 中的數據必須是能夠轉成 JSON 的類型:字符串,數字,布爾值,對象,數組。
舉例代碼中data定義了text 和array
Page({
  data: {
    text: 'init data',
    array: [{msg: '1'}, {msg: '2'}]
  }
})
對應index.wxml中的
<view>{{text}}</view>
<view>{{array[0].msg}}</view>
頁面初始化的時候小程序會自動從js的data中加載對應的text和array數據初始化顯示到{{}}中.
   
   
   
   
   
< view > {{text}} </ view >
< button bindtap = "changeText"> Change normal data </ button >
wxml中在按鈕上配置的changeText定了點擊對應的函數,在js中對應changeText()方法中:
changeText: function () {
    // this.data.text = 'changed data'  // bad, it can not work
    console.log(this.data.text);
    var text2="hola baby";
    this.setData({
      text: text2,
    })
    console.log(this.data.text);
  }
   
   
   
   
   
能夠經過this.setData來修改text的值.在changeText中經過 this.data.text能夠獲取到初始化設置的data中的屬性的text的值
Page({
  data: {
    text: 'init data',
    array: [{msg: '1'}, {msg: '2'}]
  }
})
以本例
   
   
   
   
   
第一次打印的是index.js中data中設置的text初始化的值( this .data.text ) 爲 init data
經過this.setData()方法中修改text後, 從新打印 this .data.text的值即變爲了咱們設置的hola baby
經過this.setData()修改text成功後, 對應頁面上的值也會自動改變.

this.setData解釋:

Page.prototype.setData(Object data, Function callback)

setData 函數用於將數據從邏輯層發送到視圖層(異步),同時改變對應的 this.data 的值(同步)。json


以上可見對應的視圖層控制在wxml中 邏輯控制在js中小程序

引用官方的說明以下: 視圖層(由wxml, wxss,wxs等來支持實現): api

https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/ 數組

WXML(WeiXin Markup Language)是框架設計的一套標籤語言,結合基礎組件、事件系統,能夠構建出頁面的結構。緩存

它支持數據綁定, 列表渲染,條件渲染,模版 事件, 引用等.微信

引用官方的說明以下: 邏輯層(由頁面的js, 小程序api等來支持實現): 

https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/

其中小程序提供的api說明以下:

小程序開發框架提供豐富的微信原生 API,能夠方便的調起微信提供的能力,如獲取用戶信息,本地存儲,支付功能等。

小程序原生API類型以下:
  • 事件監聽 (咱們約定,以 on 開頭的 API 用來監聽某個事件是否觸發,如:wx.onSocketOpen 監聽 WebSocket 鏈接打開事件,wx.onCompassChange 等。)
  • 同步API (如 wx.setStorage 數據存儲:將數據存儲在本地緩存中指定的 key 中。數據存儲生命週期跟小程序自己一致)
  • 異步API (如wx.setStorageSync 異步的數據存儲, 如wx.request 發起異步網絡請求)

以上咱們能夠經過api進行小程序全局的本地數據存儲和獲取, 或者發起http請求
好比在小程序頁面打開的時候加載後臺數據:
在頁面index.js的
onLoad: function (options) {}監聽頁面加載自動調用的onload方法中
經過wx:request請求後臺數據

var that = this;
wx.request({ //請求後臺數據
     url: require ( '../../config' ).getregistcostlistUrl,
     method: 'POST' ,
     header: {
          'content-type' : 'application/x-www-form-urlencoded'
     },
     data: { //向後臺數據發送的請求參數
          id: wx.getStorageSync( 'gasid' ), //以id爲name,value爲全局緩存中key爲gasid的值, 發送給後臺
          type : 3
     },
     success: function (res) { //請求成功後的回調方法
          that.setData({
            responseData: res.data  //將請求成功的值,經過this.setData 修改保存到responseData中, 這裏的responseData對應能夠下wxml中{{responseData}}來同步顯示.甚至若是responseData是對象,咱們能夠新增屬性responseData.name responseData.pwd而不須要預先定義.
       })
     let a = 0 ;
          for ( let i = 0 ; i < res.data.length; i++) {
          a = a + res.data[i].total
     }
     that.setData({
          total: a
     })
     },
     fail: function (res) {
     console.log( 'fail' )
     }
  })


以功能多選爲例

<block wx:for="{{responseData}}" wx:key="{{responseData}}">
 <view class='content' id='{{item.id}}' data-text="{{item.name}}" name='{{item.name}}' bindtap='itemSelected'>
  <text>{{item.name}}</text> 
  <image id='img-{{item.id}}' class='select_icon' src="{{item.isSelected?'../../images/selected.png':''}}"></image>
 {{iconVar}}
 </view>
</block>
responseData爲數據集合被循環.
item爲循環變量, item.name爲加油站的名字, view中的 data- text後臺函數就能夠經過
 var name = e.currentTarget.dataset. text; 來獲取值. 這是小程序約定的數據傳遞綁定方式.
//選中
  itemSelected: function (e) {
    var id = e.currentTarget.id;//e.currentTarget.dataset.index;//當前選中加油站的id
    var name = e.currentTarget.dataset.text;
    var replyLikeArr = this.data.replyLike;
    var replyLikeNameArr = this.data.replyLikeName;
    //初次加載的加油站對象數據經過onload方法中的this.setData保存在responseData中
    //而wxml中有{{responseData}}, 因此咱們能夠經過this.data.responseData獲取
    
    for (var i = 0; i < this.data.responseData.length; i++) {
      if (this.data.responseData[i].id==id){
        var item = this.data.responseData[i];//遍歷加油站集合,將結合中與將當前選中的加油站id相同的那個對象獲取到
        if(!item.isSelected){ //加油站一開始並無isSelected屬性,這裏第一次確定是false.本段代碼執行後,加油站對象就多了一個isSelect屬性,默認值爲false
          if (replyLikeArr.length > 2) {
            wx.showToast({
              title: '選擇不可超過3個',
              icon: 'loading',
              duration: 2000
            })
            return;
          }
        }
        item.isSelected = !item.isSelected; //將加油站選中的標記屬性isSelect置爲相反
        if (item.isSelected){ //若是加油站被選中的屬性爲是,這將其id和名字放入新的集合變量中
            replyLikeArr.push(id);
            replyLikeNameArr.push(item.name);
        }else{//若是加油站被選中的屬性爲否,這將其id和名字從選中集合變量中刪除
          replyLikeArr.splice(replyLikeArr.indexOf(id),1);
          replyLikeNameArr.splice(replyLikeNameArr.indexOf(item.name),1);
        }
       break;
      }
    }
    this.setData({
        //務必經過setData修改以上操做.不然新增isSelect屬性或者修改isSelect屬性的值都不會發生變化
      responseData: this.data.responseData,
      replyLike: replyLikeArr,
      replyLikeName: replyLikeNameArr
    });
  },
變量replyLikeArr和replyLikeNameArr被定義在page:data中歷來存放被選中的加油站的id和名字.

經過wxml中的
< image id = 'img-{{item.id}}' class = 'select_icon' src = "{{item.isSelected?'../../images/selected.png':''}}"></ image >
可見,若是加油站一開始沒有isSelect屬性或者屬性爲false就不會出現選中的圖片.

這裏展現瞭如何循環遍歷, 若是在方法中獲取頁面上的傳值, 如何在方法中獲取頁面的數據並修改,而且顯示了若是經過修改頁面的值同同時控制頁面效果.這個效果是基於小程序頁面數據綁定單向的這一特性(修改頁面的屬性,這頁面上的值也會自動變化).
另外如需跨頁面傳值可經過跳轉時url綁定或者api的wx.setStorage(key,object ) 來實現. 特別是wx.setStorage和wx.getStorage可實現整個小程序內部的本地緩存數據的存放和讀取.

一樣圖標選中變紅的效果

<view class="layout_horizontal" style='float:left; width:80%;'>
  <block wx:for="{{responseData}}" 
    wx:key="{{responseData}}" 
    wx:for-item="item" wx:for-index="index">
    <view  bindtap="chooseGood" 
       style='display:inline-block; width:23%; margin-left:2%;' 
         data-index="{{index}}" data-goodId="{{item.goodid}}">
     <button class="{{index==idx?'btnRed':'btn1'}}" >{{item.goodname}}</button>
    </view>
</block>
</view>
點擊後調用了chooseGood方法
到對應頁面的js中將查看方法
//選擇產品類型,同時更新數據更新報表
  chooseGood: function (e) {
    let index = e.currentTarget.dataset.index;
    var goodid = e.currentTarget.dataset.goodid;//所選產品類型的id
    this.setData({
      idx: index
    })
    wx.setStorageSync("chooseGoodid", goodid);
    this.getXYData();
  },
頁面上有data-goodId="{{item.goodid}} 和 data-index="{{index}}" 其中index是循環的索引(從0開始)
因此咱們能夠經過e.currentTarget.dataset.index和e.currentTarget.dataset.goodid來獲取值
咱們在頁面上定義若是index爲idx則樣式爲 btnRed(被選中) 不然爲btn1樣式(沒被選中)
<button class="{{index==idx?'btnRed':'btn1'}}" >{{item.goodname}}</button>
此時只須要在js中將 idx的值改成當前索引值便可. 此時被選中的商品的索引傳給了idx,頁面上
它的索引值就和idx一致,它就會使用 btnRed的樣式,表示爲被選中.

而效果
點擊顯示隱藏的其餘數據並將總體其餘view下移可經過計算
一開始獲取商品類型若是超過4個,則數組另存爲responseData 並截取只保留4個顯示.
點擊按鈕更多時,判斷本地緩存中wx.getStorageSync('goodsType') 商品類型數量,
若是超過4個則修改樣式
size = responseData.length / 4;
size = size * 60;
對應wxml中
< view style = 'font-size:20rpx ;width:100% ;display: flex;margin-left:3%;margin-top:{{moveSize}}rpx'>
moveSize變量初始在page.data設爲0,此時便可經過上外距撐開.
反之,再次點擊圖標,則會收縮.隱藏商品類型,只顯示4個.
此時將本地緩存中商品類型截取, 保留4個並複製給頁面上的須要遍歷的變量.
並將須要下拉的外邊距變量moveSize的值改成0便可.
這些操做後都須要this.setData來保存.
moreGoods: function () {
    var objArrAll = wx.getStorageSync('goodsType');
    var responseData=this.data.responseData;
    var size = 0;
    var ifMore = this.data.ifMore; //一開始沒有這多個屬性的話此時會新增屬性,默認值爲false
    //商品類型超過4個纔有展開的需求
    if (objArrAll.length>4){
      if (ifMore){//已展開,則菜單進行收縮操做
       //size默認已值爲0
        responseData = responseData.slice(0,4);
        ifMore=false;//標記爲未展開
      }else{ //未展開, 則對菜單進行展開操做
        responseData = objArrAll; //將所有商品賦給須要顯示的遍歷的對象
        ifMore = true;//標記展開
        //修改樣式
        size = responseData.length / 4;
        size = size * 60;
      }
    }

    this.setData({
      responseData,
      moveSize: size,
      ifMore,
    })
  },





相關文章
相關標籤/搜索