一、雙花括弧{{}}插值和MVVM模式 1.1 體會{{}}插值 index.wxml的標簽不是html的那些標簽,這裡的view就是div。 {{}}這樣的插值寫法,叫做mustache語法。mustache是鬍子的意思,因為{{}}像鬍子。 要在同名js文件下的data屬性中定義: 所有的框架: ...
一、雙花括弧{{}}插值和MVVM模式
1.1 體會{{}}插值
index.wxml的標簽不是html的那些標簽,這裡的view就是div。
{{}}這樣的插值寫法,叫做mustache語法。mustache是鬍子的意思,因為{{}}像鬍子。
<view class="container"> <view class="title"> 我是首頁 {{1 + 1}} {{a}}年! </view> </view>
要在同名js文件下的data屬性中定義:
Page({ data : { a : 100 } });
所有的框架:Angular、React、Vue、ReactNative、小程式都是這樣的“強耦合”的。
之前我們js操作html使用:document.getElementById()這樣的“不耦合”的方式,但是反而編程麻煩。
不僅僅{{}}可以出現在文字的部分,還可以出現在屬性值的雙引號中:
<view class="box" style="width:{{a}}px;height:{{a}}px">我是盒子</view>
1.2 體會MVVM模式
<button bindtap='add'>按我</button>
監聽直接寫在標簽上,bindtap表示綁定輕觸事件。
註意,是bindtap="add"而不是:bindtap="add()"
'add'是一個函數,要定義在js文件中。
註意:改變數據不能直接改,如果這樣寫,a的確會變化,但是視圖不會跟著變化!
Page({ data : { a : 100 }, add(){ this.data.a++; } });
必須使用this.setData()函數來改變data值,此時視圖才能變化。
Page({ data : { a : 100 }, add(){ this.setData({ a : this.data.a + 1 }); } });
數據變化了,視圖會自動改變
我們學習的所有框架都是MVVM模式的,只需要關心數據,不需要關心視圖,視圖會自動變化。
二、數據雙向綁定
2.1 調色板
先說一個知識點,用戶的屏幕是750rpx。所以如果盒子750rpx寬度,一定撐滿的,375rpx就是半屏。
slider組件:
index.wxss
.box{ width:350rpx; height:350rpx; margin:10px auto; }示例代碼
index.wxml:style行內樣式的插值,實現雙向數據綁定,就是data中的數據能夠成為組件的預設數據。
添加一個bindchanging事件,這個事件從手冊上查的。添加一個自定義屬性,叫做data-ys來區分誰是誰。
註意,自定義屬性必須以data-開頭
<view class="container"> <view class="box" style="background-color:rgb({{r}},{{g}},{{b}})"></view> <slider value="{{r}}" bindchanging="changeColor" data-ys="r" max="255" show-value block-size="18"/> <slider value="{{g}}" bindchanging="changeColor" data-ys="g" max="255" show-value block-size="18"/> <slider value="{{b}}" bindchanging="changeColor" data-ys="b" max="255" show-value block-size="18"/> </view>
index.js 事件處理函數:
Page({ data : { r : 100, g : 200, b : 123 }, changeColor(event){ this.setData({ [event.target.dataset.ys] : event.detail.value }) } });
event.target.dataset.ys就是當前觸發這個函數的組件身上的ys標識。
event.detail.value就是當前觸發這個函數的組件的值。
也就是說,微信小程式的事件處理函數,一律不能傳參!
<button bindtap="add(5)"></button>
只能是:
<button bindtap="add" data-n="5"></button>
2.2 微博發佈框
class的動態實現:{{}}中不能出現複雜語句,比如不能有for、if、while、var,最複雜就是三元了。
<view class="container"> <textarea value="{{content}}" bindinput="inputHandler" placeholder="預設" auto-focus /> <view class="{{content.length > 40 ? 'danger' : ''}}">當前:{{content.length}}字/40字</view> <view class="row"> <button disabled="{{content.length == 0 || content.length > 40}}">發佈</button> <button bindtap="clear" disabled="{{content.length == 0}}">清空</button> </view> </view>
index.js
Page({ data : { content : "" }, //當用戶輸入文本的時候 inputHandler(event){ this.setData({ content : event.detail.value }); }, //清空 clear(){ this.setData({ content: "" }); } });示例代碼
index.wxss
.danger{color:red;font-weight: bold;} .row{display: flex;}
三、指令
3.1 wx:if指令
判定一個元素是否上樹,而不是是否顯示。
<view class="container"> <button wx:if="{{isAgree}}">註冊</button> </view>
當這個變數是true按鈕上樹,否則下樹。
3.2 wx:for迴圈指令
命令一個標簽進行迴圈,使用wx:for。
index.js數據:
Page({ data : { arr: ["白板","么雞","二萬","三餅","四條"] } });
index.wxml:
<view class="container"> <view wx:for="{{arr}}" wx:key="{{index}}">{{index}} - {{item}}</view> </view>
wx:for的值必須是數組,不能是對象,此時會自動遍歷這個數組。
wx:for必須添加wx:key,表示迴圈這一項的標識,這個標識有什麼用?連上伺服器就有用了。增加效率
{{index}}、{{item}}是迴圈結構天生就有的,表示下標和項。
3.2.1 九九乘法表
因為空間太小,做五五乘法表:
<view class="row" wx:for="{{[1,2,3,4,5]}}" wx:key="{{index}}" wx:for-item="a"> <view class="col" wx:for="{{[1,2,3,4,5]}}" wx:key="{{index}}" wx:for-item="b"> {{a}} * {{b}} = {{a * b}} </view> </view>
index.wxss
.row{ width:750rpx;display: flex;} .col{ flex:1; text-align: center; font-size: 12px;border:1px solid #3bb; }
3.2.2迴圈信息流
index.wxml
<view class="container"> <view class="mingxing"> <view class="box" wx:for="{{mingxing}}" wx:key="{{index}}"> <view class="left"> <image src="{{item.picurl}}"></image> {{item.name}} </view> <view class="right"> {{item.info}} </view> </view> </view> </view>
index.wxss
.box{ width:720rpx;display: flex; border:1px solid #3bb; margin:10px auto;font-size: 13px; line-height: 24px; color:#333;padding:10px; box-sizing: border-box; } .left{flex:1;} .left image{width:180rpx; height:180rpx;} .right{flex:3; box-sizing: border-box;padding-left:10px;}示例代碼
index.js
Page({ data : { mingxing : [ { "name": "Angelababy", "info": "Angelababy(楊穎),1989年2月28日出生於上海市", "picurl": "/images/baby.png" }, { "name": "迪麗熱巴", "info": "迪麗熱巴(Dilraba),1992年6月3日出生於新疆烏魯木齊市", "picurl": "/images/dilireba.png" } ] } });示例代碼
3.2.3覆選框-迴圈數組
<view class="container"> 你的愛好: <checkbox-group bindchange="checkboxChange"> <label wx:for="{{hobbys}}" wx:key="{{index}}"> <checkbox value="{{item}}" checked="{{false}}"/> {{item}} </label> </checkbox-group> <view> 你的愛好是:{{myhobbys}} </view> </view>
Page({ data : { hobbys : ["籃球" ,"足球","羽毛球"], myhobbys : [] }, checkboxChange(event){ this.setData({ myhobbys: event.detail.value }); } });示例代碼
3.2.4操作數組-增刪改查
<view class="container"> <input placeholder="請填寫學生名字" auto-focus bindinput="inputHandler"/> <button bindtap="addstudent">增加</button> <view wx:for="{{student}}" wx:key="{{item.id}}" style="display:flex;"> <view>{{item.name}}</view> <button data-id="{{item.id}}" bindtap="delstudent">刪除</button> </view> </view>
Page({ data : { student : [ {"id": 1, "name": "小明"}, {"id": 2, "name": "小紅"}, {"id": 3, "name": "小剛"} ], //將來被添加的學生名字 needAddStudentName : "" }, delstudent(event){ const id = event.target.dataset.id; this.setData({ student: this.data.student.filter(item => item.id != id) }); }, inputHandler(event){ this.setData({ needAddStudentName : event.detail.value }); }, addstudent(){ const name = this.data.needAddStudentName; this.setData({ student: [ ...this.data.student, {id : ~~(Math.random() * 100), name } ] }); } });示例代碼
四、小程式API
4.1認識小程式的API
微信提供了非常多的API,可以方便的調起微信提供的能力,如獲取用戶信息,本地存儲,支付功能等。原理就是將JavaScript翻譯為Java、OC語言。
4.2使用請求數據的API
微信小程式,功能變數名稱只支持 https (request、uploadFile、downloadFile) 和 wss (connectSocket) 協議;
s是security安全的意思。微信小程式,只能用安全模式的https和wss協議。
https就是http的安全版本,用來提供JSON數據等等;
wss是websocket的安全版本,用來實時通信的。
功能變數名稱不能使用 IP 地址或 localhost,且不能帶埠號,而且功能變數名稱必須經過 ICP 備案;
對初學者不友好的,想跑一個上線的小程式,還得在服務上花一些錢。但是,在開發時,可以禁止上面的要求。
後端app.js提供介面
const express = require("express"); const app = express(); var a = 10; app.get("/api", (req,res)=>{ res.json({a}) }) app.get("/jia", (req,res)=>{ a++; res.json({}) }) app.listen(3000);示例代碼
<!--index.wxml--> <view class="container"> <view>{{a}}</view> <button bindtap="add">按我加伺服器的數據</button> <button bindtap="refresh">請求伺服器上最新數據</button> </view>wxml示例代碼
小程會自動幫我們跨域,跨域的原理是代理跨域。
const baseURL = "http://127.0.0.1:3000" //請求伺服器的數據 //出了page()函數外,this是window const requireServer = function(){ var self = this; wx.request({ url: `${baseURL}/api`, success: function ({ data }) { self.setData({ a: data.a }); } }); } Page({ data : { a : 0 }, //頁面顯示/切入前臺時觸發 onShow(){ //給函數綁定當前位置的this指向 requireServer.call(this); }, add(){ wx.request({ url: `${baseURL}/jia` }); }, refresh(){ requireServer.call(this); } });示例代碼
4.3模擬網路切換和監控
在模擬器里切換網路類型,查看控制台的輸出內容
在調試器里,輸入以下代碼並按回車鍵,進行網路監聽:
wx.onNetworkStatusChange(function(res) { console.log('網路連接:' + res.isConnected); console.log('網路狀態:' + res.networkType); });示例代碼
4.4生命周期
4.5小程式編譯及編譯模式