深拷貝/淺拷貝
Object.assign可以實(shí)現(xiàn)淺拷貝
后面突然想起來(lái)的,追加的時(shí)候追忘了說(shuō)的啥
原生對(duì)象
應(yīng)該是高程,對(duì)js對(duì)象分原生對(duì)象和引用對(duì)象
說(shuō)道原生對(duì)象我容易忽略object與function
對(duì)象
面向?qū)ο笕筇攸c(diǎn),繼承,多態(tài)與封裝
其中
繼承
指子類繼承父類的特征和行為,使得子類對(duì)象具有父類的實(shí)例域和方法,以達(dá)到復(fù)用的目的,是面向?qū)ο笳Z(yǔ)言的基礎(chǔ)特性
在面向?qū)ο蟊皇袌?chǎng)接收后,js選擇了強(qiáng)行面向?qū)ο笠簿褪且蕾囋玩湹睦^承方式
原型鏈繼承實(shí)現(xiàn)
針對(duì)面向原型鏈繼承的驗(yàn)證包括幾個(gè)關(guān)鍵函數(shù)
constructor,__proto__,prototype
原型鏈繼承驗(yàn)證
針對(duì)驗(yàn)證,主要幾個(gè)關(guān)鍵函數(shù)
isPrototypeOf,hasOwnProperty,instanceof,typeof
甚至包括ie系列的isXXX系列
原型鏈繼承驗(yàn)證bug
但問(wèn)題在于,整體的驗(yàn)證體系
1.屬于鴨辨式
2.兩套體系,主要指ie的isXXX系列
即使到了Object.prototype.toString為止,也沒(méi)有填完原型鏈繼承驗(yàn)證的坑
(主要指宿主環(huán)境下的對(duì)象,跨域下對(duì)象比較(這個(gè)類似與不同jvm解析對(duì)對(duì)象是否相同))
原型鏈繼承使用
最后在使用上,基于原型鏈繼承實(shí)現(xiàn),除了框架上的掛載外,很少主動(dòng)使用
比如vue任意組件內(nèi)部的this依次繼承VueComponent,Vue,允許this可直接使用Vue掛載的其他實(shí)例
但是諸如其他熱插拔式的組件,則不會(huì)繼承Vue,比如VueRouter等
大部分組件庫(kù)或框架也是如此,比如jq組件,可以通過(guò)this使用jq的實(shí)例化方法
但也僅限于此,更多的方式使用組合,本身繼承就有屬性污染或者非必要的創(chuàng)建等很已被證明的冗余的內(nèi)容(這里尤其值java,以及java針對(duì)繼承爆炸所設(shè)計(jì)的23中設(shè)計(jì)模式)
針對(duì)ui組件庫(kù),一般都不會(huì)選擇完整的繼承,類似于混合或者閹割的概念,無(wú)視對(duì)象的判斷,更像是依賴原型鏈進(jìn)行復(fù)用的技巧,比如easyui
$.fn.combobox = function(options, param){
if (typeof options == 'string'){
var method = $.fn.combobox.methods[options];
if (method){
return method(this, param);
} else {
//此處this指向的是jquery的實(shí)例,而非是combobox的實(shí)例,如果按照任意一款關(guān)于js原型鏈繼承的demo去參考,這里絕對(duì)會(huì)怪怪的
return this.combo(options, param);
}
}
}
原型鏈繼承使用原則
結(jié)合prototype.js針對(duì)原生原型拓展的槽點(diǎn),我一般會(huì)表達(dá)如下意思
1.自己給自己開(kāi)發(fā)的可以繼承
2.使用別人開(kāi)發(fā)的只能組合
除非打補(bǔ)丁,或者有特定的解決方案,比如Ext
因?yàn)楸旧聿⒎菑?qiáng)類型語(yǔ)言,所以這塊問(wèn)題不大
js繼承的替代
繼承是為了代碼復(fù)用,而代碼復(fù)用的方式有兩種
1.組合
2.繼承
而組合一定會(huì)談到的就是閉包
閉包
針對(duì)閉包,引用犀牛書,包含兩個(gè)部分
1.函數(shù)對(duì)象通過(guò)作用域進(jìn)行關(guān)聯(lián)
2.函數(shù)體內(nèi)變量保存在函數(shù)作用域內(nèi)
簡(jiǎn)單地說(shuō)的確是解決變量污染
但問(wèn)題是,閉包來(lái)自詞法作用域,這個(gè)是現(xiàn)代編程語(yǔ)言都有的,他不算js的特性
我想描述的意思應(yīng)該是閉包可以實(shí)現(xiàn)代碼復(fù)用,代替繼承
url執(zhí)行發(fā)生了什么
這是我做java的時(shí)候做的總結(jié)
1.瀏覽器請(qǐng)求前過(guò)濾-- 每個(gè)瀏覽器并不相同,可能會(huì)包括
- 補(bǔ)全url
如默認(rèn)http協(xié)議,最后的字符串/去掉
- 驗(yàn)證url
如非法協(xié)議會(huì)轉(zhuǎn)換為http
- 沒(méi)有網(wǎng),直接默認(rèn)404
- 脫機(jī)/離線數(shù)據(jù)
- 網(wǎng)址關(guān)聯(lián)
- 地址記錄
- 安全警告
等等基于體驗(yàn)或惡意的功能,最后是發(fā)送請(qǐng)求
2.發(fā)送請(qǐng)求
- DNS解析
- TCP連接
- 請(qǐng)求
- 反饋【瀏覽器處理請(qǐng)求頭】
比如根據(jù)后臺(tái)傳遞類型與系統(tǒng)關(guān)聯(lián),以進(jìn)行下一步比如自帶瀏覽器下載,第三方插件如迅雷下載或頁(yè)面加載
- 內(nèi)容傳輸
- 連接結(jié)束
- 處理內(nèi)容
1.包括進(jìn)行關(guān)聯(lián),如自動(dòng)打開(kāi)word,圖片等,國(guó)企常見(jiàn)需求,通過(guò)url請(qǐng)求,自動(dòng)打開(kāi)某軟件
2.檢測(cè)同源協(xié)議,主要指xhr,通過(guò)瀏覽器一般沒(méi)有
3.自定義的如頁(yè)面渲染
- 第三方插件,比如chrome下的json美化
- 也可能有惡意攔截或惡意劫持,參考360
內(nèi)存泄漏與溢出
描述
無(wú)用內(nèi)存無(wú)法釋放
實(shí)例
經(jīng)常在jq的兩套數(shù)據(jù)緩存上進(jìn)行對(duì)比,jq針對(duì)數(shù)據(jù)緩存,即
$.fn.setData()
為什么要修改實(shí)現(xiàn)
代碼規(guī)范
操作上一般強(qiáng)調(diào),減少對(duì)dom的數(shù)據(jù)掛載
vue訂閱與發(fā)布
Object.defineProperty,配合代理,攔截array系列各種增刪改函數(shù),針對(duì)對(duì)象屬性的新增與刪除使用$set,這個(gè)在2.0應(yīng)該依然沒(méi)有變化
更早的angular,avalon則會(huì)使用臟檢
vue不監(jiān)聽(tīng)對(duì)象的新增
對(duì)接接口的時(shí)候,后臺(tái)有次優(yōu)化,針對(duì)所有undefined數(shù)據(jù),全部不返回,以節(jié)省流量,所以所有對(duì)象,全都要求有默認(rèn)數(shù)據(jù)(兩組默認(rèn)數(shù)據(jù),一類正常的默認(rèn)數(shù)據(jù),以面對(duì)產(chǎn)品,一類為數(shù)據(jù)結(jié)構(gòu),屬性為undefined,以面對(duì)后臺(tái)),而后通過(guò)Object.assign的方式一層層進(jìn)行修正,本身考慮過(guò)如何讓vue監(jiān)聽(tīng)對(duì)象屬性的新增或者在操作是使用Vue.set的方式進(jìn)行動(dòng)態(tài)添加
而Vue3則會(huì)計(jì)劃使用new Proxy來(lái)重新進(jìn)行實(shí)現(xiàn)
所以對(duì)vue不能監(jiān)聽(tīng)數(shù)據(jù)的屬性新增比較執(zhí)念
vue組件內(nèi)props與data命名沖突
因?yàn)楹笈_(tái)語(yǔ)言,比如java的原因,數(shù)據(jù)與事件是在類的同一級(jí)下,類似于
{
...data,
...methods
}
的形式,這種形式依賴命名或者說(shuō)代碼實(shí)施檢測(cè)
如果前端這么使用,如果有重名,一定會(huì)依照順序被覆蓋
比如banckbone,用友的iuap
這里強(qiáng)調(diào)一下,因?yàn)閐ata的監(jiān)聽(tīng),類似于rsjx,為開(kāi)發(fā)人員主動(dòng)監(jiān)聽(tīng),不存在結(jié)構(gòu)轉(zhuǎn)換的問(wèn)題
結(jié)構(gòu)如下
{
name:ko.observable(''),
getName(){
}
}
所以很容易出現(xiàn)
{
...data,
...methods
}
這種形式
沖突處理
我在把iuap改成vue寫法的時(shí)候遇見(jiàn)過(guò)這個(gè)問(wèn)題,假設(shè)真的重名了,怎么處理,應(yīng)該是忽略,假設(shè)data中已存在并處理過(guò)改name,則在其他地方如methods時(shí),不在處理,那么針對(duì)vue就是,假設(shè)props已經(jīng)被監(jiān)聽(tīng),則忽略data,
vue源碼
//初始化執(zhí)行順序
export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
//依次進(jìn)行初始化
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {
initData(vm)
} else {
observe(vm._data = {}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch)
}
}
//初始化data函數(shù)
function initData (vm: Component) {
//...
if{
//...
}else if (!isReserved(key)) {
//當(dāng)屬性并未被訂閱過(guò),即非props屬性
proxy(vm, `_data`, key)
}
}
//...
}
ajax
異步j(luò)s與xml,并不局限于數(shù)據(jù),在jq中一直是可以用來(lái)獲取后臺(tái)json數(shù)據(jù),xml結(jié)構(gòu),文本結(jié)構(gòu),jsonp甚至script,最早的組件加載器都是用ajax加載script實(shí)現(xiàn)的,比如easyui,ext自帶的loader,一般會(huì)配合如下代碼
loader('tableUI')
$(function(){
//1.業(yè)務(wù)代碼
})
loader中會(huì)重新代理$(),已達(dá)到組件正確加載的目的
也包括百度,高德等第三方軟件商提供的各種loader
amd與cmd
談到async和ajax的時(shí)候大概是想描述這類代碼
//同步的
async function main()=>{
//1.初始化代碼
....
//2.初始化組件
//按需加載
//await $.getScript('xxx')
await loader('tableUI')
$.tableUi('#table');
}
//或者
//異步的
function main()=>{
//1.初始化代碼
//2.初始化組件
loader('tableUI').then(()=>{
$.tableUi('#table');
})
}
requirejs與seajs的確有寫法上的區(qū)別或者叫原理上的區(qū)別,問(wèn)題是在具體實(shí)現(xiàn)時(shí),盡量會(huì)要求同步為主,否則會(huì)有不必要的麻煩
比如金山云控制臺(tái),點(diǎn)擊數(shù)據(jù)庫(kù)【關(guān)系數(shù)據(jù)庫(kù)】,再點(diǎn)擊數(shù)據(jù)庫(kù)【表格數(shù)據(jù)庫(kù)】,業(yè)務(wù)層無(wú)發(fā)正常渲染,應(yīng)該就是table組件沒(méi)有家在上的原因

回流與重繪
在用java做dom解析的時(shí)候,遇見(jiàn)的一個(gè)問(wèn)題,dom的屬性可以修改,但節(jié)點(diǎn)類型無(wú)法修改,應(yīng)該怎么處理
對(duì)應(yīng)的其實(shí)就是回流與重繪
重繪
$0.align="right"
dom節(jié)點(diǎn)并沒(méi)有修改,可以重復(fù)使用,使用后臺(tái)也很好處理,Render樹保持不變,相應(yīng)的dom進(jìn)行重繪即可
回流
對(duì)應(yīng)的,如果將h2標(biāo)簽改成h3標(biāo)簽如何處理
無(wú)論是js還是java都需要通過(guò)函數(shù)處處理,一定是新增和刪除dom,而新增與刪除會(huì)修改Render樹的坐標(biāo),故稱為回流
針對(duì)java上,我可能會(huì)描述為
1.局部更新
調(diào)用實(shí)例對(duì)象的set系列
2.全局更新
調(diào)用靜態(tài)函數(shù)changeDom系列
概念借用
圖表系列,比如highchart或者某些圖行處理上會(huì)引用類似的概念,比如只是修改了data,調(diào)用repaint,而修改了title或者整體的結(jié)構(gòu),那就是reflow
vm描述
其實(shí)用vm描述大概這樣
export default {
data(){
return {
//監(jiān)聽(tīng)dom樹
domTree:[]
}
},
watch:{
renderTree(){
reflow();
}
},
computed:{
//獲取render樹
renderTree(){
return _.map(domTree,(dom)=>{
return {
dom:dom,
x:getX(dom),
y:getY(dom)
}
})
}
}
}
類似結(jié)構(gòu)
而這個(gè)結(jié)構(gòu)又類似于iview的table組件
使用iview的table組件不能進(jìn)行編輯,要么重寫一個(gè)EditTable,直接進(jìn)行數(shù)據(jù)的綁定,但是會(huì)丟失很多配置性的功能,要么修改內(nèi)部的rebuildData
我在寫knockout下的table組件時(shí),也遇見(jiàn)過(guò)類似的問(wèn)題
抖動(dòng)與節(jié)流
throttle/debounce這兩個(gè)函數(shù)我也是今天才知道叫抖動(dòng)和節(jié)流,我一般是放在高頻處理上描述
原文如下
重復(fù)提交(高頻處理)
- 重復(fù)提交
單位時(shí)間內(nèi),多次非冪等(post)請(qǐng)求,造成的后臺(tái)重復(fù)錄入現(xiàn)象
此處重點(diǎn)討論前端的防重復(fù)提交的方式
- 快速點(diǎn)擊
單位時(shí)間內(nèi),快速點(diǎn)擊,觸發(fā)異步事件,照成數(shù)據(jù)與ui混亂的現(xiàn)象
如導(dǎo)航,分頁(yè)等,當(dāng)導(dǎo)航快速點(diǎn)擊,會(huì)使內(nèi)容區(qū)異常抖動(dòng),且可能會(huì)與導(dǎo)航具體標(biāo)簽不一致
屬于高頻,但比較獨(dú)特,包含了異步操作,故單獨(dú)拿出來(lái)處理
- 高頻事件
單位時(shí)間內(nèi),觸發(fā)的各類事件,且響應(yīng)速度低于請(qǐng)求,照成的卡頓或其他混亂現(xiàn)象,如快速點(diǎn)擊,鼠標(biāo)移動(dòng)
以上三種情況之后統(tǒng)一描述重復(fù)提交
最終效果
- 阻止過(guò)多的ajax請(qǐng)求(post/get)
- 正確響應(yīng)最后一次結(jié)果
關(guān)鍵技術(shù)點(diǎn)
- Aborted
xhr的abort函數(shù)
setTimeout
限制性UI
修改按鈕/UI,彈菊花
重復(fù)判斷
保存正在進(jìn)行的ajax操作(0<readyState<4)及其url,當(dāng)該操作存在,且又要發(fā)送相同請(qǐng)求時(shí),視為重復(fù)提交
實(shí)現(xiàn)
實(shí)現(xiàn)的方式有很多,此處會(huì)盡量做到減少污染和依賴(變化)
根據(jù)影響范圍,做以下區(qū)分
ajax攔截/包裹/封裝
此處使用lodash的函數(shù)式寫法,如果喜歡es7的裝飾方式,需要做細(xì)微的調(diào)整
abort函數(shù)
對(duì)原有xhr(ajax),進(jìn)行abort處理
對(duì)于post,并沒(méi)有阻止ajax請(qǐng)求,請(qǐng)求已經(jīng)發(fā)送,后臺(tái)依然在處理請(qǐng)求
對(duì)于get,可以保證當(dāng)前請(qǐng)求為正確的結(jié)果(解決快速點(diǎn)擊)
實(shí)現(xiàn)
var global={};
$.ajaxSetup({
beforeSend:function(jqXHR, s ){
//為jqXHR注入url
var callbackContext = this;
jqXHR._url=callbackContext.url
}
});
function abort(ajax){
//獲取上一個(gè)請(qǐng)求
var preajax = global[ajax._url];
preajax&&preajax.abort();
global[ajax._url]=ajax
};
var abort_ajax=_.flow($.get,abort);
abort_ajax('/');
abort_ajax('/');
abort_ajax('/');
abort_ajax('/');
此種實(shí)現(xiàn)默認(rèn)url獲取數(shù)據(jù)后,會(huì)對(duì)數(shù)據(jù)進(jìn)行分發(fā)
分頁(yè),導(dǎo)航,搜索(度娘)均可使用

其他
若為傳統(tǒng)(10年前-。-)的組件+url的形式,如
<select url="api/students"></select>
<select url="api/students"></select>
此時(shí),會(huì)產(chǎn)生兩條相同請(qǐng)求,獲取數(shù)據(jù)后并不分發(fā),需要改寫代碼
若對(duì)ajax進(jìn)行了封裝,使用注入Store/Model,vuex,flux之類的模型
根據(jù)不同的場(chǎng)景描述不同的action,性質(zhì)是一樣的
裝飾
如果非要用es7裝飾,注意,promise(現(xiàn)在)沒(méi)有abort,以下寫法,不好實(shí)現(xiàn)(單指寫法,不探討是否適合)
@abort
async submit(){
var data=await Store.load('');
console.log(data);
}
abort思路,可以解決異步交互(get)下,最后一次響應(yīng)的問(wèn)題
js是同步的,無(wú)法解決同步的多次提交(同步為卡頓,響應(yīng)順序并不會(huì)錯(cuò)誤)
忽略(單例)
根據(jù)url,對(duì)ajax實(shí)現(xiàn)單例,即當(dāng)前url正在通訊時(shí),返回上一個(gè)ajax,不在創(chuàng)建信息ajax
實(shí)現(xiàn)
var ignore_ajax=function(params){
var preajax = global[params.url];
if(preajax){
return preajax
}
var ajax = $.ajax(params)
ajax.then(function(){
global[this.url]=undefined;
})
global[params.url] = ajax;
return ajax;
}
ignore_ajax({url:'/'});
ignore_ajax({url:'/'});
ignore_ajax({url:'/'});
ignore_ajax({url:'/'});
例子中省略global,ajaxSetup步奏,下同
一般由Store,Model等封裝ajax的模塊,配合readyState進(jìn)行操作,即將ajax改成單例
無(wú)法保證最后一次請(qǐng)求的響應(yīng),故本身會(huì)配合ui進(jìn)行限制性操作
保存系列,均可使用
其他
- 對(duì)于后臺(tái)超級(jí)接口,需要個(gè)性化處理
- 會(huì)無(wú)視,結(jié)果未返回時(shí),請(qǐng)求參數(shù)(body內(nèi))已變更的請(qǐng)求(配合ui)
throttle/debounce
高頻(鼠標(biāo)移動(dòng),窗口大小)請(qǐng)求中,調(diào)整請(qǐng)求和響應(yīng)速度的方式,屬于setTimeout的花樣使用
實(shí)現(xiàn)
var debounce_ajax = _.debounce($.ajax,5000);
debounce_ajax('/')
其他
- throttle
優(yōu)先執(zhí)行,之后放啞炮,類似于忽略(單例),無(wú)法保證能夠準(zhǔn)確的響應(yīng)最后一次操作
不依賴最后一次響應(yīng)的事件,比如mousemove,對(duì)于異步需要配合ui限制(也可以改用忽略的方式),總之,不是最好的選擇
- debounce
單位時(shí)間內(nèi)收集數(shù)據(jù),而后進(jìn)行請(qǐng)求,
包含數(shù)據(jù)收集的輸入框,都可以使用比如觸發(fā)框,富文本自動(dòng)保存
另:度娘的服務(wù)器就是屌
memoize
get冪等
實(shí)現(xiàn)
var memoize_ajax =_.memoize($.ajax)
其他
沒(méi)錯(cuò),就是緩存,主要用于數(shù)據(jù)更新頻率低的冪等異步操作
比如requireJS,加載導(dǎo)航數(shù)據(jù),菜單欄,甚至各種樹結(jié)構(gòu)
validate/error/timeout
禁止訪問(wèn)(權(quán)限),異常處理,超時(shí)等情況,雖然不屬于重復(fù)提交,但處理上類似
限制ui
此處ajax依賴ui,屬于ajax處理后臺(tái)進(jìn)階表現(xiàn),尤其是單例的情況下
當(dāng)然,只用ui控制也無(wú)所謂,多入口保存的情況還是比較少的
disabled/active系列/轉(zhuǎn)菊花
將整個(gè)操作函數(shù)封裝為promise,并通過(guò)e獲取相應(yīng)ui
export function buttonDisable(promise){
//尋找依賴ui
var e=arguments[arguments.length-1]
var btn=e.target.parentElement;
//設(shè)置類 or 屬性 or 轉(zhuǎn)菊花
btn.setAttribute('disabled','')
promise()
.then(()=>{
btn.removeAttribute('disabled');
})
.catch(()=>{
btn.removeAttribute('disabled');
})
}
@buttonDisable
async submit(){
var data=await Post('/');
console.log(data);
}
es6寫法(es5略)
整體包裹/限制的范圍為submit的執(zhí)行過(guò)程,若單獨(dú)對(duì)ajax進(jìn)行限制,對(duì)于嵌套/并行等各種花式ajax完全無(wú)愛(ài)
當(dāng)然,如果強(qiáng)迫必須視圖屬性代替視圖,也可以做如下操作
export function buttonDisable(vm){
return function(promise){
vm(false);
promise()
.then(()=>{
vm(true);
})
.catch(()=>{
vm(true);
})
}
}
@buttonDisable(vm.submitFlag)
async submit(){
var data=await Post('/');
console.log(data);
}
<button class="u-button u-button-info " data-bind="{click:submit,attr:{disabled:submitFlag}}">提交</button>
submitFlag,需要提前定義,轉(zhuǎn)菊花監(jiān)聽(tīng)submitFlag變化即可
封裝ajax,監(jiān)聽(tīng)readyState
async submit(){
var data=await Store.load('');
console.log(data);
}
<button class="u-button u-button-info " data-bind="{click:submit,attr:{disabled:Store.readyState}}">提交</button>
Store為ajax的封裝,其中readyState為監(jiān)聽(tīng)對(duì)象(屬性),如果沒(méi)有這一層...那就有一個(gè),算一個(gè)-。-
其他
將整個(gè)執(zhí)行函數(shù)處理為promise,而后進(jìn)行個(gè)性化處理
最好不要在ajax處理中,包含ui操作
后臺(tái)重復(fù)驗(yàn)證
提前提供id,將創(chuàng)建,改寫為"修改",防止一對(duì)一的關(guān)系轉(zhuǎn)換為一對(duì)多
ssh系列的token防重復(fù)提交,指的是該系列
緩存系列與數(shù)據(jù)庫(kù)平級(jí),不討論
其他情況并不處理...
原文結(jié)束
我想說(shuō)的應(yīng)該是clearTimeout
線程
瀏覽器是多線程
html自身的至少三個(gè)
1.事件
比如setTimeout和dom1中的事件流
2.渲染/GUI
html/css
3.xhr
以及最后網(wǎng)景后來(lái)增加的
4.js引擎
以我個(gè)人的角度看,應(yīng)該還有個(gè)主線程,去分配GUI與JS,順便保證他們的互斥性,這個(gè)應(yīng)該就是瀏覽器本身
我以前做java的時(shí)候,會(huì)說(shuō)就當(dāng)js與GUI在一個(gè)線程里即瀏覽器頁(yè)面主線程,所以造成的GUI與js的互斥,這點(diǎn)的確是描述的有問(wèn)題
而針對(duì)css與html包括js的并行,主要想描述的是依順序運(yùn)行,針對(duì)單核,多線程屬于按順序或按優(yōu)先級(jí),依次進(jìn)行運(yùn)算,這個(gè)屬于強(qiáng)行解釋
16ms
針對(duì)16ms,大概還有個(gè)14K,script壓縮保持14K倍數(shù)的傳說(shuō)吧,tcp傳輸,每包起步14K
即某種意義上看1k與10k傳輸速度相同
300ms是測(cè)試的要求,大致是頁(yè)面不能白屏超過(guò)300ms,否則按bug算
12-11補(bǔ)充
加載器
針對(duì)加載器(amd/cmd),除了開(kāi)發(fā)過(guò)loader或者使用過(guò)外,針對(duì)UI組件,主要是ext與easyui,有過(guò)細(xì)節(jié)的優(yōu)化
主要要針對(duì)的是不需要返回組件對(duì)象的組件,比如彈出層,模態(tài)框這些
屬于在業(yè)務(wù)代碼風(fēng)格不變的情況下按需加載,類似于dll的動(dòng)態(tài)引用
不需要返回結(jié)構(gòu)的加載器
整體結(jié)構(gòu)如下
//種子
$.modal = (config)=>{
if(!$.widgets.modal){
//加載模態(tài)框組件代碼
loader('modal').then(()=>{
//生成模態(tài)框組件
$.widgets.modal(config);
})
}else{
$.widgets.modal(config);
}
}
其實(shí)更像是代理,如果其他需要返回的組件也這么處理,本身來(lái)講與loader整體語(yǔ)法上是重復(fù)的,最主要是針對(duì)組件通訊或組件依賴完全無(wú)解,大致風(fēng)格如下,
$('#xxx').tableUI({
})
.then(tableUI){
}
模態(tài)框加載
后續(xù)對(duì)模態(tài)框的加載又做了一次處理,這里類似業(yè)務(wù)代碼的動(dòng)態(tài)加載,現(xiàn)在基本上由路由統(tǒng)一處理,問(wèn)題不大
模態(tài)框組將相當(dāng)其他組件來(lái)講,在交互上更依賴結(jié)構(gòu)(data)而不是dom,尤其是在模態(tài)框由iframe或者window.open實(shí)現(xiàn)的時(shí)候
比如使用時(shí)
{
//業(yè)務(wù)使用
methods:{
async getUser(){
try{
var res = await UserModal(config);
cosnole.log('已選擇',res)
}catch(e){
console.log('未選擇')
}
}
}
}
模態(tài)框--UserModal,這里可以用繼承,組合甚至裝飾
import ModalComponent from './ModalComponent'
export default function Modal(config) {
return new Promise((resolve, reject) => {
const Instance = new Vue({
render(h) {
return h(ModalComponent)
},
methods: {
ok(data) {
resolve(data);
this.destroy();
},
remove() {
reject();
this.destroy();
},
destroy() {
document.body.removeChild(this.$el);
}
}
});
const component = Instance.$mount();
document.body.appendChild(component.$el);
})
}
最終業(yè)務(wù)實(shí)現(xiàn)
<template>
<Modal v-model="show" @on-ok="ok">
模態(tài)框
</Modal>
</template>
<script>
export default {
data(){
return {
show:true
}
},
methods:{
ok(){
this.$parent.ok({
name:'xx'
})
}
}
}
</script>
按需加載dom
這里其實(shí)是按需加載dom,把js再次Promse就是按需加載js與dom
應(yīng)該說(shuō)所有的串性交互的組件都可以這么實(shí)現(xiàn)(平行的也可以,或者依賴反饋,或者多次發(fā)送,比如導(dǎo)航模塊和業(yè)務(wù)模塊),以實(shí)現(xiàn)動(dòng)態(tài)加載的目的,比如復(fù)雜的下拉或詳情等