⼩程序(微信)【面试】
?程序
1 登錄
unionid和openid
了解?程序登陸之前,我們寫了解下?程序/公眾號登錄 涉及到兩個最關鍵的? 戶標識:OpenId 是?個?戶對于?個?程序/公眾號的標識,開發者可以通過這個標識識別出? 戶。
UnionId 是?個?戶對于同主體微信?程序/公眾號/ APP 的標識,開發者需要在微信 開放平臺下綁定相同賬號的主體。開發者可通過 UnionId ,實現多個?程序、公眾號、甚 ?APP 之間的數據互通了。
關鍵Api
登錄流程設計
利?現有登錄體系
利? OpenId 創建?戶體系
OpenId 是?個?程序對于?個?戶的標識,利?這?點我們可以輕松的實 現?套基于?程序的?戶體系,值得?提的是這種?戶體系對?戶的打擾最 低,可以實現靜默登錄。具體步驟如下?程序客戶端通過 wx.login 獲取 code傳遞 code 向服務端,服務端拿到 code 調?微信登錄憑證校驗接?,微信服務器返回openid 和會話密鑰session_key ,此時開發者服務端便可以利? openid ?成?戶 ?庫,再向?程序客戶端返回?定義登錄態。
?程序客戶端緩存 (通過 storage )?定義登錄態( token ),后續調?接?時攜帶該 登錄態作為?戶身份標識即可
利? Unionid 創建?戶體系
如果戶關注了某個相同主體公眾號,或曾經在某個相同主體 App 、公眾號上進?過微信登 錄授權,通過 wx.login 可以直接獲取 到 unionid
結合 wx.getUserInfo 和 這兩種?式引導?戶主動授權,主動授權后通過返回的信息和服務端交互 (這?有?步需要服務端解 密數據的過程,很簡單,微信提供了示例代碼) 即可拿到 unionid 建??戶體系, 然后 由服務端返回登錄態,本地記錄即可實現登錄,附上微信提供的最佳實踐
調? wx.login 獲取 code ,然后從微信后端換取session_key ,?于解密getUserInfo 返回的敏感數據
使? wx.getSetting 獲取?戶的授權情況
如果?戶已經授權,直接調? API wx.getUserInfo 獲取?戶最新的信息;
?戶未授權,在界?中顯示?個按鈕提示?戶登?,當?戶點擊并授權后就獲取到? 戶的最新信息
獲取到?戶數據后可以進?展示或者發送給??的后端
注意事項
需要獲取 unionid 形式的登錄體系,在以前(18年4?之前)是通過以下這種? 式來實現,但后續微信做了調整(因為?進??程序,主動彈起各種授權彈窗的這 種形式,?較容易導致?戶流失),調整為必須使?按鈕引導?戶主動授權的? 式,這次調整對開發者影響較?,開發者需要注意遵守微信的規則,并及時和業務 ?溝通業務形式,不要存在僥幸?理,以防造成?程序不過審等情況.
因為?程序不存在 cookie 的概念, 登錄態必須緩存在本地,因此強烈建議為登錄態設置過期時間 值得?提的是如果需要?持?控安全校驗,多平臺登錄等功能,可能需要加??些公共參數,例如 platform , channel , deviceParam 等參數。在和服務端確 定?案時,作為前端同學應該及時提出這些合理的建議,設計合理的系統。
openid , unionid 不要在接?中明?傳輸,這是?種危險的?為,同時也很
不專業.
2 圖?導出
這是?種常?的引流?式,?般同時會在圖?中附加?個?程序?維碼。基本原理
借助 canvas 元素,將需要導出的樣式?先在 canvas 畫布上繪制出來 ( api 基本和h5 保持?致,但有輕微差異,使?時注意即可。
借助微信提供的 canvasToTempFilePath 導出圖?,最后再使?saveImageToPhotosAlbum (需要授權)保存圖?到本地。
如何優雅實現
繪制出需要的樣式這?步是省略不掉的。但是我們可以封裝?個繪制庫,包含常?圖形的繪制,例如矩形,圓?矩形,圓, 扇形,三?形, ?字,圖?減少繪制代碼,只需要提煉 出樣式信息,便可以輕松的繪制,最后導出圖?存?相冊。筆者覺得以下這種?式繪制更為優雅清晰?些,其實也可以使?加??個type參數來指定繪制類型,傳?的?個是樣式 數組,實現繪制。
結合上?步的實現,如果對于同?類型的卡?有多次導出需求的場景,也可以使??定義 組件的?式,封裝同?類型的卡?為?個通?組件,在需要導出圖?功能的地?,引?該 組件即可。
注意事項
?程序中?法繪制?絡圖?到 canvas 上,需要通過 downLoadFile 先下載圖? 到本地臨時?件才可以繪制 通常需要繪制?維碼到導出的圖?上,有?種?式導出?維碼時,需要攜帶的參數 必須做編碼,?且有具體的?度( 32 可?字符)限制,可以借助服務端?成短鏈接 的?式來解決。3 數據統計
數據統計作為?前?種常?的分析?戶?為的?式,?程序端也是必不可少 的。?程序采取的曝光,點擊數據埋點其實和h5原理是?樣的。但是埋點作為?個和業務邏輯不相關的需求,我們如果在每?個點擊事件,每?個?命周期加?各種埋點代碼,則會?擾正常的業務邏輯,和使代碼變的臃腫,筆者提供 以下?種思路來解決數據埋點。
?程序的代碼結構是,每?個 Page 中都有?個 Page ?法,接受?個包含 ?命周期函數,數據的 業務邏輯對象 包裝這層數據,借助?程序的底層邏輯實現??的業務邏輯。通過這個我們可以想到思路,對 Page 進??次包裝, 篡改它的?命周期和點擊事件,混?埋點代碼,不?擾業務邏輯,只要做?些 簡單的配置即可埋點,簡單的代碼實現如下:
這種思路不光適?于埋點,也可以?來作全局異常處理,請求的統?處理等場景。
分析接?
對于特殊的?些業務,我們可以采取 接?埋點,什么叫接?埋點呢?很多情況下,我們有的 api 并不是多處調?的,只會在某?個特定的??調?,通過這個思路我們可以分析出,該接?被請求,則這個?為被觸發了,則完全可以通過服務端?志得出埋點數據,但是這種?式局限性較?,?且屬于分析結果 得出過程,可能存在誤差,但可以作為?種思路了解?下。
4 ?程化
?程化做什么
?前的前端開發過程,?程化是必不可少的?環, 那?程序?程化都需要做些什么呢, 先看下?前?程序開發當中存在哪些問題需要解決:不?持 css 預編譯器,作為?種主流的 css 解決?案,不論是 less , sass , stylus都可以提升 css 效率 不?持引?npm包 (這?條,從微信公開課中聽聞,微信準備?持) 不?持 ES7 等后續的 js 特性,好?的 async await 等特性都?法使? 不?持引?外部字體?件,只?持 base64
沒有 eslint 等代碼檢查?具。
?案選型
具體開發思路
通過 gulp 的 task 實現:實時編譯 less ?件?相應?錄 。
引??持 async , await 的運?時?件 。
編譯字體?件為 base64 并?成相應 css ?件,?便使?。
依賴分析哪些地?引?了 npm 包,將 npm 包打成?個?件,拷??相應?錄。
檢查代碼規范。
5 ?程序架構
微信?程序的框架包含兩部分 View 視圖層、 App Service 邏輯層。
View 層?來渲染??結構, AppService 層?來邏輯處理、數據請求、接?調?。
它們在兩個線程?運?。
視圖層使? WebView 渲染, iOS 中使??帶 WKWebView ,在 Android 使?騰訊的x5 內核(基于 Blink )運?。
邏輯層使?在 iOS 中使??帶的 JSCore 運?,在 Android 中使?騰訊的 x5 內核 (基于 Blink )運?。 開發?具使? nw.js 同時提供了視圖層和邏輯層的運?環境。
6 WXML && WXSS
WXML
?持數據綁定 。
?持邏輯算術、運算。
?持模板、引? ?持添加事件( bindtap )。
Wxml 編譯器: Wcc 把 Wxml ?件 轉為 JS。
執??式: Wcc index.wxml
使? Virtual DOM ,進?局部更新。
WXSS
wxss編譯器: wcsc 把 wxss ?件轉化為 js
執??式: wcsc index.wxss
尺?單位 rpx
rpx(responsive pixel ): 可以根據屏幕寬度進??適應。規定屏幕寬為750rpx 。公式:
樣式導?
使? @import 語句可以導?外聯樣式表, @import 后跟需要導?的外聯樣 式表的相對路徑,? ; 表示語句結束。
內聯樣式靜態的樣式統?寫到 class 中。 style 接收動態的樣式,在運?時會進?解析,請盡量避免將靜態的樣式寫進 style中,以免影響渲染速度
全局樣式與局部樣式
定義在 app.wxss 中的樣式為全局樣式,作?于每?個??。在 page 的wxss ?件中定義的樣式為局部樣式,只作?在對應的??,并會覆蓋app.wxss 中相同的選擇器 。
7 ?程序的問題
?程序仍然使? WebView 渲染,并?原?渲染。(部分原?) 服務端接?返回的頭?法執?,?如: Set-Cookie 。
依賴瀏覽器環境的 JS 庫不能使?。
不能使? npm ,但是可以?搭構建?具或者使? mpvue 。(未來官?有計劃?持)。
不能使? ES7 ,可以??? babel+webpack ?搭或者使? mpvue 。 不?持使???的字體(未來官?計劃?持)。
可以? base64 的?式來使? iconfont 。
?程序不能發朋友圈(可以通過保存圖?到本地,發圖?到朋友前。?維碼可以使?B接?)。
獲取?維碼/?程序接?的限制
程序推送只能使?“服務通知” ?且需要?戶主動觸發提交 formId , formId 只有7天有 效期。(現在的做法是在每個??都放? form 并且隱藏以此獲取更多的 formId 。后端 使?原則為:優先使?有效期最短的)。
?程序??限制 2M,分包總計不超過 8M 。
轉發(分享)?程序不能拿到成功結果,原來可以。鏈接(?游戲造的孽)。
拿到相同的 unionId 必須綁在同?個開放平臺下。開放平臺綁定限制:
50 個移動應?
10 個?站
50 個同主體公眾號
5 個不同主體公眾號
50 個同主體?程序
5 個不同主體?程序
公眾號關聯?程序
所有公眾號都可以關聯?程序。
?個公眾號可關聯10個同主體的?程序,3個不同主體的?程序。
?個?程序可關聯500個公眾號。
公眾號?個?可新增關聯?程序13次,?程序?個?可新增關聯500次。
?個公眾號關聯的10個同主體?程序和3個?同主體?程序可以互相跳轉 品牌搜索不?持?融、醫療 。
?程序授權需要?戶主動點擊
?程序不提供測試 access_token
安卓系統下,?程序授權獲取?戶信息之后,刪除?程序再重新獲取,并重新授權,得到 舊簽名,導致第?次授權失敗
開發者?具上,授權獲取?戶信息之后,如果清緩存選擇全部清除,則即使使?了wx.checkSession ,并且在 session_key 有效期內,授權獲取?戶信息也會得到新的
session_key
8 授權獲取?戶信息流程
session_key 有有效期,有效期并沒有被告知開發者,只知道?戶越頻繁使??程序,session_key 有效期越?。
在調? wx.login 時會直接更新 session_key ,導致舊session_key 失效 ?程序內先調? wx.checkSession 檢查登錄態,并保證沒有過期的 session_key 不會 被更新,再調? wx.login 獲取 code 。接著?戶授權?程序獲取?戶信息,?程序拿到加密后的?戶數據,把加密數據和 code 傳給后端服務。后端通過 code 拿到session_key 并解密數據,將解密后的?戶信息返回給?程序。
?試題:先授權獲取?戶信息再 login 會發?什么?
?戶授權時,開放平臺使?舊的 session_key 對?戶信息進?加密。調? wx.login重新登錄,會刷新 session_key ,這時后端服務從開放平臺獲取到新 session_key , 但是?法對? session_key 加密過的數據解密,?戶信息獲取失敗 在?戶信息授權之前先調? wx.checkSession 呢? wx.checkSession 檢查登錄態,并 且保證 wx.login 不會刷新session_key ,從?讓后端服務正確解密數據。但是這?存在?個問題,如果?程序較?時間不?導致 session_key 過期,則 wx.login 必定會重 新?成 session_key ,從?再?次導致?戶信息解密失敗。
9 性能優化
我們知道 view 部分是運?在 webview 上的, 所以前端領域的?多數優化?式都有?。加載優化
?程序加載的三個階段的表示
優化?式
代碼壓縮。
及時清理??代碼和資源?件。
減少代碼包中的圖?等資源?件的??和數量。
分包加載。
?屏加載的體驗優化建議
提前請求: 異步數據請求不需要等待??渲染完成。
利?緩存: 利? storage API 對異步請求數據進?緩存,?次啟動時先利?緩存數據渲染??,在進?后臺更新。
避免?屏:先展示???架?和基礎內容。
及時反饋:即時地對需要?戶等待的交互操作給出反饋,避免?戶以為?程序?響應。
使?分包加載優化
在構建?程序分包項?時,構建會輸出?個或多個功能的分包,其中每個分包?程序必定 含有?個主包,所謂的主包,即放置默認啟動??/ TabBar ??,以及?些所有分包都需 ?到公共資源/ JS 腳本,?分包則是根據開發者的配置進?劃分。
在?程序啟動時,默認會下載主包并啟動主包內??,如果?戶需要打開分包內某個? ?,客戶端會把對應分包下載下來,下載完成后再進?展示。
優點:
對開發者??,能使?程序有更?的代碼體積,承載更多的功能與服務。
對?戶??,可以更快地打開?程序,同時在不影響啟動速度前提下使?更多功能。
整個?程序所有分包??不超過 8M
單個分包/主包??不能超過 2M
原?分包加載的配置 假設?持分包的?程序?錄結構如下
開發者通過在 app.json subPackages 字段聲明項?分包結構。
{ "pages":[ "pages/index", "pages/logs" ], "subPackages": [ { "root": "packageA", "pages": [ "pages/cat", "pages/dog" ] }, { "root": "packageB", "pages": [ "pages/apple", "pages/banana" ] } ]分包原則
聲明 subPackages 后,將按 subPackages 配置路徑進?打包, subPackages 配置路 徑外的?錄將被打包到 app (主包) 中。
app (主包)也可以有??的 pages (即最外層的 pages 字段。
subPackage 的根?錄不能是另外?個 subPackage 內的??錄 。
??的 TAB ??必須在 app (主包)內。
引?原則
packageA ?法 require packageB JS ?件,但可以 require app 、?? package 內的 JS` ?件。
packageA ?法 import packageB 的 template ,但可以 require app 、?? package 內的 template`
packageA ?法使? packageB 的資源,但可以使? app 、?? package` 內的資源。
官?即將推出 分包預加載(截止目前還沒推出)
獨?分包
渲染性能優化
每次 setData 的調?都是?次進程間通信過程,通信開銷與 setData 的數據量正相關。
setData 會引發視圖層??內容的更新,這?耗時操作?定時間中會阻塞?戶交互。
setData 是?程序開發使?最頻繁,也是最容易引發性能問題的。
避免不當使? setData
使? data 在?法間共享數據,可能增加 setData 傳輸的數據量。。 data 應僅包括 與??渲染相關的數據。
使? setData 傳輸?量數據,通訊耗時與數據正相關,??更新延遲可能造成??更新 開銷增加。僅傳輸??中發?變化的數據,使? setData 的特殊 key 實現局部更新。 短時間內頻繁調? setData ,操作卡頓,交互延遲,阻塞通信,??渲染延遲。避免不必要的 setData ,對連續的 setData 調?進?合并。
在后臺??進? setData ,搶占前臺??的渲染資源。??切?后臺后的 setData 調 ?,延遲到??重新展示時執?。
避免不當使?onPageScroll
只在有必要的時候監聽 pageScroll 事件。不監聽,則不會派發。
避免在 onPageScroll 中執?復雜邏輯。
避免在 onPageScroll 中頻繁調? setData
避免滑動時頻繁查詢節點信息( SelectQuery )?以判斷是否顯示,部分場景建議使?節 點布局橡膠狀態監聽( inersectionObserver )替代。
使??定義組件
10 wepy vs mpvue
相?傳統的?程序框架,這個?直是我們作為資深開發者?較期望去解決的, 在 Web 開發中,隨著 Flux 、 Redu x、 Vuex 等多個數據流?具出現, 我們也期望在業務復雜的?程序中使?。
WePY 默認?持 Redux ,在腳?架?成項?的時候可以內置
Mpvue 作為 Vue 的移植版本,當然?持 Vuex ,同樣在腳?架?成項?的時候可以內置。
組件化
WePY 類似 Vue 實現了單?件組件,最?的差別是?件后綴 .wpy ,只是寫法上會有差異。
Mpvue 作為 Vue 的移植版本,?持單?件組件, template 、 script 和 style都在?個 .vue ?件中,和 vue 的寫法類似,所以對 Vue 開發熟悉的同學會?較適應。現在主流前端框架:Anglar,react,Vue,都可以了解一下。
?程化
wepy 內置了構建,通過 wepy init 命令初始化項?,?致流程如下:
wepy-cli 會判斷模版是在遠程倉庫還是在本地,如果在本地則會?即跳到第 3 步, 反之繼續進?。
會從遠程倉庫下載模版,并保存到本地。
詢問開發者 Project name 等問題,依據開發者的回答,創建項?。
mpvue 沿?了 vue 中推崇的 webpack 作為構建?具,但同時提供了?些??的插件 以及配置?件的?些修改,?如 :
11 mpvue
mpvue
Vue.js ?程序版, fork ? vuejs/vue@2.4.1 ,保留了 vue runtime 能?, 添加了?程序平臺的?持。 mpvue 是?個使? Vue.js 開發?程序的前端框架。
框架基于 Vue.js 核?, mpvue 修改了 Vue.js 的 runtime 和 compiler 實 現,使其可以運?在?程序環境中,從?為?程序開發引?了整套 Vue.js 開發體驗。
框架原理
兩個??向:
通過 mpvue 提供 mp 的 runtime 適配?程序
通過 mpvue-loader 產出微信?程序所需要的?件結構和模塊內容。
七個具體問題:
要了解 mpvue 原理必然要了解 Vue 原理,這是?前提:
現在假設您對 Vue 原理有個?概的了解。那么接下來會有幾個問題請帶入思考。(Vue不熟練的同學可以先收藏起來,以后再看哈)
由于 Vue 使?了 Virtual DOM ,所以 Virtual DOM 可以在任何?持 JavaScript語?的平臺上操作,譬如說?前 Vue ?持瀏覽器平臺或 weex ,也可以是 mp (?程 序)。那么最后 Virtual DOM 如何映射到真實的 DOM 節點上呢? vue 為平臺做了?層適配層,瀏覽器平臺? runtime/node-ops.js 、 weex 平臺? runtime/nodeops.js ,?程序? runtime/node-ops.js 。不同平臺之間通過適配層對外提供相同的接 ?, Virtual DOM 進?操作 Real DOM 節點的時候,只需要調?這些適配層的接?即可,?內部實現則不需要關?,它會根據平臺的改變?改變 所以思路肯定是往增加?個 mp 平臺的 runtime ?向?。但問題是?程序不能操作DOM ,所以 mp 下的 node-ops.js ??的實現都是直接 return obj
新 Virtual DOM 和舊 Virtual DOM 之間需要做?個 patch ,找出 diff 。 patch完了之后的 diff 怎么更新視圖,也就是如何給這些 DOM 加? attr 、 class 、style 等 DOM 屬性呢? Vue 中有 nextTick 的概念?以更新視圖, mpvue 這塊對于 ?程序的 setData 應該怎么處理呢? 另外個問題在于?程序的 Virtual DOM 怎么?成?也就是怎么將 template 編譯成 render function 。這當中還涉及到運?時-編譯器-vs-只包含運?時,顯然如果要提? 性能、減少包??、輸出 wxml 、 mpvue 也要提供預編譯的能?。因為要預輸出 wxml 且沒法動態改變 DOM ,所以動態組件,?定義 render ,和 <script type="text/xtemplate"> 字符串模版等都不?持
另外還有?些其他問題,最后總結?下
1.如何預編譯?成 render function 2.如何預編譯?成 wxml , wxss , wxs 3.如何 p atch 出 diff 4.如何更新視圖 5.如何建??程序事件代理機制,在事件代理函數中觸發與之對應的 vue 組件事件響應。 6.如何建? vue 實例與?程序 Page 實例關聯。 7.如何建??程序和 vue ?命周期映射關系,能在?程序?命周期中觸發 vue ?命周期。
platform/mp 的?錄結構
mpvue-loader
mpvue-loader 是 vue-loader 的?個擴展延伸版,類似于超集的關系, 除了 vue-loader 本身所具備的能?之外,它還會利? mpvue-templatecompiler ?成 render function
它會從 webpack 的配置中的 entry 開始,分析依賴模塊,并分別打包。在 entry 中
app 屬性及其內容會被打包為微信?程序所需要的 app.js/app.json/app.wxss ,其 余的會?成對應的?? page.js / page.json / page.wxml / page.wxss ,如示例的 entry 將會?成如 下這些?件,?件內容下?慢慢講來:
wxml 每?個 .vue 的組件都會被?成為?個 wxml 規范的 template , 然后通過 wxml 規范的 import 語法來達到?個復?,同時組件如果涉及到props 的 data 數據,我們也會做相應的處理,舉個實際的例?:
<template><div class="my-component" @click="test"><h1>{{msg}}</h1><other-component :msg="msg"></other-component></div> </template> <script> import otherComponent from './otherComponent.vue' export default {components: { otherComponent },data () {return { msg: 'Hello Vue.js!' }},methods: {test() {}} } </script>這樣?個 Vue 的組件的模版部分會?成相應的 wxml
<import src="components/other-component$hash.wxml" /> <template name="component$hash"><view class="my-component" bindtap="handleProxy"><view class="_h1">{{msg}}</view><template is="other-component$hash" wx:if="{{ $c[0] }}" data="{{ ..</view> </template>可能已經注意到了 other-component(:msg=“msg”) 被轉化成了 。 mpvue在運?時會從根組件開始把所有的組件實例數據合并成?個樹形的數據,然后通過 setData 到 appData , $c 是 $children 的縮寫。?于那個 0 則 是我們的 compiler 處理過后的?個標記,會為每?個?組件打?個特定的 不重復的標記。 樹形數據結構如下。
// 這?數據結構是?個數組,index 是動態的 { $child: { '0'{ // ... root data $child: { '0': { // ... data msg: 'Hello Vue.js!', $child: { // ...data } } } } } }wxss
這個部分的處理同 web 的處理差異不?,唯?不同在于通過配置?成.css 為 .wxss ,其中的對于 css 的若?處理,在 postcss-mpvuewxss 和 px2rpx-loader 這兩部分的?檔中?詳細的介紹。
推薦和?程序?樣,將 app.json/page.json 放到????處,使? copy-webpackplugin copy 到對應的?成位置。
這部分內容來源于 app 和 page 的 entry ?件,通常習慣是 main.js , 你需要在你的???件中 export default { config: {} } ,這才能被我 們的 loader 識別為這是?個配置,需要寫成 json ?件。
每天一句中文式外語
泰語
1、你好!/Sa-wa-di-ka薩瓦迪卡(男生要說:薩瓦迪卡撲)/Hello!/Hi!?
2、你好嗎?/sa-bai-di-mai薩拜迪麥/How?are?you?
3、我還好!/sa-bai-di薩拜迪/I?am?fine!? ?
4、您叫什么名字?/kun-ci-a-lai坤賜阿萊/what?is?your?name??? ??
5、你去哪里?/kun-bai-nai?坤拜奈/where?are?you?going??? 6、再見!/la-gong?拉拱(聯想記憶:拉弓射箭:那就是再見了)/?Good?Bye!/Bye?Bye ?
7、祝好運!/cuo-di措迪(聯想記憶:用腳搓地表示好運)/?Good?Luck!?? ??
8、謝謝你!/kuo-kun擴坤/Thank?you! ?
9、對不起!/kuo-tuo擴拓?/sorry!/Excuse?me!
10、不要緊!沒關系!/mai-bian-lai賣鞭來(窮的要命,但是心愛的馬兒舍不得賣,那就賣鞭來生活。賣鞭來)/never?mind!
(日常會常用的我用紅字標識出來了)對了,英語是國際通用語言,一定要重視起來喲!
總結
以上是生活随笔為你收集整理的⼩程序(微信)【面试】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【已解决】window 更新:*某些设置
- 下一篇: 大厂面试干货:面试官最喜欢pick什么样