中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

小程序的view模塊和service模塊怎么構成

發布時間:2022-03-31 10:13:32 來源:億速云 閱讀:238 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“小程序的view模塊和service模塊怎么構成”,內容詳細,步驟清晰,細節處理妥當,希望這篇“小程序的view模塊和service模塊怎么構成”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

打開微信 web 開發者工具,然后輸入 openVendor() 便會打開 WeappVendor這個目錄,這里包含了 view 模塊和 service  模塊使用的幾個核心文件:

  • wcc 可執行程序,用于將 wxml 轉為 view 模塊使用的 js 代碼,使用方式為wcc xxx.wxml

  • wcsc 可執行程序,用于將 wxss 轉為 view 模塊使用的 css 代碼,使用方式為 wcsc xxx.wxss

  • WAService.js 提供 service 模塊大部分功能,下面會有詳細介紹

  • WAWebview.js 提供 view 模塊大部分功能,下面會有詳細介紹

view 頁面詳解

view 頁面的 template 如下:

<!DOCTYPE html> <html lang="zh-CN"> <head>   <link href="https://res.wx.qq.com/mpres/htmledition/images/favicon218877.ico" rel="Shortcut Icon">   <meta charset="UTF-8" />   <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />    <script>     var __webviewId__;   </script>    <!-- percodes -->    <!--{{WAWebview}}-->    <!--{{reportSDK}}-->    <!--{{webviewSDK}}-->    <!--{{exparser}}-->    <!--{{components_js}}-->    <!--{{virtual_dom}}-->    <!--{{components_css}}-->    <!--{{allWXML}}-->    <!--{{eruda}}-->    <!--{{style}}-->    <!--{{currentstyle}}-->    <!--{{generateFunc}}--> </head>  <body>   <div></div> </body>  </html>

其中 <!-- percodes --> 會在 dev 模式開啟后被替換為一個時間錨點,例如:

<script>var pageFrameStartTime = new Date();</script>

<!--{{WAWebview}}--> 會被 WAWebview.js 內代碼替換

<!--{{WAWebview}}--> 到 <!--{{generateFunc}}--> 之間暫時沒有被使用到

<!--{{generateFunc}}--> 會被 wcc 命令生成后的 js 代碼替換

除了上面這些,頁面上還會被插入頁面和應用的 style 標簽,如:

<link rel="stylesheet" type="text/css" href="index.wxss">

這里的 wxss 文件包含的是原始 wxss 文件轉換后的 css

以及生成 DOM 的啟動腳本:

<script>   document.dispatchEvent(new CustomEvent("generateFuncReady", {     detail: {       generateFunc: $gwx('./page/index.wxml')     }   })) </script>

WAWebview.js 文件中的各個模塊(行號為 jsbeautify 之后代碼行號,開發者工具版本:092300):

  • 1-77 行: WeixinJSBridge 對象兼容層,這個大概只會在調試時用到,因為開發時和運行時頁面都會被后臺以注入的方式添加  WeixinJSBridge 這個對象。我們可以通過這段代碼看到它暴露的方法: invoke invokeCallbackHandleron publish  subscribe subscribe subscribeHandler。

  • 78-235 行:Reporter 對象,它的作用就是發送錯誤和性能統計數據給后臺

  • 236-596 行:wx 對象,頁面的核心之一,一方面封裝 WeixinJSBridge 的 invokeMethod 方位為易于調用的形式(例如  redirectTo, navigateTo等),另一方面封裝 WeixinJSBridge  回調方法,調用者可以使用wx.onAppDataChange(callback) 添加數據變更的回調函數,***提供wx.publishPageEvent  發送頁面事件到后臺

  • 607-1267 行:wxparser 對象,提供 dom 到 wx element 對象之間的映射操作,提供元素操作管理和事件管理功能

  • 1268-1285 行:轉發 window 上的 animation 和 transition 相關的動畫事件到 exparser

  • 1286-1313 行:訂閱并轉發 WeixinJSBridge 提供的全局事件到 exparser

  • 1324-1345 行:轉發 window 上的 error 以及各種表單事件到 exparser

  • 1347-3744 行:使用 exparser.registerBehavior 和exparser.registerElement 方法注冊各種以  wx- 做為標簽開頭的元素到 exparser

  • 3744-4498 行:virtual dom 渲染算法實現,提供 diff apply render 等方法,該模塊接口基本與 virtual-dom  一致,這里特別的地方在于它所 diff 和生成的并不是原生 DOM,而是各種模擬了 DOM 接口的 wx element 對象

  • 4599-4510 行:插入默認樣式到頁面

從頁面 data 到 dom 的主要流程如下:

var vtree var rootNode  document.addEventListener("generateFuncReady", function(e) {   var generateFunc = e.detail.generateFunc;   wx.onAppDataChange(function(obj) {     // 合并 data 到現有 data     DataStore.setData(obj.data)     // 生成 virtual dom 的 javascript plain object     var props = generateFunc(DataStore.getData())      // ***次渲染     if (obj.options.firstRender) {       vtree = createVirtualTree(props, true)       rootNode = vtree.render()       rootNode.replaceDocumentElement(document.body)       wx.initReady()     } else {       var other_vtree = createVirtualTree(props, false)       var patches = vtree.diff(other_vtree)       patches.apply(rootNode)       vtree = other_vtree       document.dispatchEvent(new CustomEvent("pageReRender", {}));     }   }) })

上面的 DataStore 對象提供合并和獲取當前頁面 data 對象的功能,其實現如下:

var DataStore = (function() {   var data = {}   return {     getData: function() {       return data     },     setData: function(e) {       for (var t in e) {         for (var n = (0, parsePath)(t), o = data, a = void 0, s = void 0, c = 0; c < n.length; c++) Number(n[c]) === n[c] && Number(n[c]) % 1 === 0 ? Array.isArray(o) || (a[s] = [], o = a[s]) : "[object Object]" !== Object.prototype.toString.call(o) && (a[s] = {}, o = a[s]), s = n[c], a = o, o = o[n[c]];         a && (a[s] = e[t])       }     }   } })()  // 解析 key 為 data 內對象的路徑字符串 function parsePath(e) {   for (var t = e.length, n = [], i = "", r = 0, o = !1, a = !1, s = 0; s < t; s++) {     var c = e[s];     if ("\\" === c) s + 1 < t && ("." === e[s + 1] || "[" === e[s + 1] || "]" === e[s + 1]) ? (i += e[s + 1], s++) : i += "\\";     else if ("." === c) i && (n.push(i), i = "");     else if ("[" === c) {       if (i && (n.push(i), i = ""), 0 === n.length) throw new Error("path can not start with []: " + e);       a = !0, o = !1     } else if ("]" === c) {       if (!o) throw new Error("must have number in []: " + e);       a = !1, n.push(r), r = 0     } else if (a) {       if (c < "0" || c > "9") throw new Error("only number 0-9 could inside []: " + e);       o = !0, r = 10 * r + c.charCodeAt(0) - 48     } else i += c   }   if (i && n.push(i), 0 === n.length) throw new Error("path can not be empty");   return n }

可以看到,每次 data 變化之后,小程序就會開始整個頁面的 diff patch 過程。

對于原生實現的組件, exparser 會在監視到數據變化后發送對應事件到 WeixinJSBridge。

service 頁面詳解

service 頁面會被被拼接為以下的樣子:

<!DOCTYPE html> <html> <head>   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />   <link href="https://res.wx.qq.com/mpres/htmledition/images/favicon218877.ico" rel="Shortcut Icon">   <script>   var __wxAppData = {}   var __wxRoute   var __wxRouteBegin   </script>   <script>var __wxConfig = {"pages":["page/index"],   // app 相關各種配置   }</script>   <script src="http://70475629.appservice.open.weixin.qq.com/asdebug.js"></script>   <script src="http://70475629.appservice.open.weixin.qq.com/WAService.js"></script>   <script src="http://70475629.appservice.open.weixin.qq.com/app.js"></script>   <script>     __wxRoute = 'page/index';     __wxRouteBegin = true   </script>   <script src="http://70475629.appservice.open.weixin.qq.com/page/index.js"></script> </head>  <body>   <script>     window._____sendMsgToNW({       sdkName: 'APP_SERVICE_COMPLETE'     })   </script> </body>  </html>

除了配置和開發者編寫的頁面、app.js,頁面還在加載了 asdebug.js 和 WAService.js 兩個文件。

asdebug.js 文件位于 nwjs 項目目錄下,路徑為app/dist/weapp/appservice/asdebug.js。  它包含了兩個部分,一個是 WeixinJSBridge 針對 service 模塊的實現,另一塊是一些方便命令使用的接口, 例如:help()  會告訴你一些可用的函數:

小程序的view模塊和service模塊怎么構成

該文件只會在開發者工具內被引入,如果小程序在微信內運行,應該會由微信底層提供 WeixinJSBridge。

WAService 負責 service 模塊的一些核心邏輯,它包含以下部分 (行號為 jsbeautify  之后代碼行號,開發者工具版本:092300):

  • 1-78 行: 跟 WAWebview.js 一樣的 WeixinJSBridge 兼容模塊

  • 79-245 行: 跟 WAWebview.js 一樣的 Reporter 模塊

  • 246-1664 行:比 WAWebview.js 中 wx 功能更為豐富 wx 接口模塊

  • 1665-2304 行:appServiceEngine 模塊,提供 Page,App,GetApp 接口

  • 2305-2360 行: 為 window 對象添加 AMD 接口 require define

現在的 WAService 還有有很多地方依賴 window 對象,所以很有可能它在微信中和開發者工具內一樣,依然運行于 webview  標簽之內。

讀到這里,這篇“小程序的view模塊和service模塊怎么構成”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宁德市| 汉寿县| 丰台区| 红原县| 台南市| 平顶山市| 双牌县| 孟州市| 齐齐哈尔市| 牙克石市| 陵川县| 志丹县| 资溪县| 武威市| 蒙城县| 拉萨市| 新泰市| 策勒县| 华安县| 沁源县| 贵州省| 永靖县| 淄博市| 灵山县| 错那县| 民丰县| 疏勒县| 景宁| 吉隆县| 普安县| 周至县| 广安市| 新邵县| 东源县| 南昌县| 右玉县| 贡觉县| 松江区| 香河县| 宁乡县| 长汀县|