<img src="http://upload-images.jianshu.io/upload_images/280040-fe08cf42989c7906.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="【微信小程序】從入門到放棄" />
前言
關(guān)于微信小程序是什么,能做什么的問題,草民在此不在羅列了僵驰,隨著小程序的天天刷屏蒜茴,想必您也是來吃一些干貨,本篇博文和大家走進(jìn)微信小程序的從入門到放棄~
微信小程序開放功能
草民看過很多的文檔诺核,微信的官方文檔寫的著實(shí)不錯(cuò)了,草民真是發(fā)自內(nèi)心夸贊一下騰訊的這個(gè)能力入客,大家可以前往閱讀,下面通過一張圖來總覽一下小程序開放的功能:
<img src="http://upload-images.jianshu.io/upload_images/280040-89d79024384a7820.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="微信小程序提供接口" />
功能解讀:
微信小程序在UI部分沿用了自己weui的基礎(chǔ)樣式鞍泉,且由于小程序依托于微信app边器,這樣小程序就的很多api可以以橋接的方式來調(diào)用原生接口,包括導(dǎo)航砚嘴、地圖、選擇圖片工育、IO如绸、網(wǎng)絡(luò)、登錄扼脐、支付等功能必然都是通過橋接來實(shí)現(xiàn)的,這也是小程序相比應(yīng)用號(hào)和其他webapp的優(yōu)勢~
微信小程序跨平臺(tái)動(dòng)態(tài)化方案
由于微信小程序源碼并未開源猖毫,關(guān)于微信小程序采用的動(dòng)態(tài)化原理大家也都在猜測中吁断,先簡單普及一下最新的兩種動(dòng)態(tài)化方案:
**hybird **
采用傳統(tǒng)htm+css+js的框架進(jìn)行開發(fā):
優(yōu)點(diǎn):
1.簡單 快速掷伙,模版布局現(xiàn)成卒废,熟練的H5開發(fā)工程師都可以勝任
2.顛覆性的react框架的出現(xiàn)之后引入了Virtual DOM的概念摔认,強(qiáng)大的DOM diff操作是UI更新更加流暢
缺點(diǎn):
1.渲染速度與性能方面的表現(xiàn)依然與原生相差甚遠(yuǎn)
2.從內(nèi)存方面的考慮,列表復(fù)用問題無法解決
** React Native 與 Weex**
優(yōu)點(diǎn):
1.開發(fā)沿用html或xml+css+js的方式,但是通過transform層將html 與 css 轉(zhuǎn)換成Virtual DOM环壤,native端進(jìn)行映射渲染,性能方面大可不必?fù)?dān)心懂酱。
2.在native端植入了JS引擎,這樣就可以擴(kuò)展native api瞎领,調(diào)用一些系統(tǒng)權(quán)限或者擴(kuò)展功能,例如選擇圖片驼修。
缺點(diǎn):
1.雖然沿用了前端傳統(tǒng)開發(fā)方式,但是現(xiàn)階段的html或xml與css的標(biāo)準(zhǔn)性是不夠的,包括svg 蹲坷、css繪制圖標(biāo)等
2.需要了解部分的native知識(shí)轻掩,對(duì)開發(fā)效率方面是一個(gè)降低
通過上面兩種方案的比較唇牧,個(gè)人還是更傾向于后者的,畢竟性能問題依然是很重要的,最初也猜測微信小程序選擇的是后者崖蜜,畢竟開放功能里面有很多是native才擁有的能力。
...
可結(jié)論要讓大家失望了等恐,微信小程序采用的是前者,有很多人依然不相信,說我強(qiáng)大的騰訊帝國不可能選擇落后的方案扎即,來看一張圖片:
了解android的人都知道上圖的意思茎刚,不過為了給其他工種程序員講解膛锭,還是簡單介紹一下這個(gè)功能莫杈,在android的開發(fā)者功能里邊有一個(gè)顯示布局邊界的設(shè)置,這個(gè)功能可以把所有android原生控件的布局邊界都顯示出來关顷,而上圖的navigationBar與底部的bottomBar都是原生的,但是中間大部分內(nèi)容都是webview,也證明了之前的觀點(diǎn)宗雇,微信小程序采用的是Hybird方式。
很多人要開始吐槽說,說草民你講這些沒用啊砾嫉,我們又不關(guān)心原理墙杯,我們只想吃肉高镐,不管是那頭豬身上的观腊,有那么一句話苫耸,不想當(dāng)不想當(dāng)廚子的裁縫不是好司機(jī),想必大家不會(huì)想一直站在別人的肩上寫代碼吧,希望大家能夠領(lǐng)悟到草民做這么多鋪墊的意義渔扎。好吧,話不多說,接下來我們正式開始小程序的講解紧唱。
開發(fā)準(zhǔn)備
一、下載開發(fā)工具
二、添加項(xiàng)目
三、填寫項(xiàng)目信息
appid是小程序的,如果沒有的話,選擇無APPID转捕,填寫完成之后點(diǎn)擊添加項(xiàng)目即可~
項(xiàng)目架構(gòu)
程序主體
1辕万、app.js : 主要存放一些公共的業(yè)務(wù)邏輯醉途,或者監(jiān)聽小程序聲明周期等操作
注:在任意一個(gè)page的js中,都可以通過調(diào)用getApp()獲取app.js對(duì)象
App({
onLaunch: function() {
// Do something initial when launch.
},
onShow: function() {
// Do something when show.
},
onHide: function() {
// Do something when hide.
},
globalData: 'I am global data'
})
操作:
1货葬、App.prototype.getCurrentPage()
getCurrentPage() 函數(shù)用于獲取當(dāng)前頁面的實(shí)例。
2劲够、getApp()
我們提供了全局的 getApp() 函數(shù)余舶,可以獲取到小程序?qū)嵗?/p>
// other.js
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data
注意:
- App() 必須在 app.js 中注冊(cè)庇谆,且不能注冊(cè)多個(gè)。
- 不要在定義于 App() 內(nèi)的函數(shù)中調(diào)用 getApp() 政恍,使用 this 就可以拿到 app 實(shí)例。
- 不要在 onLaunch 的時(shí)候調(diào)用 getCurrentPage()馁菜,此時(shí) page 還沒有生成君仆。
- 通過 getApp() 獲取實(shí)例之后,不要私自調(diào)用生命周期函數(shù)凫岖。
2拐邪、app.json : 設(shè)置界面組成、公共窗口展現(xiàn)隘截、底部tabbar樣式扎阶、超時(shí)時(shí)間等
{
"pages": [
"pages/index/index",
"pages/logs/index"
],
"window": {
"navigationBarTitleText": "Demo"
},
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首頁"
}, {
"pagePath": "pages/logs/logs",
"text": "日志"
}]
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"debug": true
}
3、 app.wxss : 配置公共樣式
定義在 app.wxss 中的樣式為全局樣式婶芭,作用于每一個(gè)頁面~
.container {
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
display: flex;
flex-direction: column;
justify-content: space-between;
box-sizing: border-box;
}
頁面
對(duì)于小程序很多人有一個(gè)錯(cuò)覺东臀,那就是小程序是用html5,這個(gè)真說錯(cuò)了犀农,看看頁面的架構(gòu)惰赋, 小程序是微信全新定義的規(guī)范,是基于XML+JS的,不支持也不兼容HTML赁濒,兼容受限的部分CSS寫法轨奄。
上圖的小程序的page目錄,后綴名分別是wxml拒炎、wxss和js挪拟,不過微信對(duì)wxml的全稱定義也不是weixin xml,而是WeiXin Markup Language击你,同時(shí)wxss也是WeiXin Style Sheets玉组,也說明了小程序開發(fā)將是脫離傳統(tǒng)前端開發(fā)的一種形態(tài),下文介紹四部分的詳細(xì)應(yīng)用~
**index.json : **
界面的配置丁侄,只能設(shè)置 window 相關(guān)的配置項(xiàng)惯雳,以決定本頁面的窗口表現(xiàn),包括navigationBar的標(biāo)題鸿摇、背景石景、顏色及是否允許下拉等
{
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "微信接口功能演示",
"backgroundColor": "#eeeeee",
"backgroundTextStyle": "light"
}
注意:
為了方便開發(fā)者減少配置項(xiàng),規(guī)定描述頁面的這四個(gè)文件必須具有相同的路徑與文件名拙吉。
簡單示例
一鸵钝、 編寫app.js
//app.js
App( {
getUserInfo: function( cb ) {
var that = this
if( this.globalData.userInfo ) {
typeof cb == "function" && cb( this.globalData.userInfo )
} else {
//調(diào)用登錄接口
wx.login( {
success: function() {
wx.getUserInfo( {
success: function( res ) {
that.globalData.userInfo = res.userInfo
typeof cb == "function" && cb( that.globalData.userInfo )
}
})
}
})
}
},
globalData: {
userInfo: null,
},
})
二、配置app.json
增加個(gè)人中心界面
{
"pages": [
"pages/mine/index"
],
"window": {
"backgroundTextStyle": "light",
"backgroundColor": "#ffffff",
"navigationBarBackgroundColor": "#0092ff",
"navigationBarTitleText": "滴答寶",
"navigationBarTextStyle": "white"
}
}
三庐镐、編寫個(gè)人中心界面
目錄結(jié)構(gòu)如下:
1恩商、index.wxml
<!--index.wxml-->
<toast hidden="{{toastHidden}}" duration="1000" bindchange="toastChange">{{toastContent}}</toast>
<view class="container">
<view bindtap="headTap" class="userinfo">
<image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</view>
<block wx:for-index="index" wx:for="{{userListInfo}}">
<view data-index="{{index}}" bindtap="cellItemClick" class="weui_cell" style="margin-top:{{item.margin}};">
<view wx:if="false" class="weui_cell_hd">
<image src="{{item.icon}}"></image>
</view>
<text class="tv_cell_left"> {{item.leftItem}} </text>
<text wx:if="{{item.rightItem}} == null" class="tv_cell_right">{{item.rightItem}}</text>
<view wx:if="{{item.showArrow}}" class="iv-arrow"></view>
</view>
</block>
<view class="v_below">
<text class="tv_server_time">客服電話 400-686-1179</text>
<text class="tv_server_time">服務(wù)時(shí)間 10:00~22:00</text>
<text class="tv_server_time">官方郵箱 dida@shuidihuzhu.com</text>
</view>
</view>
2、index.wxss
.container {
background-color: #F2f2f2;
}
.userinfo {
display: flex;
flex-direction: column;
padding: 50rpx 0;
align-items: center;
background: #0092ff;
}
.userinfo-avatar {
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #333;
}
.weui_cell {
position: relative;
display: flex;
padding: 15px;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border-bottom: 1px solid #dadada;
background-color: white;
}
.weui_cell_hd image {
width: 100%;
height: 20px;
vertical-align: -2px;
}
.tv_cell_left {
position: absolute;
font-size: 30rpx;
color: #333;
left: 20rpx;
}
.tv_cell_right {
position: absolute;
font-size: 28rpx;
color: #999999;
right: 50rpx;
}
.iv-arrow {
position: absolute;
right: 30rpx;
border-top: 2rpx solid #c7c7c7;
border-right: 2rpx solid #c7c7c7;
width: 16rpx;
height: 16rpx;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
}
.v_below {
display: flex;
flex-direction: column;
align-items: center;
}
.tv_server_time {
font-size: 28rpx;
color: #999999;
margin-top: 20rpx;
}
3必逆、index.js
var app = getApp()
Page( {
data: {
userInfo: {},
toastHidden: true,
toastContent: '',
userListInfo: [ {
leftItem: '我的賬戶',
showArrow: true,
}, {
leftItem: '邀請(qǐng)好友 (一起賺錢)',
margin: '20rpx',
showArrow: true,
}, {
leftItem: '我的業(yè)績',
showArrow: true,
}, {
leftItem: '用戶協(xié)議',
margin: '20rpx',
showArrow: true,
}, {
leftItem: '當(dāng)前版本',
rightItem: 'V 1.0.0 (內(nèi)測版)',
margin: '20rpx',
showArrow: false,
}]
},
onLoad: function() {
var that = this
//調(diào)用應(yīng)用實(shí)例的方法獲取全局?jǐn)?shù)據(jù)
app.getUserInfo( function( userInfo ) {
//更新數(shù)據(jù)
that.setData( {
userInfo: userInfo
})
})
},
toastChange: function() {
this.setData( {
toastHidden: true
})
},
headTap( e ) {
//更新數(shù)據(jù)
this.setData( {
toastHidden: false,
toastContent: "點(diǎn)擊頭部"
})
},
cellItemClick( e ) {
var index = e.currentTarget.dataset.index
console.log( "index = " + index )
//更新數(shù)據(jù)
this.setData( {
toastHidden: false,
toastContent: "點(diǎn)擊" + index
})
},
})
整體代碼十分簡單怠堪,這里只是想讓您看到基本的效果演示,如果需要更深層次的使用名眉,大家還請(qǐng)到官方文檔閱讀粟矿,相信您幾個(gè)小時(shí)就可以搞定,簡單的集成演示就介紹到這里~
技術(shù)缺陷
一定會(huì)有人發(fā)出疑問损拢,微信小程序就那么優(yōu)秀嗎陌粹?沒有問題、沒有坑嗎福压?
答:肯定是有的掏秩,在這里草民表達(dá)一下自己對(duì)程序框架的看點(diǎn),代碼世界的框架只有兩種荆姆,第一種是天天被吐槽的蒙幻,第二種是沒人用的,希望大家還是要以發(fā)現(xiàn)美的眼光去看待一個(gè)框架胆筒,同時(shí)還要用挑剔的眼光去審視一個(gè)框架邮破,采用發(fā)現(xiàn)問題,提出問題,解決問題的方式進(jìn)行優(yōu)化抒和。
下面我介紹點(diǎn)在微信小程序開發(fā)時(shí)一些不爽的地方矫渔,其他問題都是可以解決的,草民只是提幾個(gè)代碼層級(jí)的問題摧莽,這也是我最注重的:
1庙洼、操作反饋組件
小程序提供了四種操作反饋組件,action-sheet范嘱、modal、toast员魏、loading丑蛤,想法很好,而且多數(shù)框架都有撕阎,可草民不理解的就是受裹,您不能封裝成module來使用嗎?
看下官方使用方式:
我希望的方式是這樣的:
var toast = require('@wx-module/model')
modal.toast({
'message': ‘toast 消息內(nèi)容’,
'duration': 1000
})
不知道大家的想法是怎樣的虏束,反正草民是非常遵循傻瓜式編程的~
2棉饶、template 模板封裝
和大家表明一下,小程序的template模板只支持wxml的引入镇匀,并不支持具體的業(yè)務(wù)邏輯與css樣式照藻,這也是本人接受不了的現(xiàn)實(shí),我想封裝一個(gè)組件汗侵,組件中沒有業(yè)務(wù)邏輯幸缕,我管他叫什么?組件化開發(fā)是這樣定義的嗎晰韵?希望騰訊下一版本迭代是將此問題解決发乔。
3、不支持配置別名雪猪,只能采用相對(duì)路徑的方式進(jìn)行require
看一下require的方式:
var router = require('../../config/router.js')
草民想冒昧問一句栏尚,這個(gè)../..您看著爽嗎,和下面這個(gè)比如何只恨?
var router = require('root/config/router.js')
4译仗、適配方案 rpx(responsive pixel)
微信小程序新定義了一個(gè)尺寸單位,可以適配不同分辨率的屏幕官觅,它規(guī)定屏幕寬為750rpx古劲,如在 iPhone6 上,屏幕寬度為375px缰猴,共有750個(gè)物理像素产艾,則750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
項(xiàng)目中我大多數(shù)都采用rpx進(jìn)行適配闷堡,但是有時(shí)1rpx有時(shí)顯示不出來隘膘,而且當(dāng)我設(shè)置750rpx時(shí),在android手機(jī)顯示不滿一屏杠览,就是說在android屏幕上并沒有按照模板750rpx進(jìn)行適配或者說適配方案存在問題弯菊,也希望開發(fā)者在使用時(shí)注意。
運(yùn)營問題:
送大家一個(gè)彩蛋吧踱阿,在這里提醒一下大家運(yùn)營小程序時(shí)可能出現(xiàn)的問題管钳,希望大家在運(yùn)營時(shí)避免以下幾點(diǎn),防止犯一些不必要的錯(cuò)誤導(dǎo)致影響運(yùn)營效果與項(xiàng)目進(jìn)度~
提交「小程序」時(shí)需要注意哪些地方软舌,才不會(huì)被拒才漆?
1、小程序的名稱必須和所提供的服務(wù)有所關(guān)聯(lián)佛点,而且必須是兩個(gè)詞以上的組合醇滥,不能使用廣泛使用不具備識(shí)別性的詞語來命名,比如日歷超营、電話鸳玩。
2、提交小程序?qū)彶闀r(shí)演闭,頭像 LOGO 要盡量使用清晰度高的圖片不跟,這個(gè)清晰度是指可以看清、分別米碰、圖片中包含的元素躬拢,否則微信不予通過。
3见间、微信希望聊闯,用戶打開小程序的時(shí)候直接就能使用到相關(guān)的功能,因此這份文檔提到米诉,用戶在小程序的頁面就能使用到相關(guān)的服務(wù)菱蔬,不能隱藏,也不能進(jìn)行多次跳轉(zhuǎn)史侣。有特別規(guī)定拴泌,「小程序首頁必須能夠直達(dá)或者經(jīng)過 2 次點(diǎn)擊到達(dá)」相關(guān)的功能。
4惊橱、小程序的功能不能過于簡單蚪腐,比如說只有一個(gè)頁面,或只提供一個(gè)按鈕税朴。
5回季、小程序不能展示家制、推薦第三方小程序,不能做小程序?qū)Ш脚菀弧⒒ネ撇埂⑿〕绦蚺判邪竦取R膊荒芡ㄟ^小程序來搜索其它小程序鼻忠。
6涵但、用戶使用小程序時(shí),不能以關(guān)注或使用其它小程序作為條件帖蔓。
7矮瘟、禁止誘導(dǎo)分享,這個(gè)不用再說塑娇,微信對(duì)此一直嚴(yán)厲打壓澈侠。
8、小程序不能用作營銷活動(dòng)钝吮、廣告用途埋涧,不能存在類似算命板辽、星座運(yùn)勢之類的測試類內(nèi)容奇瘦,不能包含賭博競猜抽獎(jiǎng)等內(nèi)容。
9劲弦、小程序里面的圖片耳标,不能包含廣告、網(wǎng)址邑跪。
運(yùn)營「小程序」的時(shí)候次坡,需要注意哪些地方,才不會(huì)下架画畅?
1砸琅、微信不允許批量注冊(cè)、重復(fù)提交大量類似的小程序轴踱。
2症脂、小程序的添加,不能設(shè)置付費(fèi)淫僻,必須是免費(fèi)添加诱篷。
3、如果你的微信小程序含有支付功能雳灵,需要在簡介當(dāng)中明確指示棕所。
4、如果你希望通過小程序創(chuàng)業(yè)悯辙,需要注意:如果小程序所屬的公司被收購或合并琳省,你從微信和微信小程序接收的小程序里繼續(xù)使用迎吵。
5、如果小程序使用到地理位置定位功能岛啸,在采集钓觉、 獲取用戶地理位置時(shí)必須得到用戶的同意。
6坚踩、小程序后臺(tái)服務(wù)荡灾,僅限于集中目的:VoIP、音頻播放瞬铸、地理位置批幌、完成任務(wù)和本地提醒。
7嗓节、禁止多媒體比如音頻荧缘、視頻的自動(dòng)播放。
結(jié)語
從入門到放棄到此結(jié)束拦宣,大家酌情吸收截粗,希望能夠?qū)Υ蠹矣兴鶐椭x謝(-_-)