Mock缺少與服務器交換數據的行爲。
json中的最後一行的 逗號(,)不能保留。json格式下,鍵值都應該是雙引號。
微信小程序---model彈窗:<model></model>標籤
tabBar
json 的 pages 數組中排第一個的頁面必須是 tabbar 的第一個標籤的主頁
請注意switchTab只能跳轉到帶有tab的頁面,不能跳轉到不帶tab的頁面!跳轉不帶tab的頁面還是需要使用redirect或者navigate!
page.json
每一個小程序頁面也可以使用.json
文件來對本頁面的窗口表現進行配置。頁面的配置比app.json
全局配置簡單得多,只是設置 app.json 中的 window 配置項的內容,頁面中配置項會覆蓋 app.json 的 window 中相同的配置項。
頁面的.json
只能設置window
相關的配置項,以決定本頁面的窗口表現,所以無需寫window
這個鍵
bindtap
小程序中,全用bindtap(bind+event),或者catchtap(catch+event)綁定事件,例如:
跳轉其他頁面,並傳遞一個參數:
一個超級簡單的佈局:....
/* pages/classify/classify.wxss */
.title {
display: flex;
justify-content: center;
height: 80rpx;
line-height: 80rpx;
}
.text {
color:#ccc;
font-size:30rpx;
padding: 0 20rpx;
}
.line {
position: relative;
top: 40rpx;
width: 30rpx;
border-top: 1px solid #ccc;
}
還有一個超級簡單的佈局 :多份圖片文字都居中
.container {
display: flex;
justify-content: space-around;
}
.container .item {
width: 20%;
text-align: center;
border: 1px solid #ccc;
}
.container .item image{
width: 100%;
height: 80rpx;
}
.container .item view{
font-size:26rpx;
}
flex佈局:
flex-direction: column; //排列方向
justify-content: space-around; //主軸對齊方向: 每個元素兩側的距離均相等
align-items:center; //交叉軸對齊方向:根據flex-direction判斷
1. 基礎佈局
.container {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items:center;
height: 400px;
background-color:blue;
}
2. wrap 換行及根據高度計算消除多餘的間距
.container {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items:flex-start;
flex-wrap: wrap;
height: 200px;
background-color:blue;
}
.chunk {
width: 150px;
height: 100px;
}
小程序:
1. 首頁注意細節
點擊到最後一期期刊時,箭頭無法再點擊。
通過本地緩存,讀取期刊數據(而不是每次點擊去請求服務端)。
2. 搜索頁
頭部搜索固定頂部。
點擊搜索後,內容直接覆蓋搜索頁。
加載更多loading功能。
3. 其餘
分享功能。
小程序跳轉其他小程序。
<image> 標籤引入圖片時,需要設置高度和寬度。否則就是默認的寬高(寬320px;高240px))
小程序尺寸單位與設計原則:
rpx自適應尺寸。(當設計師以iphone6爲設計稿標準時,標註的尺寸與rpx爲1:1,而px則需要設置爲標註的一半)。
情況:字體的大小假如不希望隨機型改變。border邊框。
只有很少的css樣式可以被組件繼承。
文字本身有空白間距。(設置和文字相同的line-height就能夠消除)。
設置diaplay:inline-flex; 自適應寬度。
bind:tap(觸摸事件,阻止點擊冒泡)。
一般setData方法多用於點擊後改變頁面信息或者刷新後與後臺交互獲取最新的信息
注意:
- 直接修改 this.data 而不調用 this.setData 是無法改變頁面的狀態的,還會造成數據不一致
- 單次設置的數據不能超過1024kB,請儘量避免一次設置過多的數據。
組件內部的數據就直接寫在data中(組件的內部數據),需要開放出來的數據寫在properties屬性中(組件的對外屬性)。
wx.request(Object):
1. 只要服務器返回了結果(而不管結果是成功還是失敗),都是執行success回調函數。需要在小程序的後臺賬號中添加要訪問的域名。
2. 是一個異步函數,如果直接對這個賦值是取不到結果的。
3. 涉及到this的指代問題:可以直接在回調中使用箭頭函數解決作用域的問題。獲取異步的數據
success:(res)=>{
console.log(this.data.test)
}
ES6的新語法:模塊化的導入和導出
導出:新建一個config.js文件,寫入:
const config = {
api_base_url: 'http://bl.7yue.pro/v1/',
appkey: 'KOLDaSADSDLWWbF'
}
export {config}
導入:新建util/http.js,寫入:
import {config} from '/config.js'
將API的調用封裝成一個類:
ES5只有indexOf方法,可以用來確定一個字符串是否包含在另一個字符串中。ES6又提供了三種新方法。
includes():返回布爾值,表示是否找到了參數字符串;
startsWith():返回布爾值,表示參數字符串是否在查找字符串的頭部;
endsWith():返回布爾值,表示參數字符串是否在查找字符串的尾部。
let s = 'Hello world!'; s.indexOf('e') //1 s.startsWith('Hello') // true s.endsWith('!') // true s.includes('o') // true
同時這三個方法都支持第二個參數,表示開始搜索的位置。
在import時只能使用相對路徑,而組件中是可以使用絕對路徑的。
import {config} from '../config.js'
class HTTP{
// 類中的方法
request(params) {
// 如果沒有指定方法,就默認是GET
if(!params.method) {
params.method='GET'
}
// 發起微信請求
wx.request({
url: config.api_base_url +params.url,
method:params.method,
data:params.data,
header:{
'content-type':'application/json',
'appkey': config.appkey
},
success:(res)=>{
let code = res.statusCode.toString()
// 如果是2開頭則調用成功的方法,startsWith
if(code.startsWith('2')){
params.success(res.data)
}else{
}
},
fail:(err)=> {
}
})
}
}
export {HTTP}
在classify/classify.js中使用:使用自定義的類的方法
import {HTTP} from '../../util/http.js'
let http= new HTTP()
Page({
/**
* 生命週期函數--監聽頁面加載
*/
onLoad: function (options) {
http.request({
url:'classic/latest',
success:(res)=>{
console.log(res)
}
})
// wx.request({
// url: 'http://bl.7yue.pro/v1/classic/latest',
// header: {
// appkey: 'KOLDaSADSDLWWbF'
// },
// success:(res)=>{
// console.log(this.data.test)
// }
// })
}
})
增加API調用時的錯誤異常處理:util/http.js:增加了一個私有方法去顯示錯誤信息
import {config} from '../config.js'
const tip = {
1: '抱歉,出現一個錯誤了', //作爲默認的錯誤提示
1005: 'appkey無效,申請一個咯',
3000:'期刊不存在'
}
class HTTP{
// 類中的方法
request(params) {
// 發起微信請求
wx.request({
success:(res)=>{
let code = res.statusCode.toString()
// 如果是2開頭則調用成功的方法,startsWith
if(code.startsWith('2')){
params.success && params.success(res.data)
}else{
let error_code = res.error_code
this._show_error(error_code)
}
},
fail:(err)=> {
this._show_error(1)
}
})
};
_show_error(error_code) {
if(!error_code) {
error_code = 1
}
wx.showToast({
title: tip[error_code],
icon:'none',
duration:2000
})
}
}
export {HTTP}
改寫獲取數據的方法:models/classic.js : 通過擴展HTTP這個類
import {HTTP} from '../util/http.js'
// 拓展一個類的方法,獲取數據
class ClassModel extends HTTP {
// 在方法中調用回調函數
getLatest(sCallback) {
this.request({
url: 'classic/latest',
success: (res) => {
sCallback(res)
}
})
}
}
export {ClassModel}
同時獲取數據的方法就可以改成:pages/classify/classify.js:在實例化的方法中使用箭頭函數調用結果。
import {ClassModel} from '../../models/classic.js'
let classic= new ClassModel()
Page({
onLoad: function (options) {
classic.getLatest((res)=>{
})
}
})
通過回調函數獲得調用的結果。
在組件中設置自定義事件:this.triggerEvent("like",{},{})
1. 通知頁面,用戶點擊了這個組件
2. 並且需要附加一個狀態:用戶的行爲
組件的自定義事件:this.triggerEvent("like",{},{}) 事件名就是like
// 激活事件
let behavior = this.properties.like ? 'like' : 'cancel'
this.triggerEvent("like", {
behavior //改變事件中detail的值
}, {})
然後在頁面中通過bind:like=“like” 綁定自定義的事件。
models/like.js中寫POST請求:
import { HTTP } from '../util/http.js'
// 拓展一個類的方法,獲取數據
class LikeModel extends HTTP {
// 在方法中調用回調函數
like(behavior, artID, category ) {
let url = behavior == "like" ? "like" : "like/cancel"
this.request({
url: url,
method: 'POST',
data: {
art_id: artID,
type: category
}
})
}
}
export { LikeModel }
父組件中調用:
onLike: function (event) {
console.log(event)
let behavior = event.detail.behavior
likeModel.like(behavior, this.data.classicData.id, this.data.classicData.type)
},
在data中的字符串初始化應爲: ''表示。數字就用:0表示。
組件的observer函數,在改變屬性值之後會自動調用和這個函數:
(不能在屬性properties中的observer中改變自身的值,否則會發生無限遞歸):利用wxs可以解決。
// components/expore/index.js
Component({
/**
* 組件的屬性列表
*/
properties: {
index: {
type: String,
oberver:function(newVal,oldVal,changePath) {
let val = newVal < 10? '0'+newVal : newVal
this.setData({
_index:val
})
}
}
},
/**
* 組件的初始數據
*/
data: {
_index:''
},
})
5. input封裝爲內置組件
對於將 input
封裝在自定義組件中、而 form
在自定義組件外的情況, form
將不能獲得這個自定義組件中 input
的值。此時需要使用自定義組件的內置behavior wx://form-field
。
form表單:
<form bindsubmit="formSubmit">
表單
<!-- 自定義的input組件 只需要在這個自定義的組件中加上name屬性即可,不需要在組件中的input上加name屬性 -->
<my-input name="test"></my-input>
<button form-type="submit">提交</button>
</form>
自定義input組件:
<!-- 自定義input組件 -->
<view>
<!-- 這裏不需要設置name屬性,而是在調用組件時,添加name屬性。如<my-input name="test"></my-input> -->
<input bindinput="getInputValue"></input>
</view>
提示:behaviors的功能相當於組件之間公用代碼,裏面有公用的屬性、方法。可以把behavior當做構造函數,別的組件能使用這個behavior的方法和數據。
Component({
behaviors: ['wx://form-field'], //wx://form-field 代表一個內置 behavior ,它使得這個自定義組件有類似於表單控件的行爲。
properties: {
// value:{ //其實要在自定義input組件中設置固定(默認)值,可以直接在properties中設置,不用在attached中調用setData設置
// type: String,
// value: '1' // 默認值爲 1
// }
},
attached() {
// this.setData({
// value: '官網給出的例子:在attached生命週期設置的value值是固定的,所以我在input失去焦點時,設置value值'
// })
},
methods:{
getInputValue (e) {
this.setData({
value: e.detail.value // behaviors: ['wx://form-field']裏面就有設置value屬性,所以我們可以直接拿來設置value
})
}
}
})
可以: 原文地址