在小程序中,JSON扮演的靜態配置的角色。javascript
小程序配置 app.jsonphp
{ "pages": ["pages/index/index", "pages/logs/logs"], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle": "black" } }
https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.htmlcss
若是小程序是一個多 tab 應用(客戶端窗口的底部或頂部有 tab 欄能夠切換頁面),能夠經過 tabBar 配置項指定 tab 欄的表現,以及 tab 切換時顯示的對應頁面。html
其中 list 接受一個數組,只能配置最少 2 個、最多 5 個 tab。tab 按數組的順序排序,每一個項都是一個對象java
{ "pages": ["pages/index/index", "pages/logs/index"], "tabBar": { "list": [ { "iconPath": "assets/fonts/首頁.png", "selectedIconPath": "assets/fonts/home.png", "pagePath": "pages/index/index", "text": "首頁" }, { "pagePath": "pages/logs/logs", "text": "日誌" } ] } }
tabBar 還有其餘屬性json
顏色僅支持十六進制,定位僅支持top和bottom,其中top時不支持圖標。小程序
{ "tabBar": { "color": "#ff00ff", "selectedColor": "#0000ff", "backgroundColor": "#00ff00", "position":"bottom" } }
每個小程序頁面也可使用 .json 文件來對本頁面的窗口表現進行配置。頁面中配置項在當前頁面會覆蓋 app.json 的 window 中相同的配置項微信小程序
頁面配置中只能設置 app.json 中 window 對應的配置項,以決定本頁面的窗口表現,因此無需寫 window 這個屬性。api
WXML 充當的就是相似 HTML 的角色。數組
<view class="container"> <view class="userinfo"> <button wx:if="{{!hasUserInfo && canIUse}}">獲取頭像暱稱</button> <block wx:else> <image src="{{userInfo.avatarUrl}}" background-size="cover"></image> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </block> </view> <view class="usermotto"> <text class="user-motto">{{motto}}</text> </view> </view>
block標籤的做用是直接解析裏面的內容,不解析自身block標籤。
WXSS 具備 CSS 大部分的特性,小程序在 WXSS 也作了一些擴充和修改。
新增了尺寸單位。在寫 CSS 樣式時,開發者須要考慮到手機設備的屏幕會有不一樣的寬度和設備像素比,採用一些技巧來換算一些像素單位。WXSS 在底層支持新的尺寸單位 rpx ,開發者能夠免去換算的煩惱,只要交給小程序底層來換算便可,因爲換算採用的浮點數運算,因此運算結果會和預期結果有一點點誤差。
提供了全局的樣式和局部樣式。和前邊 app.json, page.json 的概念相同,你能夠寫一個 app.wxss 做爲全局樣式,會做用於當前小程序的全部頁面,局部頁面樣式 page.wxss 僅對當前頁面生效。
此外 WXSS 僅支持部分 CSS 選擇器
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html
==iPhone6 1rpx = 0.5px 1px = 2rpx==
<view>{{ msg }}</view> <button bindtap="clickMe">點擊我</button>
Page({ data:{ msg: '小程序' }, clickMe() { this.setData({msg: 'Hello World'}) } })
更詳細的資料:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
小程序的運行環境分紅渲染層和邏輯層,其中 WXML 模板和 WXSS 樣式工做在渲染層,JS 腳本工做在邏輯層。
小程序的渲染層和邏輯層分別由2個線程管理:渲染層的界面使用了WebView 進行渲染;邏輯層採用JsCore線程運行JS腳本。一個小程序存在多個界面,因此渲染層存在多個WebView線程,這兩個線程的通訊會經由微信客戶端(Native)作中轉,邏輯層發送網絡請求也經由Native轉發。
微信客戶端在打開小程序以前,會把整個小程序的代碼包下載到本地。
緊接着經過 app.json 的 pages 字段就能夠知道你當前小程序的全部頁面路徑。
整個小程序只有一個 App 實例,是所有頁面共享的,具體內容查看註冊程序 App https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/app.html
小程序提供了豐富的組件
https://developers.weixin.qq.com/miniprogram/dev/component/
<navigator url="/page/navigate/navigate?title=navigate" hover-class="navigator-hover" > 跳轉到新頁面 </navigator> <navigator url="../../redirect/redirect/redirect?title=redirect" open-type="redirect" hover-class="other-navigator-hover" > 在當前頁打開 </navigator> <navigator url="/page/index/index" open-type="switchTab" hover-class="other-navigator-hover" > 切換 Tab </navigator>
爲了讓開發者能夠很方便的調起微信提供的能力,例如獲取用戶信息、微信支付等等,小程序提供了不少 API 給開發者去使用。
wx.scanCode({ success: (res) => { console.log(res) } })
https://developers.weixin.qq.com/miniprogram/dev/api/index.html
WXML(WeiXin Markup Language)是框架設計的一套標籤語言,結合基礎組件、事件系統,能夠構建出頁面的結構。
<!--wxml--> <view>{{message}}</view>
// page.js Page({ data: { message: 'Hello MINA!' } })
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/data.html
默認數組的當前項的下標變量名默認爲 index,數組當前項的變量名默認爲 item
<!--wxml--> <view wx:for="{{array}}">{{item}}</view>
// page.js Page({ data: { array: [1, 2, 3, 4, 5] } })
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/list.html
如不提供 wx:key,會報一個 warning
<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch>
Page({ data: { objectArray: [ {id: 5, unique: 'unique_5'}, {id: 4, unique: 'unique_4'}, {id: 3, unique: 'unique_3'}, {id: 2, unique: 'unique_2'}, {id: 1, unique: 'unique_1'}, {id: 0, unique: 'unique_0'} ] } })
<!--wxml--> <view wx:if="{{view == 'WEBVIEW'}}">WEBVIEW</view> <view wx:elif="{{view == 'APP'}}">APP</view> <view wx:else="{{view == 'MINA'}}">MINA</view>
// page.js Page({ data: { view: 'MINA' } })
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/conditional.html
wx:if 是惰性的,若是在初始渲染條件爲 false,框架什麼也不作,在條件第一次變成真的時候纔開始局部渲染。
相比之下,hidden 就簡單的多,組件始終會被渲染,只是簡單的控制顯示與隱藏。
通常來講,wx:if 有更高的切換消耗而 hidden 有更高的初始渲染消耗。所以,若是須要頻繁切換的情景下,用 hidden 更好,若是在運行時條件不大可能改變則 wx:if 較好。
<view hidden="{{hidden}}"> 內容 </view>
<!--wxml--> <template name="staffName"> <view> FirstName: {{firstName}}, LastName: {{lastName}} </view> </template> <template is="staffName" data="{{...staffA}}"></template> <template is="staffName" data="{{...staffB}}"></template> <template is="staffName" data="{{...staffC}}"></template>
// page.js Page({ data: { staffA: {firstName: 'Hulk', lastName: 'Hu'}, staffB: {firstName: 'Shang', lastName: 'You'}, staffC: {firstName: 'Gideon', lastName: 'Lin'} } })
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/template.html
WXML 提供兩種文件引用方式import和include。
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/import.html
<!-- item.wxml --> <template name="item"> <text>{{text}}</text> </template>
在 index.wxml 中引用了 item.wxml,就可使用item模板:
<import src="item.wxml" /> <template is="item" data="{{text: 'forbar'}}" />
WXS(WeiXin Script)是小程序的一套腳本語言,結合 WXML,能夠構建出頁面的結構。
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/
<!--wxml--> <wxs module="m1"> var msg = "hello world"; module.exports.message = msg; </wxs> <view>{{m1.message}}</view>
頁面輸出:
hello world
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
<view id="tapTest" data-hi="WeChat" bindtap="tapName">Click me!</view>
Page({ tapName(event) { console.log(event) } })
事件綁定的寫法同組件的屬性,以 key、value 的形式。
bind事件綁定不會阻止冒泡事件向上冒泡,catch事件綁定能夠阻止冒泡事件向上冒泡。
如在下邊這個例子中,點擊 inner view 會前後調用handleTap3和handleTap2(由於tap事件會冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,再也不向父節點傳遞),點擊 middle view 會觸發handleTap2,點擊 outer view 會觸發handleTap1。
<view id="outer" bindtap="handleTap1"> outer view <view id="middle" catchtap="handleTap2"> middle view <view id="inner" bindtap="handleTap3"> inner view </view> </view> </view>
須要在捕獲階段監聽事件時,能夠採用capture-bind、capture-catch關鍵字,後者將中斷捕獲階段和取消冒泡階段。
在下面的代碼中,點擊 inner view 會前後調用handleTap二、handleTap四、handleTap三、handleTap1。
<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2" > outer view <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4" > inner view </view> </view>
#box2{ height: 100px; width: 100px; background: blue; } #box2:hover{ transform: rotate(180deg) scale(.5, .5); background: red; transition: background 2s ease, transform 2s ease-in 1s; }
// app.wxss 在主頁面引入,page頁面就均可以使用了 @import './assets/animate.wxss';
<view class='{{a}}'></view>
this.setData({ a : ['box', 'animated', 'fadeOutRight'] })
https://developers.weixin.qq.com/miniprogram/dev/api/wx.createAnimation.html
<button bindtap="fn">動畫</button> <view animation="{{animationData}}" style="background:red;height:100rpx;width:100rpx;position: absolute;top:1000rpx;" ></view>
data: { animationData: {} }, fn() { const animation = wx.createAnimation({ duration: 3000 }) this.animation = animation animation.scale(2, 2).rotate(45).step().width(400).top(10).step() this.setData({ animationData: animation.export() }) }
step方法表示動畫完成。一組動畫中的全部動畫會同時開始,一組動畫完成後纔會進行下一組動畫。
導出動畫隊列。export 方法每次調用後會清掉以前的動畫操做。
鼠標右鍵->新建組件,會生成一組文件。
// components/toast/toast.js Component({ //組件的屬性列表 properties: { str : String }, //組件的生命週期函數 lifetimes: { attached() { // 在組件實例進入頁面節點樹時執行 console.log('attached:', this.properties.str); }, detached() { // 在組件實例被從頁面節點樹移除時執行 console.log('刪除') } }, // 組件的初始數據 data: { }, // 組件的方法列表 methods: { show(){ } } })
// components/toast/toast.wxml <view> 傳過來的屬性:{{str}} </view>
// pages/mine/mine.json { "usingComponents": { "toast":"/components/toast/toast" } }
// pages/mine/mine.wxml <toast id="abc" str="hello"></toast>
// pages/mine/mine.js Page({ data: { }, fn(){ this.toast = this.selectComponent("#abc"); this.toast.show(); } })
page頁的生命週期:https://developers.weixin.qq.com/miniprogram/dev/guide/framework/page-life-cycle.html
page頁生命週期鉤子函數的示例代碼:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html
component頁的生命週期:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html
組件的生命週期,指的是組件自身的一些函數,這些函數在特殊的時間點或遇到一些特殊的框架事件時被自動觸發。
其中,最重要的生命週期是 created attached detached ,包含一個組件實例生命流程的最主要時間點。
==自小程序基礎庫版本 2.2.3 起,組件的的生命週期也能夠在 lifetimes 字段內進行聲明(這是推薦的方式,其優先級最高)。==
Component({ lifetimes: { attached() { // 在組件實例進入頁面節點樹時執行 }, detached() { // 在組件實例被從頁面節點樹移除時執行 }, }, // 如下是舊式的定義方式,能夠保持對 <2.2.3 版本基礎庫的兼容 attached() { // 在組件實例進入頁面節點樹時執行 }, detached() { // 在組件實例被從頁面節點樹移除時執行 }, // ... })
在小程序中全部頁面的路由所有由框架進行管理。
https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html
調用 API wx.navigateTo
保留當前頁面,跳轉到應用內的某個頁面。可是不能跳到 tabbar 頁面。
wx.navigateTo({ url: 'test?id=1' }) // test.js Page({ onLoad(option) { console.log(option.query) } })
使用組件
<navigator open-type="navigateTo"/>
調用 API wx.redirectTo
關閉當前頁面,跳轉到應用內的某個頁面。可是不容許跳轉到 tabbar 頁面。
wx.redirectTo({ url: 'test?id=1' })
使用組件
<navigator open-type="redirectTo"/>
調用 API wx.navigateBack
關閉當前頁面,返回上一頁面或多級頁面。
// 注意:調用 navigateTo 跳轉時,調用該方法的頁面會被加入堆棧,而 redirectTo 方法則不會。見下方示例代碼 // 此處是A頁面 wx.navigateTo({ url: 'B?id=1' }) // 此處是B頁面 wx.navigateTo({ url: 'C?id=1' }) // 在C頁面內 navigateBack,將返回A頁面 wx.navigateBack({ delta: 2 })
使用組件
<navigator open-type="navigateBack">
用戶按左上角返回按鈕
調用 API wx.switchTab
跳轉到 tabBar 頁面,並關閉其餘全部非 tabBar 頁面
{ "tabBar": { "list": [ { "pagePath": "index", "text": "首頁" }, { "pagePath": "other", "text": "其餘" } ] } }
wx.switchTab({ url: '/index' })
使用組件
<navigator open-type="switchTab"/>
用戶切換 Tab
調用 API wx.reLaunch
關閉全部頁面,打開到應用內的某個頁面
wx.reLaunch({ url: 'test?id=1' })
使用組件
<navigator open-type="reLaunch"/>
能夠將一些公共的代碼抽離成爲一個單獨的 js 文件,做爲一個模塊。模塊經過 module.exports 能對外暴露接口。
// common.js function sayHello(name) { console.log(`Hello ${name} !`) } module.exports.sayHello = sayHello
const common = require('common.js') Page({ helloMINA() { common.sayHello('MINA') } })
在 JavaScript 文件中聲明的變量和函數只在該文件中有效;不一樣的文件中能夠聲明相同名字的變量和函數,不會互相影響。
經過全局函數 getApp 能夠獲取全局的應用實例,若是須要全局的數據能夠在 App 中設置,如:
// app.js App({ globalData: 1 })
// a.js // Get the app instance. const app = getApp() // Get the global data and change it. app.globalData++
// b.js // 若是是從a跳轉到b,那麼此次輸出的是2 console.log(getApp().globalData)
每一個微信小程序須要事先設置一個通信域名,小程序只能夠跟指定的域名與進行網絡通訊。包括普通 HTTPS 請求(wx.request)、上傳文件(wx.uploadFile)、下載文件(wx.downloadFile) 和 WebSocket 通訊(wx.connectSocket)
==跳過域名校驗==
在微信開發者工具中,能夠臨時開啓 開發環境不校驗請求域名、TLS版本及HTTPS證書 選項,跳過服務器域名的校驗。此時,在微信開發者工具中及手機開啓調試模式時,不會進行服務器域名的校驗。
wx.request({ url: 'test.php', // 僅爲示例,並不是真實的接口地址 data: { x: '', y: '' }, header: { 'content-type': 'application/json' // 默認值 }, success(res) { console.log(res.data) } })
https://developers.weixin.qq.com/miniprogram/dev/api/wx.request.html
每一個微信小程序均可以有本身的本地緩存
==單個 key 容許存儲的最大數據長度爲 1MB,全部數據存儲上限爲 10MB。==
wx.setStorage({ key: 'key', data: 'value' })
try { wx.setStorageSync('key', 'value') } catch (e) { }
wx.getStorage({ key: 'key', success(res) { console.log(res.data) } })
const value = wx.getStorageSync('key')
wx.clearStorage({ success(){} })
wx.clearStorageSync()
wx.removeStorage({ key: 'key', success(res) { console.log(res.data) } })
wx.removeStorageSync('key')
wx.showToast({ title: '成功', icon: 'success', duration: 2000 })
wx.showModal({ title: '提示', content: '這是一個模態彈窗', success(res) { if (res.confirm) { console.log('用戶點擊肯定') } else if (res.cancel) { console.log('用戶點擊取消') } } })
顯示 loading 提示框。需主動調用 wx.hideLoading 才能關閉提示框
wx.showLoading({ title: '加載中', }) setTimeout(function () { wx.hideLoading() }, 2000)
wx.showActionSheet({ itemList: ['A', 'B', 'C'], success(res) { console.log(res.tapIndex) }, fail(res) { console.log(res.errMsg) } })
微信小程序固然還提供其餘能力,具體應查看官方文檔。