用戶在視圖上的修改會自動同步到數據模型中去,一樣若是數據模型中的數據發生改變,也會同步到視圖層中。css
AppID
(在 微信開發者工具 新建小程序項目時須要)模擬器
編輯器
調試器
控制編輯器視圖,iphone6
100%
WIFI
分別爲機型選擇、縮放比例、網絡選擇普通編輯
模式下,每次刷新都是從新載入index刷新,能夠經過添加編譯模式
,自定義刷新指定頁面,這樣方便調試預覽
能夠在手機上預覽小程序遠程調試
手機能夠訪問小程序,同時編輯器提供控制檯一系列工具用於調試index.js
index.json
index.wxss
index.wxml
html
即app.json,app.json記錄了一些全局配置:react
{ "pages": [ "pages/index/index", //第一項就是進入小程序的首頁 "pages/calldetail/calldetail", "pages/finishcheck/finishcheck", ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#000", "navigationBarTitleText": "Hello", "navigationBarTextStyle": "white" }, "debug": true }
pages
頁面路徑window
頁面的窗口表現tabBar
底部tab切換networkTimeout
網絡超時時間debug
是否開啓debug模式,debug模式下控制檯會打印出詳細調試信息
更多關於app.json,詳細見官方文檔css3
window
頁面的窗口表現es6
enablePullDownRefresh
是否開啓下拉刷新,當設置爲true開啓下拉刷新,backgroundColor
頁面背景色在下拉的時候的「縫隙」中才會顯示出來設置tabBar
時要和pages
一一對應:json
"pages": [ "pages/index/index", "pages/movie/movie", "pages/logs/logs" ], "tabBar": { "color": "#707070", "selectedColor": "#129763", "list": [ { "text": "首頁", "pagePath": "pages/index/index", "iconPath": "common/img/main.png" }, { "text": "日誌", "pagePath": "pages/logs/logs", "iconPath": "common/img/logs.png" }, { "text": "視頻", "pagePath": "pages/movie/movie", "iconPath": "common/img/audio.png" } ] }
app.js中註冊App,會獲得一個程序實例,能夠被其餘頁面訪問小程序
App({ //程序實例 gldData: { a: 1 } })
頁面js中註冊Page:數組
Page({ //頁面實例 //在頁面中獲取應用實例 //經過getApp全局函數獲取應用實例 const app = getApp() pageData: { //自定義的頁面數據 b: 2 } onLoad: function(){ //在本頁面實例中訪問pageData console.log(this.pageData) } })
onLaunch
onLaunch在小程序運行期間,只會運行一次;程序銷燬(過了一段時間沒有運行,或手動刪除了小程序,再次添加運行)以後,再次啓動就會執行onShow
每次在後臺切換過來,就會執行onHide
每次切換到後臺,就會執行緩存
onLoad
頁面加載的時候執行,只會執行一次onReady
頁面第一次渲染完成以後,只會執行一次onShow
頁面顯示的時候就會執行,能夠執行屢次onHide
頁面隱藏就會執行,能夠執行屢次onUnload
頁面卸載的時候執行,只會執行一次
進入小程序首頁,會依次執行onLoad
onShow
onReady
,經過tabBar
從首頁
切換到視頻頁
,index不會被卸載,因此不會執行onUnload,可是會執行onHide
,進入視頻頁,視頻頁會執行視頻頁的onLoad、onShow、onReady,而後再經過tabBar從視頻頁切換回首頁,視頻頁執行onHide
,首頁執行onShow
微信
在首頁中加入導航navigator,經過navigator的方式跳轉到視頻頁,首頁仍是會執行隱藏方法onHide
,視頻頁左上角出現返回的返回方式,用這種返回方式返回到首頁,視頻頁會發生銷燬執行onUnload
let arr1 = [ 'Matt', 'Moly', 'Joe', 'Hurley' ] let arr2 = [ {id: Math.random(), name: 'Matt'}, {id: Math.random(), name: 'Moly'}, {id: Math.random(), name: 'Joe'}, {id: Math.random(), name: 'Hurley'} ] Page({ data: { arrNames: arr1 arr2Names: arr2 } }) <view wx:for="{{arrNames}}" wx:key="*this">{{item}}</view> <view wx:for="{{arr2Names}}" wx:key="id">{{item.name}}</view>
均可以循環渲染出name
Page({ data: { score: 80 } }) <view wx:if="{{score>70 && score<90}}">等級B</view> <view wx:elif="{{score<70 && score>30}}">等級C</view> <view wx:elif="{{score<30}}">等級D</view> <view wx:else>等級A</view>
block
並非真正的元素,用來輔助渲染一些平級的元素
<block wx:if="{{score===80}}"> <view>{{name}}</view> <view>{{score}}</view> <view>等級A</view> </block> <block wx:else>學生不符合要求</block>
//定義好template,指定name <template name="hello"> <view>這是hello行</view> </template> //在頁面中須要用到template的地方使用template,is和name要對應起來,這樣頁面上就能渲染出template中的內容 <template is="hello"></template>
//gender爲動態內容 <template name="hello"> <view>{{gender}}</view> </template> //相似react,這裏傳入變量gender,對象的形式 <template is="hello" data="{{gender: 'female'}}"></template>
<template name="renderList"> //渲染這個模板時就須要names這樣一個數組 <text>分數:{{score}}</text> <block wx:for="{{names}}" wx:key="id"> <view>{{item.name}}</view> <view>哈哈哈</view> </block> </template> <template is="renderList" data="{{names, score}}"></template> //js的data中已經定義了names和score
template.wxml
),放置的位置視狀況而定;<import src="template.wxml"/>
(這裏template.wxml和頁面wxml在同一目錄下)header.wxml
),在頁面中的引入方式:<include src="header.wxml"/>
<view bind:tap="onTap"> <text>點按我能夠打印信息</text> </view> onTap(){ console.log("我是誰") }
其中,bind:tap
中的冒號能夠不寫bindtap
事件函數中額外自帶事件對象參數:
onTap(e){ console.log(e) }
<view bind:tap="onTap" id='view' data-name="容器"> <text id="text" data-name="文字">點按我能夠打印信息</text> </view> onTap(e){ console.log(e) }
點擊view空白部分:
點擊text文字:
bindtap
不阻止事件冒泡catchtap
阻止事件冒泡
<view catch:tap="onTap" id='view' data-name="容器"> <text id="text" data-name="文字">點按我能夠打印信息</text> </view>
rpx規定屏幕寬爲750px
.class
#id
element
element, element
:after
:before
(好比不支持css3的屬性選擇器)
<text style='color: {{color}}'>點按我能夠打印信息</text> data: { color: 'red' }
<!--index.wxml--> <view class="container"> <wxs module="tool"> function createName(names) { return names.split(',') } module.exports = createName </wxs> <!-- tool就是wxs導出的函數 --> <!-- names爲js中data定義的 --> <view wx:for="{{tool(names)}}">{{item}}</view> </view> <!--index.js--> data: { names: "Alice,John,Sara,Dave" }
wxs也能夠獨立出來:
<!--tool.wxs--> function createName(names) { return names.split(',') } module.exports = createName <!--index.wxml--> <view class="container"> <!--tool.wxs和index.wxml在同一目錄下--> <wxs src="tool.wxs" module="tool"></wxs> <view wx:for="{{tool(names)}}">{{item}}</view> </view>
wxs不支持es6
<view>{{magicNumber}}</view> <button bindtap='onTap'>點擊</button> data: { magicNumber: Math.random() }, onTap(){ //this.data.magicNumber = 8999 //這種更新方式是沒用的 this.setData({ magicNumber: Math.random() //相似react更新方式 }) }
data變化,視圖不必定更新,這是一個異步的過程。
<input type="text" value="hello" bindinput='onInputChange'></input> onInputChange(e){ console.log(e) //return Math.random() //還能夠return出去一個值,控制輸入框東西的顯示 }
在輸入框輸入的時候,控制檯不斷打印事件對象,e.detail.value即爲輸入框內容
自定義組件,能夠單獨出來:
Component
註冊組件Component
註冊的是組件,Page
註冊的是頁面
而後在頁面的json文件中註冊自定義組件:
在頁面中使用自定義組件:
<!--index.wxml--> <magic-number></magic-number>
其中,在magicNumber.wxml中
<text>magicNumber自定義組件</text>
因此在index頁面中顯示的就是文字「magicNumber自定義組件」。
<!-- mnum.wxml --> <text bindtap="onTap">{{magicNumber}}</text> // mnum.js Component({ data: { magicNumber: Math.random() }, methods: { //組件裏事件的回調函數要統一寫在methods裏 onTap(e) { this.setData({ magicNumber: Math.random() }) } } })
<!-- mnum.wxml --> <text bindtap="onTap">{{magicNumber}}</text> // mnum.js Component({ data: { magicNumber: Math.random() }, methods: { //組件裏事件的回調函數要統一寫在methods裏 onTap(e) { this.setData({ magicNumber: Math.random() }) // 在自定義組件的事件回調函數中,還能夠另外再觸發事件,名稱自定義,用於頁面中使用 // 另外能夠攜帶一些參數到頁面(這裏data中的magicNumber) this.triggerEvent('getMagicNumber', this.data.magicNumber) } } }) // mnum.json { "component": true } <!--index.wxml--> <magic-number bind:getMagicNumber="onGetMagicNumber"></magic-number> // index.js onGetMagicNumber(e){ console.log(e) }
點擊index中顯示的自定義組件文字,控制檯打印處相關信息:
點擊文字頁面取整顯示:
<!-- mnum.wxml --> <text bindtap="onTap">{{magicNumber}}</text> <!--mnum.js--> Component({ data: { magicNumber: Math.random() }, methods: { //組件裏事件的回調函數要統一寫在methods裏 onTap(e) { this.setData({ magicNumber: Math.random() }) // 在自定義組件的事件回調函數中,還能夠另外再觸發事件,名稱自定義,用於頁面中使用 // 另外能夠攜帶一些參數到頁面(這裏data中的magicNumber) this.triggerEvent('getMagicNumber', this.data.magicNumber) } } }) <!--mnum.json--> { "component": true } <!--index.wxml--> <magic-number bind:getMagicNumber="onGetMagicNumber"></magic-number> <view>{{num}}</view> // index.js Page({ data: { num: null }, onGetMagicNumber(e){ this.setData({ //e.detail即爲那個值 num: Math.floor(e.detail*1000) }) } })
點擊文字,index頁面中的{{num}}也跟着變化,可是在頁面初始狀態,{{num}}顯示的是null,爲了讓{{num}}與自定義組件中的隨機數一致,在自定義組件的生命週期函數中:
自定義組件的自定義屬性要小寫,並用烤串形式:
<!-- mnum.wxml --> <text>{{nowIn}} is here!</text> // mnum.js Component({ properties: { // js爲駝峯式,頁面中爲烤串式 nowIn: String }, attached(){ //組件中經過this.data獲取到properties進而獲取到nowIn console.log(this.data) } }) <!--mnum.json--> { "component": true } <!--index.wxml--> <magic-number now-in="Index" bind:getMagicNumber="onGetMagicNumber"> </magic-number>
頁面顯示爲Index is here!
,控制檯打印信息爲{nowIn: "Index"}
小程序裏兩種方式實現導航:navigator
使用API進行導航
具體參數可在官網查閱 關於navigator
open-type
的屬性值——navigate
跳轉到switchTab
以tab方式切換頁面navigateBack
頁面回退redirect
重定向reLaunch
從新加載url頁面,頂部不會出現回退按鈕
<navigator url='/pages/movie/movie' open-type='navigate' >到movie</navigator> <!-- open-type的默認值爲navigate --> <navigator url='/pages/about/about'>到about</navigator>
navigate(跳轉到)
navigator方式,頂部會出現回退的樣式:
<navigator url='/pages/movie/movie' open-type='switchTab'>以tab方式切換到movie頁</navigator>
<!-- 要實現以tab方式切換頁面,在app.json中要配合寫上tab的配置項 -->
<navigator open-type='navigateBack'>回退</navigator>
<!--index.wxml--> <view>首頁</view> <navigator url='/pages/about/about'>到about</navigator> <!--pages/about/about.wxml--> <view>about頁</view> <navigator url='/pages/movie/movie' open-type='redirect'>重定向到movie頁</navigator> <!--pages/movie/movie.wxml--> <view>movie頁</view> <navigator url="/pages/about/about">去about</navigator>
從首頁進入about頁,在about頁重定向到movie頁,點擊頂部的回退,直接回退到首頁,而不是about頁 index-about-在about頁重定向到movie頁-到movie頁後點擊頂部回退-直接回到index頁
<!--index.wxml--> <view>首頁</view> <navigator url='/pages/about/about'>到about</navigator> <!--pages/about/about.wxml--> <view>about頁</view> <navigator url='/pages/movie/movie' open-type='reLaunch'>reLaunch movie頁</navigator> <!--pages/movie/movie.wxml--> <view>movie頁</view> <navigator url="/pages/about/about">去about</navigator>
在首頁進入about頁,在about頁以reLaunch的方式進入movie頁,movie頁就是小程序當前加載的惟一頁面 index-about-在about頁以reLaunch方式進入movie頁-movie頁,當前小程序加載的惟一頁面,頂部沒有返回按鈕
navigate
wx.navigateTo(OBJECT)
跳轉到redirect
wx.redirectTo(OBJECT)
重定向switchTab
wx.switchTab(OBJECT)
跳轉到某個tabnavigateBack
wx.navigateBack(OBJECT)
回退reLaunch
wx.reLaunch(OBJECT)
重加載
<!--index.wxml--> <view>首頁</view> <view bindtap='onGotoMovie'>使用API方式跳轉到movie</view> // index.js Page({ onGotoMovie(){ wx.navigateTo({ url: '/pages/movie/movie', }) } })
點擊便可以navigate的方式跳轉到movie頁
受權方式:用戶信息
(受權button)其餘信息受權
(wx.authorize(OBJECT)先進行受權直接獲取信息,未受權會先進行受權)
<!--index.wxml--> <!-- 點擊出現用戶受權彈框,點擊取消或者肯定會執行回調函數 --> <!-- onGetUserInfo即爲執行的回調 --> <button open-type='getUserInfo' bindgetuserinfo='onGetUserInfo'>獲取用戶信息</button> // index.js Page({ onGetUserInfo(e){ //接收一個事件對象,將其打印出來 console.log(e) } })
點擊按鈕,用戶出現受權彈窗:(以前進行過受權操做可先清除受權數據)
e.detail.userInfo爲用戶的一些基本信息
<!--index.wxml--> <button bindtap='onAuthLocation'>受權位置</button> // index.js Page({ onAuthLocation(){ wx.authorize({ //只是進行受權 scope: 'scope.userLocation', success: msg=>console.log(msg, 'location success'), fail: e=>console.log(e, 'location fail') }) } })
點擊按鈕,出現受權彈窗,根據用戶的選擇,會執行success或者fail的回調:
以點擊容許爲例,控制檯打印爲:
<!--index.wxml--> <button bindtap='onGetLocation'>獲取位置</button> // index.js Page({ onGetLocation(){ wx.getLocation({ //獲取到受權後的信息 success: msg=>console.log(msg, "位置"), fail: e=>console.log(e, "沒獲取到位置") }) } })
點擊按鈕:
選擇肯定,控制檯就會打印出地理信息相關信息:
<!--index.wxml--> <button bindtap='onGetSetting'>獲取受權信息</button> // index.js Page({ onGetSetting(){ wx.getSetting({ //微信提供這樣一個API用於告訴哪些信息受權了哪些信息沒有受權 success: msg => console.log(msg, "受權相關信息"), }) } })
<!--index.wxml--> <button bindtap='onGotoSetting'>打開受權信息面板</button> // index.js Page({ onGotoSetting(){ wx.openSetting({ success: msg=>console.log(msg, "設置完成") }) } })
點擊能夠進入受權面板:
微信裏能夠同步或者異步地緩存數據
<!--index.wxml--> <button bindtap='onCache'>緩存數據</button> // index.js Page({ onCache(){ wx.setStorage({ key: 'name', data: {p1: 'Matt'}, //data能夠指定字符串,也能夠指定對象 success: ()=>{ wx.getStorage({ key: 'name', success: data=>{ console.log(data) } }) } }) } })
點擊按鈕,便可實現緩存:
同時能夠取到緩存中name爲key的緩存數據,在控制檯打印出來:
以上設置緩存的方式是異步的。
如下爲同步設置緩存的方式:
<!--index.wxml--> <button bindtap='onCache'>緩存數據</button> // index.js Page({ onCache(){ wx.setStorageSync('names', 'Hurley') let ns = wx.getStorageInfoSync('names') console.log(ns) } })
點擊按鈕,緩存中寫入names:
並在控制檯打印出:
<!--index.wxml--> <view>{{name}}</view> <button bindtap='onSet'>設置緩存數據</button> <button bindtap='onGetName'>獲取name</button> <button bindtap='onRemoveName'>移除name</button> // index.js Page({ data: { name: 'hello' }, onSet(){ wx.setStorageSync('name', 'Hurley') }, onGetName(){ let n = wx.getStorageSync("name") console.log(n) if(n){ this.setData({ name: n }) } }, onRemoveName(){ //緩存中key爲「name」的緩存被移除 wx.removeStorageSync('name') } })
點擊「設置緩存數據」,緩存中寫入key爲「name」的緩存;
而後點擊「獲取name」,從緩存中獲取到key爲「name」的value值,並更新到data中的name,在視圖中{{name}}也會更新;
而後點擊「移除name」,緩存中key爲「name」的緩存數據被移除。
<!--index.wxml--> <button bindtap='onReq'>請求服務</button> // index.js Page({ onReq(){ wx.request({ url: 'http://localhost:3000/hello', data: { name: 'Joe' }, method: 'POST', success: data=>{ console.log(data) } }) } })
點擊按鈕,控制檯出現報錯:
所以,在小程序裏進行請求須要進行相應配置:
這樣就能夠經過接口請求到數據,快速調試時設置不校驗域名,能夠請求到數據