摘要:傳統(tǒng)的網(wǎng)頁編程采用的三劍客來實現(xiàn),在微信小程序中同樣有三劍客。觀察者模式不難實現(xiàn),重點是如何在微信小程序中搭配其特有的生命周期來使用。交互事件傳統(tǒng)的事件傳遞類型有冒泡型與捕獲型,微信小程序中自然也有。
本文由作者鄒永勝授權(quán)網(wǎng)易云社區(qū)發(fā)布。
簡介
為了更好的展示我們即時通訊SDK強(qiáng)悍的能力,網(wǎng)易云信IM SDK微信小程序DEMO的開發(fā)就提上了日程。用產(chǎn)品的話說就是:
云信 IM 小程序 SDK 的能力演示
提供開發(fā)者小程序開發(fā)參考
換句話說就是在微信里面通過我們云信的IM SDK再實現(xiàn)一個mini版微信。整個小程序主要功能點總的來說是:
登錄注冊(為了實現(xiàn)不同端同一賬號體系,所以沒有采用微信授權(quán)登錄)
最近會話展示
通訊錄
單聊對話
用戶名片
廢話不多說直接上圖:
一期已經(jīng)上線,不足的地方,懇請斧正
本文從基礎(chǔ)開始介紹在開發(fā)云信DEMO的過程中的一些難點、整體的結(jié)構(gòu)設(shè)計、思考的一些解決方案以及踩過的一些坑,希望對大家有些幫助當(dāng)然希望更多人接入網(wǎng)易云信SDK。
基礎(chǔ)
小程序開發(fā)基本零門檻,難度基本與模板語言相當(dāng),如果你有使用MVVM框架開發(fā)前端的經(jīng)驗,基本花個半小時過一遍微信小程序官方文檔,即可入門,具體開發(fā)細(xì)節(jié)可以邊做邊查本人就是這樣的。。。。
首先需要明白小程序的運行環(huán)境,它運行在微信的上下文中,處于微信這個沙盒中,沒有window對象,不能訪問基于browser context下的DOM。在ios設(shè)備上是運行在JSCore(蘋果開發(fā)),在android設(shè)備上則是在X5(騰訊基于webkit開發(fā)),在開發(fā)工具中運行在nwjs(同類型還有electron)
一個標(biāo)準(zhǔn)的小程序是由一個應(yīng)用實例以及多個頁面實例構(gòu)成。仔細(xì)想來微信小程序不就是由多個相互關(guān)聯(lián)的頁面組成的嘛,在每個頁面中,需要考慮與外部以及與其他頁面進(jìn)行交互。本著“3W+1H”原則,因此也就可以提煉出在開發(fā)整個IM DEMO過程中需要關(guān)注的點:
如何定義頁面、修改樣式
頁面怎么進(jìn)行屏幕適配
多頁面間怎么進(jìn)行通信
每個頁面的生命周期過程
如何定義組件、組件間如何通信
局部與全局狀態(tài)的通信
交互事件的處理
官方提供的一些組件以及能力
0x01 靜態(tài)頁面
在微信官網(wǎng)下載開發(fā)工具,然后新建一個小程序工程,會發(fā)現(xiàn)項目根目錄下會有一個 app.json和project.config.json以及pages/logs 目錄下的 logs.json,這里來闡述下它們的區(qū)別:
app.json 是對當(dāng)前小程序的全局配置,包括了小程序的所有頁面路徑、界面表現(xiàn)、網(wǎng)絡(luò)超時時間、底部 tab 等,具體每一項代表什么可以查看
project.config.json是針對小程序開發(fā)工具的一個配置文件,記載了你針對開發(fā)工具配置進(jìn)行的一些修改,例如界面顏色、編譯配置等,詳細(xì)配置可查看這里
page.json頁面級的配置文件,可以多帶帶定義該頁面的一些屬性,例如頂部顏色、是否可下拉、使用組件定義等,詳細(xì)配置可查看這里
闡述完各種配置文件之后,可以開始進(jìn)行頁面的編程。傳統(tǒng)的網(wǎng)頁編程采用的三劍客 HTML+CSS+JS來實現(xiàn),在微信小程序中同樣有三劍客 WXML+WXSS+JS。
WXML與HTML十分類似,可以說就是帶有模板語法,經(jīng)過微信封裝的自定義標(biāo)簽的集合。
操碎了心的微信給我們封裝了很多組件,例如view、button、text、map、video、audio等等,全部通過自定義標(biāo)簽的方式實現(xiàn),部分組件渲染提升為原生組件,提高了整體效率(也帶來了不少麻煩)。
當(dāng)然整個頁面上還支持個人十分喜愛的一種模板語法-Mustache語法,與Vue類似,你可以在表達(dá)式中訪問在data中已經(jīng)定義好的數(shù)據(jù),一旦數(shù)據(jù)發(fā)生變化,綁定的頁面會自動刷新,實現(xiàn)渲染與邏輯分離。當(dāng)然還需要條件、循環(huán)等控制能力,這些在整個模板中都有,更為詳細(xì)的可以查看文檔
WXSS說白了就是弱化版CSS,并在此基礎(chǔ)上增加了尺寸單位rpx,以此為基礎(chǔ)實現(xiàn)屏幕的適配(具體原理與rem方案適配屏幕類似);可以在頁面wxss定義頁面級樣式,在app.wxss定義全局樣式;僅僅支持部分css選擇器(要特別注意)
JS和我們寫網(wǎng)頁的有些區(qū)別,所有的方法、屬性均以Page實例中的對象屬性的形式存在,我們可以在此聲明微信提供的頁面生命周期鉤子、自定義方法以及頁面數(shù)據(jù)。需要注意的是js中沒有與DOM和BOM相關(guān)對象以及屬性,也就是常見的window、document等是沒有的。后面會闡述如果你想獲取dom結(jié)構(gòu)以及樣式時的解決方案。
0x02頁面間通信
整個小程序是由多個頁面組成,有時候會遇到需要跨頁面進(jìn)行通信的場景,例如聊天跳轉(zhuǎn)到聊天界面、刪除、拉黑好友后通知外部進(jìn)行好友列表的刷新等等。思考后有如下幾種方式可供參考:
頁面跳轉(zhuǎn)情況下可以通過querystring進(jìn)行數(shù)據(jù)的傳遞。缺點是數(shù)據(jù)量受到querystring大小的限制而且僅僅局限于頁面間跳轉(zhuǎn)。
全局狀態(tài)下存儲,每次變化后修改全局?jǐn)?shù)據(jù)(localStorage或globalData),然后頁面每次onShow時檢查此全局?jǐn)?shù)據(jù),并做出相應(yīng)的反應(yīng)。缺點是顯而易見的,業(yè)務(wù)復(fù)雜時,冗余代碼十分多,且需要觸發(fā)onShow方法,存在一定的局限性。
要想滿足耦合性小、不局限于頁面跳轉(zhuǎn)通信、通信數(shù)據(jù)量不受限制這些需求,很明顯發(fā)布/訂閱模式(觀察者模式)符合我們的要求。既能做到時間上解耦又能做到對象間解耦。iOS端的Notification Center以及android端的EventBus都是通過這一設(shè)計模式來處理跨頁面間通信的的需求的。然后微信小程序內(nèi)部并沒有集成這一事件通知機(jī)制,因此需要手動去實現(xiàn)一個并將其與微信小程序的頁面生命周期結(jié)合起來。
觀察者模式是由調(diào)度中心、發(fā)布者、訂閱者組成。訂閱者會先在調(diào)度中心訂閱某一特定事件并注冊對應(yīng)的回調(diào)函數(shù),當(dāng)發(fā)布者發(fā)布了該事件后,訂閱中心就會取出訂閱了該事件的所有訂閱者注冊的回調(diào)函數(shù)進(jìn)行執(zhí)行。
觀察者模式不難實現(xiàn),重點是如何在微信小程序中搭配其特有的生命周期來使用。本項目在用戶登錄以及注冊成功時會初始化消息訂閱中心,并全局(globalData)保存,使得訂閱器一直駐存在內(nèi)存中,調(diào)用時直接從globalData調(diào)用即可。當(dāng)然這其中還存在一些小問題,在頁面進(jìn)行切換時需要注意訂閱者、發(fā)布者之間的時序,比如訂閱早于發(fā)布或者發(fā)布之后還未訂閱的情況。后期會詳細(xì)介紹該種模式的實現(xiàn)過程敬請期待。
0x03交互事件
傳統(tǒng)的DOM事件傳遞類型有冒泡型與捕獲型,微信小程序中自然也有。通常會使用bind、catch(冒泡)和capture-bind、capture-catch(捕獲)前綴來裝飾具體的交互事件,兩者的區(qū)別如下:
bind綁定的事件不會阻止冒泡事件冒泡
catch綁定的事件會阻止冒泡事件冒泡
而小程序支持的事件類型與傳統(tǒng)的H5的差不多,新增了長按事件以及css動畫相關(guān)觸發(fā)(類似于Vue的js動畫鉤子)事件,具體為觸摸事件touchstart、touchmove、touchcancel、touchend、tap;長按事件longpress、longtap;動畫相關(guān)事件transitionend、animationstart、animationiteration、animationend;3Dtouch事件touchforcechange
整個事件命名還是較為清晰,基本做到了見名知意,詳細(xì)可以查看文檔
頁面跳轉(zhuǎn)時觸發(fā)的鉤子以及Page實例的生命周期,請自行查看官網(wǎng),這里不再贅述,這部分內(nèi)容同樣重要。
說完了事件,肯定要說事件傳參了,方法主要有兩種:
綁定到標(biāo)簽上,然后在event對象中獲取(具體是target或currentTarget則視情況而定)
使用頁面狀態(tài)數(shù)據(jù)或者全局?jǐn)?shù)據(jù)
0x04 自定義組件
從小程序基礎(chǔ)庫版本 1.6.3 開始,它支持了組件化編程。組件類似于每一個頁面,同樣由四個文件構(gòu)成json、wxml、wss、js,只在js中默認(rèn)的一些鉤子函數(shù)變化了、json中定義變化了,wxml和wss基本類似。多說一句,組件wxss中不應(yīng)使用ID選擇器、屬性選擇器和標(biāo)簽名選擇器被你干了這么多,還剩啥。。。下面就來展開講講
對于json文件的話需要將 component 字段設(shè)為 true
對于wxml文件,它的寫法與頁面模板相同。組件模版與數(shù)據(jù)拼接后生成的節(jié)點樹,將被插入到組件的引用位置上。但是組件模板多出一個功能就是:支持slot。用過vue的對它肯定十分熟悉,在制作容器組件(承載組件使用者提供的wxml結(jié)構(gòu))時用起來十分方便。同時它還支持多插槽(name區(qū)分),只需在js文件中聲明下即可。
對于wxss文件,寫法與css類似,只是有幾點區(qū)別:作用域僅僅局限于組件內(nèi);只使用class選擇器(其他選擇器要么不支持,要么在特殊情況下會有問題);除了繼承樣式外,例如font、color等,全局樣式(app.wxss)對自定義組件無效。至于外部引入樣式則從 1.9.90 基礎(chǔ)庫才開始支持。。。
對于js文件則與前面的頁面類似,整個js文件基本就是一個自定義組建的構(gòu)造器,調(diào)用構(gòu)造器可以指定組件的屬性、數(shù)據(jù)、方法等。比較常用的有:
properties:Object Map
外部傳入組件的屬性,用于模板渲染,可設(shè)置三個字段, type 表示屬性類型、 value 表示屬性初始值、 observer 表示屬性值被更改時的響應(yīng)函數(shù)(注意需要使用駝峰法寫法,在wxml中則使用連字符寫法)
data:Object
組件內(nèi)部數(shù)據(jù),用于模板渲染
methods:Object
組件的方法,包括事件響應(yīng)函數(shù)和任意的自定義方法
生命周期鉤子
created: 組件實例進(jìn)入頁面節(jié)點樹時執(zhí)行,此時不能調(diào)用 setData
attached: 組件實例進(jìn)入頁面節(jié)點樹時執(zhí)行
ready: 組件布局完成后執(zhí)行,此時可以使用 SelectorQuery獲取節(jié)點信息
moved: 組件實例被移動到節(jié)點樹的另一個位置時執(zhí)行
detached:組件實例在頁面節(jié)點樹被移除時執(zhí)行
behaviors:String Array
組件間代碼復(fù)用機(jī)制(類似于mixins)
組件實例this可以自組件方法、生命周期、屬性observer中訪問。通過組件實例可以獲取許多有用的屬性和方法,例如is(組件文件路徑)、triggerEvent(觸發(fā)事件,外部可監(jiān)聽)、setData(設(shè)置data并渲染視圖)等
了解了組件的實現(xiàn)過程,接下來就是使用。用法很簡單,只需在json文件中聲明組件,然后在wxml中引入使用即可。
// index.json 引入組件,并定義引用名字{ "usingComponents": { "input-modal": "/path/to/inputmodal"
}
}// index.html 引入組件并傳入屬性以及監(jiān)聽事件
內(nèi)部slot // index.js 實現(xiàn)事件監(jiān)聽函數(shù)Page({ tipClickHandler(e) { console.log("自定義組件事件"); }
})
工程結(jié)構(gòu)
整個微信小程序DEMO目錄結(jié)構(gòu)如下:
|- components 自定義組件目錄
|- images 項目中使用的一些高頻次圖片
|- pages 主功能一級頁面
|- contact 通訊錄頁 |- login 登錄頁 |- recentchat 最近會話頁 |- register 注冊頁 |- setting 設(shè)置頁
|- partials 二級頁面
|- addfriend 添加好友頁 |- blacklist 黑名單頁 |- chatting 聊天頁 |- forwardcontact 轉(zhuǎn)發(fā)消息通訊錄頁 |- historyfromcloud 云端歷史記錄頁 |- messagenotification 消息通知中心頁 |- modify 修改個人資料頁 |- personcard 非陌生人個人名片頁 |- strangercard 陌生人個人名片頁
|- utils 存放一些工具類js
|- config.js 存放項目的基本配置 |- emojimap.js emoji文本與對應(yīng)圖片的映射關(guān)系,自定義emoji組件使用 |- event.js 觀察者模式具體實現(xiàn) |- imageBase64.js 存儲一些小圖標(biāo)bese64編碼 |- imeventhandler.js 網(wǎng)易IM SDK初始化以及對應(yīng)的回調(diào)函數(shù)注冊,通過消息發(fā)布、訂閱與外部通信 |- pinyin.js 獲取漢字的拼音 |- util.js 一些工具方法的集合
|- vendors 引入外部的庫,主要有網(wǎng)易云信 IM 的SDK以及md5加密
|- app.js 小程序根實例,存儲了全局中的一些數(shù)據(jù)
|- app.json 注冊頁面以及定義頁面一些基本樣式
|- app.wxss 全局樣式
|- project.config.json 設(shè)置整個小程序工程的一些屬性,包括編譯類型(截止2018年3月新增加了微信插件)、基礎(chǔ)庫版本等
技術(shù)棧的一些思考
這里探討下目前(截止2018年3月)比較流行的三種開發(fā)微信小程序的方式:微信小程序原生、wepy、mpVue
微信小程序 wepy mpvue
開發(fā)規(guī)范 小程序開發(fā)規(guī)范 vue開發(fā)規(guī)范 vue開發(fā)規(guī)范
狀態(tài)管理 無 無 vuex
組件化 比較原始 自定義組件規(guī)范 vue組件
多端復(fù)用 不可 可轉(zhuǎn)化為H5 可轉(zhuǎn)化為H5
構(gòu)建方式 開發(fā)工具內(nèi)置自動構(gòu)建 框架內(nèi)置 webpack
構(gòu)建原理 開發(fā)工具自動構(gòu)建 構(gòu)建為dist后轉(zhuǎn)化為小程序支持類型然后將開發(fā)工具指向dist目錄,支持熱更新 構(gòu)建為dist后轉(zhuǎn)化為小程序支持類型然后將開發(fā)工具指向dist目錄,支持熱更新
接著分析下云信IM DEMO的需求,首先受限于同一設(shè)備下一個用戶的Storage的上限為10MB,所以這邊不做聊天數(shù)據(jù)的持久化,所有的聊天數(shù)據(jù)、用戶數(shù)據(jù)存儲在內(nèi)存中,在小程序被微信關(guān)閉(駐留后臺過久)或者用戶手動關(guān)閉(殺了微信進(jìn)程)時所有數(shù)據(jù)會被重置;其次本期需求主要為p2p單聊,后期還會添加上群聊功能等功能,所以這邊整體代碼量需要控制,不能引入非必要框架;本期需求支持的消息類型有文本、emoji、地圖、視頻、語音、圖片,部分組件可以借助微信提供的能力,加速渲染。。。
接下來大致評估下實現(xiàn)每個頁面的技術(shù)點
一級頁面:
最近會話頁
滑動刪除 - 自定義組件實現(xiàn)
單條消息條目 - 全局拿到數(shù)據(jù),然后進(jìn)行清洗渲染
消息通知 - 消息訂閱器
通訊錄頁
昵稱排序 - 漢字轉(zhuǎn)拼音
新增、拉黑、刪除好友 - 消息訂閱器
設(shè)置頁
展示個人數(shù)據(jù) - 數(shù)據(jù)清洗
修改個人資料 - 調(diào)用照相、相冊接口實現(xiàn)修改頭像以及其他類型數(shù)據(jù)
登錄注冊頁
二級頁面:
聊天頁
聊天界面布局
emoji鍵盤 - 自定義emoji組件(圖片資源存儲在網(wǎng)易nos上)
多種消息類型 - 支持語音、地理位置、文本、圖像、視頻、猜拳、emoji消息,本質(zhì)就是實現(xiàn)了一個富文本渲染自定義組件,能夠有效渲染不同的消息類型
支持消息的多種手勢操作,支持消息的撤消、刪除、轉(zhuǎn)發(fā)操作,單擊不同類型消息實現(xiàn)語音、視頻消息的播放
個人資料
分為兩種,一種是陌生人個人資料、一種是好友個人資料,兩種不同類型頁面展示的頁面組件是不一致的
入口分為如下幾種:單擊通訊錄條目進(jìn)入好友信息列表;單擊聊天記錄頭像進(jìn)入好友列表;添加好友,結(jié)果不同則展示不同的類型用戶資料
修改個人資料頁
支持修改頭像、昵稱、性別、生日、手機(jī)、郵箱、簽名,盡可能做到最大的復(fù)用
黑名單列表
消息通知界面
自定義頂部tabbar組件
聊天歷史記錄界面
初步結(jié)合框架特點以及幾大開放方式特性,矛頭重點集中在如何解決應(yīng)用狀態(tài)管理上面,經(jīng)過評估后功能點較多,因此需要盡可能的減少引入外部框架,所以這邊在微信小程序的基礎(chǔ)上實現(xiàn)全局存儲一個消息訂閱器,然后在每個功能頁面中訂閱相應(yīng)的事件,在相應(yīng)的地方發(fā)布對應(yīng)的事件。這樣就解決了狀態(tài)管理這個痛點。對于其他的一些區(qū)別個人覺得沒有任何問題,對于一個有過現(xiàn)代前端開發(fā)經(jīng)驗,有使用過mvvm框架經(jīng)驗的開發(fā)者來說,入門小程序也就是幾個小時的時間本人就是。既然花個幾個小時能夠入門小程序原生開發(fā),為何還要去選那些坑較多,入門時間相同的框架呢。。。
因此制定了如下開發(fā)原則:盡量采用微信提供的原生組件,減少引入外部組件,手?jǐn)]項目中所需的自定義組件,全局存儲數(shù)據(jù)。頁面間采用觀察者模式進(jìn)行通信
觀察者模式
常規(guī)的觀察者模式實現(xiàn)起來并不復(fù)雜,總結(jié)來說就是:訂閱器中存儲了所有訂閱者注冊的所有回調(diào)函數(shù),當(dāng)事件發(fā)生時,訂閱器就會循環(huán)遍歷所有的訂閱者,并找出訂閱該事件的訂閱者所注冊的回調(diào)函數(shù)并執(zhí)行;取消訂閱則是重訂閱者數(shù)組中刪除對應(yīng)的回調(diào)函數(shù)。
結(jié)合在小程序中使用就是在一開始初始化登錄組件時就初始化消息訂閱器,并將其保存在全局?jǐn)?shù)據(jù)(globalData)中,這樣全局就駐留了該對象,在各個頁面中就可以輕松調(diào)用訂閱器中的訂閱、發(fā)布方法來實現(xiàn)通信了。
// 訂閱function _bind(eventName, callback, isOne, context) { / eslint valid-typeof: 0 /
if (typeof eventName !== "string" || typeof callback !== "function") { throw new Error("args: " + stringStr + ", " + functionStr + "")
} if (!hasOwnKey(__onfireEvents, eventName)) {
__onfireEvents[eventName] = {}
}
__onfireEventseventName = [callback, isOne, context] return [eventName, __cnt]
}// 發(fā)布function fire(eventName) { // fire events
var args = slice(arguments, 1)
setTimeout(function() { if (hasOwnKey(__onfireEvents, eventName)) {
_each(__onfireEvents[eventName], function(key, item) { item[0].apply(item[2], args) // do the function if (item[1]) delete __onfireEvents[eventName][key] // when is one, delete it after triggle })
}
})
}
上面是整個觀察者模式的核心:訂閱、發(fā)布,當(dāng)然如果你還想繼續(xù)完善,可以嘗試增加命名空間來防止事件名沖突以及增加離線事件支持。
自定義組件
微信小程序自定義組件比較簡單,詳情可以查看。這里就以聊天界面中使用的自定義emoji組件舉例,來闡述如何實現(xiàn)一個自定義組件。
組件的定義方式,以及對應(yīng)的生命周期鉤子這邊就不再說明,請查閱上面文檔。本組件借助了小程序提供的swiper組件(省的自己判斷scroll的位置來切換頁面),每個swiper-Item里面再通過模板循環(huán)出每張emoji圖片,而每個emoji的key對應(yīng)線上地址則由自己提前準(zhǔn)備好的一個已經(jīng)抽象好的js提供,每組swiper內(nèi)含有的emoji數(shù)量則通過程序自動分割,并在最后添加刪除按鈕。
// 為每頁分配對應(yīng)的emojifunction splitAlbumKeys(arr, space, currentAlbum) { const delta = space || 23
let result = [] let factor = Math.ceil(arr.length / delta) let begin = 0
let end = 1
if (factor == 1) {
result = [[...arr]]
} else { for (let i = 1; i < factor; i++) { let temp = []
temp = [...arr.slice(begin, i * delta)] begin = i * delta result.push(temp) } result.push([...arr.slice(delta * (factor - 1), arr.length)])
} if (currentAlbum == "emoji" || this.data.currentAlbum == "emoji") { // 只有emoji才添加刪除按鈕
result.map((cata, index) => { if(index != (result.length-1)) { cata.push("[刪除]") } })
} return result
}// 單擊emoji,向外傳遞事件function emojiTap(e) { let emoji = e.target.dataset.emoji if (!emoji) return
this.triggerEvent("EmojiClick", emoji)
}// 單擊發(fā)送,向外傳遞事件function emojiSend () { this.triggerEvent("EmojiSend")
}
在外部使用過程中,只需要監(jiān)聽對應(yīng)的事件即可.
遇到的一些坑
微信小程序開發(fā)可以說是在坑中前行,經(jīng)常會遇到一些很奇怪的問題,在此記錄在冊,希望后來人可以跳過,增加開發(fā)效率
小程序模板引擎的列表循環(huán)支持?jǐn)?shù)組,不支持對象
text 組件實質(zhì)是行內(nèi)標(biāo)簽
background-image 只能用網(wǎng)絡(luò)url或者base64
注意事件對象中target 和 currentTarget的區(qū)別
URL 傳參數(shù)時微信會自動攔截"=",導(dǎo)致后面頁面onLoad中options參數(shù)容易解析出錯
二級頁面無法再使用tabbar,必須自定義
自定義組件中methods對象中定義的方法必須使用es5的函數(shù)定義
注意多種小程序授權(quán)情況
直接同意
拒絕后,進(jìn)引導(dǎo),繼續(xù)拒絕
拒絕后,進(jìn)引導(dǎo),點擊授權(quán),進(jìn)入授權(quán)設(shè)置頁,再點授權(quán)
拒絕后,進(jìn)引導(dǎo),點擊授權(quán),進(jìn)入授權(quán)設(shè)置頁,直接退出
input組件渲染級別提升為原生,某些布局下會出問題
注意某些提升為原生組件(例如video、map等)導(dǎo)致的層級問題
當(dāng)然還有一些微信提供的createSelectorQuery的一些問題,只能等待大家去探索了
這邊僅僅是拋出一些我開發(fā)中遇到的部分問題,在整個開發(fā)過程中踩過的坑遠(yuǎn)遠(yuǎn)不止這些,希望我們一起在坑中前行。。。
寫在最后
初步統(tǒng)計本項目大概8500行代碼(去除IM SDK以及MD5加密庫),換句話說不到9000行代碼,你就能在微信中實現(xiàn)一個mini 微信,這一切均借助于云信IM SDK強(qiáng)大的即時通訊能力。當(dāng)然本期版本還存在很多不足的地方,希望在做第二期群聊功能的時候,能繼續(xù)升級整體的組織架構(gòu)。
網(wǎng)易云信IM免費試用請點擊這里。
更多網(wǎng)易技術(shù)、產(chǎn)品、運營經(jīng)驗分享請訪問網(wǎng)易云社區(qū)
文章來源: 網(wǎng)易云社區(qū)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/25329.html
摘要:但對于整個事件流上的別的元素來說,執(zhí)行順序還會受到另外一個因素的影響。以上面的場景為例,在捕獲階段執(zhí)行的事件,如果執(zhí)行,則事件流終止,不會到達(dá)目標(biāo)階段,的世界則不會被執(zhí)行執(zhí)行結(jié)果為線上參考事件流 向dom綁定事件的事件的三種方式 行內(nèi)綁定 按鈕 js內(nèi)綁定 btnDom.onclick = function clickHandler() { console.log(click)...
摘要:常用的數(shù)組方法刪除數(shù)組的最后一個元素,返回被刪除的元素,原數(shù)組長度減。原數(shù)組發(fā)生了變化,但沒有創(chuàng)建新的數(shù)組。將指定數(shù)組進(jìn)行排序,返回排好序的數(shù)組。顛倒數(shù)組元素的順序,返回逆序后的數(shù)組。 數(shù)組,對于每一個前端人員來說是非常常見且重要的數(shù)據(jù)結(jié)構(gòu)之一,也是面試常常出現(xiàn)的題目,掌握數(shù)組的方法能幫助我們更高效地處理問題。不過在數(shù)組的學(xué)習(xí)中,我們常常會混淆數(shù)組本身的方法和Javascript提供的...
摘要:前端渲染過程的二三事本文不會介紹整個前端渲染過程的步驟,只是記錄最近閱讀的文章的些許思考和感悟。那么現(xiàn)在我們可以明白這個問題的關(guān)鍵所在了,因為在大部分頁面中是擁有的,而由于其解析順序,那么在事件之前必定已經(jīng)成功構(gòu)造樹。 前端渲染過程的二三事 本文不會介紹整個前端渲染過程的步驟,只是記錄最近閱讀的文章的些許思考和感悟。(文章地址一(系列),文章地址二) 希望大家在閱讀這篇文章之前能將上述...
摘要:分表字段的選擇。問題產(chǎn)生之前提到在分表應(yīng)用上線前我們需要將原有表的數(shù)據(jù)遷移到新表中,這樣才能保證業(yè)務(wù)不受影響。雖說凌晨的業(yè)務(wù)量下降,但依然有少部分的請求過來,也會出現(xiàn)各種數(shù)據(jù)庫異常。 showImg(https://segmentfault.com/img/remote/1460000019462791?w=496&h=285); 前言 本篇是上一篇《一次分表踩坑實踐的探討》,所以還沒...
閱讀 3214·2021-11-25 09:43
閱讀 3217·2021-11-23 09:51
閱讀 3529·2019-08-30 13:08
閱讀 1582·2019-08-29 12:48
閱讀 3605·2019-08-29 12:26
閱讀 410·2019-08-28 18:16
閱讀 2575·2019-08-26 13:45
閱讀 2441·2019-08-26 12:15