成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

JavaScript模塊化發(fā)展

mengbo / 858人閱讀

摘要:所有依賴這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到所有依賴加載完成之后前置依賴,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。如果將前面的代碼改寫(xiě)成形式,就是下面這樣定義了一個(gè)文件,該文件依賴模塊,當(dāng)模塊加載完畢之后執(zhí)行回調(diào)函數(shù),這里并沒(méi)有暴露任何變量。

模塊化是我們?nèi)粘i_(kāi)發(fā)都要用到的基本技能,使用簡(jiǎn)單且方便,但是很少人能說(shuō)出來(lái)但是的原因及發(fā)展過(guò)程?,F(xiàn)在通過(guò)對(duì)比不同時(shí)期的js的發(fā)展,將JavaScript模塊化串聯(lián)起來(lái)整理學(xué)習(xí)記憶。

如何理解模塊化 面臨的問(wèn)題

技術(shù)的誕生是為了解決某個(gè)問(wèn)題,模塊化也是。在js模塊化誕生之前,開(kāi)發(fā)者面臨很多問(wèn)題:隨著前端的發(fā)展,web技術(shù)日趨成熟,js功能越來(lái)越多,代碼量也越來(lái)越大。之前一個(gè)項(xiàng)目通常各個(gè)頁(yè)面公用一個(gè)js,但是js逐漸拆分,項(xiàng)目中引入的js越來(lái)越多:









當(dāng)年我剛剛實(shí)習(xí)的時(shí)候,項(xiàng)目中的js就是類(lèi)似這樣,這樣的js引入造成了問(wèn)題:

全局變量污染:各個(gè)文件的變量都是掛載到window對(duì)象上,污染全局變量。

變量重名:不同文件中的變量如果重名,后面的會(huì)覆蓋前面的,造成程序運(yùn)行錯(cuò)誤。

文件依賴順序:多個(gè)文件之間存在依賴關(guān)系,需要保證一定加載順序問(wèn)題嚴(yán)重。

這些問(wèn)題嚴(yán)重干擾開(kāi)發(fā),也是日常開(kāi)發(fā)中經(jīng)常遇到的問(wèn)題。

什么是模塊化

我覺(jué)得用樂(lè)高積木來(lái)比喻模塊化再好不過(guò)了。每個(gè)積木都是固定的顏色形狀,想要組合積木必須使用積木凸起和凹陷的部分進(jìn)行連接,最后多個(gè)積木累積成你想要的形狀。

模塊化其實(shí)是一種規(guī)范,一種約束,這種約束會(huì)大大提升開(kāi)發(fā)效率。將每個(gè)js文件看作是一個(gè)模塊,每個(gè)模塊通過(guò)固定的方式引入,并且通過(guò)固定的方式向外暴露指定的內(nèi)容。

按照js模塊化的設(shè)想,一個(gè)個(gè)模塊按照其依賴關(guān)系組合,最終插入到主程序中。

模塊化解決方案

模塊化這種規(guī)范提出之后,得到社區(qū)和廣大開(kāi)發(fā)者的響應(yīng),不同時(shí)間點(diǎn)有多種實(shí)現(xiàn)方式。我們舉個(gè)例子:a.js

// a.js
var aStr = "aa";
var aNum = cNum + 1;

b.js

// b.js
var bStr = aStr + " bb";

c.js

// c.js
var cNum = 0;

index.js

// index.js
console.log(aNum, bStr);

四份文件,不同的依賴關(guān)系(a依賴c,b依賴a,index依賴a b)在沒(méi)有模塊化的時(shí)候我們需要頁(yè)面中這樣:

    


嚴(yán)格保證加載順序,否則報(bào)錯(cuò)。

1. 閉包與命名空間

這是最容易想到的也是最簡(jiǎn)便的解決方式,早在模塊化概念提出之前很多人就已經(jīng)使用閉包的方式來(lái)解決變量重名和污染問(wèn)題。

這樣每個(gè)js文件都是使用IIFE包裹的,各個(gè)js文件分別在不同的詞法作用域中,相互隔離,最后通過(guò)閉包的方式暴露變量。每個(gè)閉包都是多帶帶一個(gè)文件,每個(gè)文件仍然通過(guò)script標(biāo)簽的方式下載,標(biāo)簽的順序就是模塊的依賴關(guān)系。

上面的例子我們用該方法修改下寫(xiě)法:

a.js

// a.js
var a = (function(cNum){
   var aStr = "aa";
   var aNum = cNum + 1; 
    
    return {
       aStr: aStr,
       aNum: aNum
    };
})(cNum);

b.js

// b.js
var bStr = (function(a){
   var bStr = a.aStr + " bb";
    
   return bStr;
})(a);

c.js

// c.js
var cNum = (function(){
   var cNum = 0;
    
   return cNum;
})();

index.js

;(function(a, bStr){
    console.log(a.aNum, bStr);
})(a, bStr)

這種方法下仍然需要在入口處嚴(yán)格保證加載順序:

    


這種方式最簡(jiǎn)單有效,也是后續(xù)其他解決方案的基礎(chǔ)。這樣做的意義:

各個(gè)js文件之間避免了變量重名干擾,并且最少的暴露變量,避免全局污染。

模塊外部不能輕易的修改閉包內(nèi)部的變量,程序的穩(wěn)定性增加。

模塊與外部的連接通過(guò)IIFE傳參,語(yǔ)義化更好,清晰地知道有哪些依賴。

不過(guò)各個(gè)模塊的依賴關(guān)系仍然要通過(guò)加裝script的順序來(lái)保證。

2. 面向?qū)ο箝_(kāi)發(fā)

一開(kāi)始一些人在閉包的解決方案上做出了規(guī)范約束:每個(gè)js文件始終返回一個(gè)object,將內(nèi)容作為object的屬性。

比如上面的例子中b.js

// b.js
var b = (function(a){
   var bStr = a.aStr + " bb";
    
   return {
       bStr: bStr
   };
})(a);

及時(shí)返回的是個(gè)值,也要用object包裹。后來(lái)很多人開(kāi)始使用面向?qū)ο蟮姆绞介_(kāi)發(fā)插件:

;(function($){
    var LightBox = function(){
        // ...
    };
    
    LightBox.prototype = {
        // ....
    };
    
    window["LightBox"] = LightBox;
})($);

使用的時(shí)候:

var lightbox = new LightBox();

當(dāng)年很多人都喜歡這樣開(kāi)發(fā)插件,并且認(rèn)為能寫(xiě)出這種插件的水平至少不低。這種方法只是閉包方式的小改進(jìn),約束js文件返回必須是對(duì)象,對(duì)象其實(shí)就是一些個(gè)方法和屬性的集合。這樣的優(yōu)點(diǎn):

規(guī)范化輸出,更加統(tǒng)一的便于相互依賴和引用。

使用‘類(lèi)’的方式開(kāi)發(fā),便于后面的依賴進(jìn)行擴(kuò)展。

本質(zhì)上這種方法只是對(duì)閉包方法的規(guī)范約束,并沒(méi)有做什么根本改動(dòng)。

3. YUI

早期雅虎出品的一個(gè)工具,模塊化管理只是一部分,其還具有JS壓縮、混淆、請(qǐng)求合并(合并資源需要server端配合)等性能優(yōu)化的工具,說(shuō)其是現(xiàn)有JS模塊化的鼻祖一點(diǎn)都不過(guò)分。

// YUI - 編寫(xiě)模塊
YUI.add("dom", function(Y) {
  Y.DOM = { ... }
})

// YUI - 使用模塊
YUI().use("dom", function(Y) {
  Y.DOM.doSomeThing();
  // use some methods DOM attach to Y
})

// hello.js
YUI.add("hello", function(Y){
    Y.sayHello = function(msg){
        Y.DOM.set(el, "innerHTML", "Hello!");
    }
},"3.0.0",{
    requires:["dom"]
})

// main.js
YUI().use("hello", function(Y){
    Y.sayHello("hey yui loader");
})

YUI的出現(xiàn)令人眼前一新,他提供了一種模塊管理方式:通過(guò)YUI全局對(duì)象去管理不同模塊,所有模塊都只是對(duì)象上的不同屬性,相當(dāng)于是不同程序運(yùn)行在操作系統(tǒng)上。YUI的核心實(shí)現(xiàn)就是閉包,不過(guò)好景不長(zhǎng),具有里程碑式意義的模塊化工具誕生了。

4. CommonJs

2009年Nodejs發(fā)布,其中Commonjs是作為Node中模塊化規(guī)范以及原生模塊面世的。Node中提出的Commonjs規(guī)范具有以下特點(diǎn):

原生Module對(duì)象,每個(gè)文件都是一個(gè)Module實(shí)例

文件內(nèi)通過(guò)require對(duì)象引入指定模塊

所有文件加載均是同步完成

通過(guò)module關(guān)鍵字暴露內(nèi)容

每個(gè)模塊加載一次之后就會(huì)被緩存

模塊編譯本質(zhì)上是沙箱編譯

由于使用了Node的api,只能在服務(wù)端環(huán)境上運(yùn)行

基本上Commonjs發(fā)布之后,就成了Node里面標(biāo)準(zhǔn)的模塊化管理工具。同時(shí)Node還推出了npm包管理工具,npm平臺(tái)上的包均滿足Commonjs規(guī)范,隨著Node與npm的發(fā)展,Commonjs影響力也越來(lái)越大,并且促進(jìn)了后面模塊化工具的發(fā)展,具有里程碑意義的模塊化工具。之前的例子我們這樣改寫(xiě):

a.js

// a.js
var c = require("./c");

module.exports = {
    aStr: "aa",
    aNum: c.cNum + 1
};

b.js

// b.js
var a = require("./a");

exports.bStr = a.aStr + " bb";

c.js

// c.js
exports.cNum = 0;

入口文件就是 index.js

var a = require("./a");
var b = require("./b");

console.log(a.aNum, b.bStr);

可以直觀的看到,使用Commonjs管理模塊,十分方便。Commonjs優(yōu)點(diǎn)在于:

強(qiáng)大的查找模塊功能,開(kāi)發(fā)十分方便

標(biāo)準(zhǔn)化的輸入輸出,非常統(tǒng)一

每個(gè)文件引入自己的依賴,最終形成文件依賴樹(shù)

模塊緩存機(jī)制,提高編譯效率

利用node實(shí)現(xiàn)文件同步讀取

依靠注入變量的沙箱編譯實(shí)現(xiàn)模塊化

這里補(bǔ)充一點(diǎn)沙箱編譯:require進(jìn)來(lái)的js模塊會(huì)被Module模塊注入一些變量,使用立即執(zhí)行函數(shù)編譯,看起來(lái)就好像:

(function (exports, require, module, __filename, __dirname) {
    //原始文件內(nèi)容
})();

看起來(lái)require和module好像是全局對(duì)象,其實(shí)只是閉包中的入?yún)?,并不是真正的全局?duì)象。之前專(zhuān)門(mén)整理探究過(guò) Node中的Module源碼分析,也可以看看阮一峰老師的require()源碼解讀,或者廖雪峰老師的CommonJS規(guī)范。

5. AMD和RequireJS

Commonjs的誕生給js模塊化發(fā)展有了重要的啟發(fā),Commonjs非常受歡迎,但是局限性很明顯:Commonjs基于Node原生api在服務(wù)端可以實(shí)現(xiàn)模塊同步加載,但是僅僅局限于服務(wù)端,客戶端如果同步加載依賴的話時(shí)間消耗非常大,所以需要一個(gè)在客戶端上基于Commonjs但是對(duì)于加載模塊做改進(jìn)的方案,于是AMD規(guī)范誕生了。

AMD是"Asynchronous Module Definition"的縮寫(xiě),意思就是"異步模塊定義"。它采用異步方式加載模塊,模塊的加載不影響它后面語(yǔ)句的運(yùn)行。所有依賴這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到所有依賴加載完成之后(前置依賴),這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。

AMD規(guī)范

AMD與Commonjs一樣都是js模塊化規(guī)范,是一套抽象的約束,與2009年誕生。文檔這里。該約束規(guī)定采用require語(yǔ)句加載模塊,但是不同于CommonJS,它要求兩個(gè)參數(shù):

require([module], callback);

第一個(gè)參數(shù)[module],是一個(gè)數(shù)組,里面的成員就是要加載的模塊;第二個(gè)參數(shù)callback,則是加載成功之后的回調(diào)函數(shù)。如果將前面的代碼改寫(xiě)成AMD形式,就是下面這樣:

require(["math"], function (math) {

    math.add(2, 3);

});

定義了一個(gè)文件,該文件依賴math模塊,當(dāng)math模塊加載完畢之后執(zhí)行回調(diào)函數(shù),這里并沒(méi)有暴露任何變量。不同于Commonjs,在定義模塊的時(shí)候需要使用define函數(shù)定義:

define(id?, dependencies?, factory);

define方法與require類(lèi)似,id是定義模塊的名字,仍然會(huì)在所有依賴加載完畢之后執(zhí)行factory。

RequireJs

RequireJs是js模塊化的工具框架,是AMD規(guī)范的具體實(shí)現(xiàn)。但是有意思的是,RequireJs誕生之后,推廣過(guò)程中產(chǎn)生的AMD規(guī)范。文檔這里。

RequireJs有兩個(gè)最鮮明的特點(diǎn):

依賴前置:動(dòng)態(tài)創(chuàng)建

RequireJs當(dāng)年在國(guó)內(nèi)非常受歡迎,主要是以下優(yōu)點(diǎn):

動(dòng)態(tài)并行加載js,依賴前置,無(wú)需再考慮js加載順序問(wèn)題。

核心還是注入變量的沙箱編譯,解決模塊化問(wèn)題。

規(guī)范化輸入輸出,使用起來(lái)方便。

對(duì)于不滿足AMD規(guī)范的文件可以很好地兼容。

不過(guò)個(gè)人覺(jué)得RequireJs配置還是挺麻煩的,但是當(dāng)年已經(jīng)非常方便了。

6. CMD和SeaJs CMD規(guī)范

同樣是受到Commonjs的啟發(fā),國(guó)內(nèi)(阿里)誕生了一個(gè)CMD(Common Module Definition)規(guī)范。該規(guī)范借鑒了Commonjs的規(guī)范與AMD規(guī)范,在兩者基礎(chǔ)上做了改進(jìn)。

define(id?, dependencies?, factory);

與AMD相比非常類(lèi)似,CMD規(guī)范(2011)具有以下特點(diǎn):

define定義模塊,require加載模塊,exports暴露變量。

不同于AMD的依賴前置,CMD推崇依賴就近(需要的時(shí)候再加載)

推崇api功能單一,一個(gè)模塊干一件事。

SeaJs

SeaJs是CMD規(guī)范的實(shí)現(xiàn),跟RequireJs類(lèi)似,CMD也是SeaJs推廣過(guò)程中誕生的規(guī)范。CMD借鑒了很多AMD和Commonjs優(yōu)點(diǎn),同樣SeaJs也對(duì)AMD和Commonjs做出了很多兼容。

SeaJs核心特點(diǎn):

需要配置模塊對(duì)應(yīng)的url。

入口文件執(zhí)行之后,根據(jù)文件內(nèi)的依賴關(guān)系整理出依賴樹(shù),然后通過(guò)插入

對(duì)于seaJs中的就近依賴,有必要多帶帶說(shuō)一下。來(lái)看一下上面例子中的log順序:

seaJs執(zhí)行入口文件,入口文件依賴a和b,a內(nèi)部則依賴c。

依賴關(guān)系梳理完畢,開(kāi)始動(dòng)態(tài)script標(biāo)簽下載依賴,控制臺(tái)輸出:

a1
a2
b1
b2
c1
c2

依賴加載之后,按照依賴順序開(kāi)始解析模塊內(nèi)部的define:inner a1

在a模塊中遇到了require("./c"),就近依賴這時(shí)候才去執(zhí)行c模塊的factory:inner c1

然后解析b模塊:inner b1

全部依賴加載完畢,執(zhí)行最后的factory:index

完整的順序就是:

a1
a2
b1
b2
c1
c2
inner a1
inner c1 
inner b1
index

這是一個(gè)可以很好理解SeaJs的例子。

7. ES6中的模塊化

之前的各種方法和框架,都出自于各個(gè)大公司或者社區(qū),都是民間出臺(tái)的結(jié)局方法。到了2015年,ES6規(guī)范中,終于將模塊化納入JavaScript標(biāo)準(zhǔn),從此js模塊化被官方扶正,也是未來(lái)js的標(biāo)準(zhǔn)。

之前那個(gè)例子再用ES6的方式實(shí)現(xiàn)一次:

a.js

import {cNum} from "./c";

export default {
    aStr: "aa",
    aNum: cNum + 1
};

b.js

import {aStr} from "./a";

export const bStr = aStr + " bb";

c.js

export const bNum = 0;

index.js

import {aNum} from "./a";
import {bStr} from "./b";

console.log(aNum, bStr);

可以看到,ES6中的模塊化在Commonjs的基礎(chǔ)上有所不同,增加了關(guān)鍵字import,export,default,as,from,而不是全局對(duì)象。另外深入理解的話,有兩點(diǎn)主要的區(qū)別:

CommonJS 模塊輸出的是一個(gè)值的拷貝,ES6 模塊輸出的是值的引用。

CommonJS 模塊是運(yùn)行時(shí)加載,ES6 模塊是編譯時(shí)輸出接口。

一個(gè)經(jīng)典的例子:

// counter.js
exports.count = 0
setTimeout(function () {
  console.log("increase count to", ++exports.count, "in counter.js after 500ms")
}, 500)

// commonjs.js
const {count} = require("./counter")
setTimeout(function () {
  console.log("read count after 1000ms in commonjs is", count)
}, 1000)

//es6.js
import {count} from "./counter"
setTimeout(function () {
  console.log("read count after 1000ms in es6 is", count)
}, 1000)

分別運(yùn)行 commonjs.js 和 es6.js:

?  test node commonjs.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in commonjs is 0
?  test babel-node es6.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in es6 is 1

這個(gè)例子解釋了CommonJS 模塊輸出的是值的拷貝,也就是說(shuō),一旦輸出一個(gè)值,模塊內(nèi)部的變化就影響不到這個(gè)值。ES6 模塊的運(yùn)行機(jī)制與 CommonJS 不一樣。JS 引擎對(duì)腳本靜態(tài)分析的時(shí)候,遇到模塊加載命令import,就會(huì)生成一個(gè)只讀引用。等到腳本真正執(zhí)行時(shí),再根據(jù)這個(gè)只讀引用,到被加載的那個(gè)模塊里面去取值。換句話說(shuō),ES6 的import有點(diǎn)像 Unix 系統(tǒng)的“符號(hào)連接”,原始值變了,import加載的值也會(huì)跟著變。因此,ES6 模塊是動(dòng)態(tài)引用,并且不會(huì)緩存值,模塊里面的變量綁定其所在的模塊。

更多ES6模塊化特點(diǎn),參照阮一峰老師的ECMAScript 6 入門(mén)。

總結(jié)思考

寫(xiě)了這么多,其實(shí)都是蜻蜓點(diǎn)水地從使用方式和運(yùn)行原理分析了不同方法的實(shí)現(xiàn)?,F(xiàn)在重新看一下當(dāng)時(shí)模塊化的痛點(diǎn):

全局變量污染:各個(gè)文件的變量都是掛載到window對(duì)象上,污染全局變量。

變量重名:不同文件中的變量如果重名,后面的會(huì)覆蓋前面的,造成程序運(yùn)行錯(cuò)誤。

文件依賴順序:多個(gè)文件之間存在依賴關(guān)系,需要保證一定加載順序問(wèn)題嚴(yán)重。

不同的模塊化手段都在致力于解決這些問(wèn)題。前兩個(gè)問(wèn)題其實(shí)很好解決,使用閉包配合立即執(zhí)行函數(shù),高級(jí)一點(diǎn)使用沙箱編譯,緩存輸出等等。

我覺(jué)得真正的難點(diǎn)在于依賴關(guān)系梳理以及加載。Commonjs在服務(wù)端使用fs可以接近同步的讀取文件,但是在瀏覽器中,不管是RequireJs還是SeaJs,都是使用動(dòng)態(tài)創(chuàng)建script標(biāo)簽方式加載,依賴全部加載完畢之后執(zhí)行,省去了開(kāi)發(fā)手動(dòng)書(shū)寫(xiě)加載順序這一煩惱。

到了ES6,官方出臺(tái)設(shè)定標(biāo)準(zhǔn),不在需要出框架或者h(yuǎn)ack的方式解決該問(wèn)題,該項(xiàng)已經(jīng)作為標(biāo)準(zhǔn)要求各瀏覽器實(shí)現(xiàn),雖然現(xiàn)在瀏覽器全部實(shí)現(xiàn)該標(biāo)準(zhǔn)尚無(wú)時(shí)日,但是肯定是未來(lái)趨勢(shì)。

參考

JavaScript模塊化開(kāi)發(fā)的演進(jìn)歷程

精讀 js 模塊化發(fā)展

淺談模塊化開(kāi)發(fā)

深入理解 ES6 模塊機(jī)制

Module 的加載實(shí)現(xiàn)

SeaJS 從入門(mén)到原理

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/95486.html

相關(guān)文章

  • JavaScript模塊發(fā)展變遷史

    摘要:前兩天有朋友拿了這樣一段代碼來(lái)問(wèn)我,我想把一段代碼寫(xiě)成模塊化的樣子,你幫我看看是不是這樣的。的一個(gè)好處在與依賴前置,所有被使用到的模塊都會(huì)被提前加載好,從而加快運(yùn)行速度。 前兩天有朋友拿了這樣一段代碼來(lái)問(wèn)我,我想把一段代碼寫(xiě)成模塊化的樣子,你幫我看看是不是這樣的。,代碼大概是這樣的: (function(global) { var myModules = { n...

    姘存按 評(píng)論0 收藏0
  • 精讀《js 塊化發(fā)展

    摘要:我是這一期的主持人黃子毅本期精讀的文章是。模塊化需要保證全局變量盡量干凈,目前為止的模塊化方案都沒(méi)有很好的做到這一點(diǎn)。精讀本次提出獨(dú)到觀點(diǎn)的同學(xué)有流形,黃子毅,蘇里約,,楊森,淡蒼,留影,精讀由此歸納。 這次是前端精讀期刊與大家第一次正式碰面,我們每周會(huì)精讀并分析若干篇精品好文,試圖討論出結(jié)論性觀點(diǎn)。沒(méi)錯(cuò),我們?cè)噲D通過(guò)觀點(diǎn)的碰撞,爭(zhēng)做無(wú)主觀精品好文的意見(jiàn)領(lǐng)袖。 我是這一期的主持人 ——...

    Freelander 評(píng)論0 收藏0
  • 全新單頁(yè)JavaScript框架Amaple

    摘要:但目前來(lái)看,單頁(yè)應(yīng)用在技術(shù)實(shí)現(xiàn)和體驗(yàn)上還有更大的發(fā)展空間,而這就是所要推進(jìn)的。模塊化頁(yè)面模塊化單頁(yè)應(yīng)用的特點(diǎn)之一是將頁(yè)面劃分為多個(gè)模塊,跳轉(zhuǎn)時(shí)更新模塊的內(nèi)容。與其他單頁(yè)庫(kù)相比,它們的職責(zé)更清晰,也易于理解。 showImg(https://segmentfault.com/img/bV2wO3?w=792&h=303);單頁(yè)Web應(yīng)用作為新一代Web模式,為用戶提供了更流暢的體驗(yàn)滿足感...

    djfml 評(píng)論0 收藏0
  • 全新單頁(yè)JavaScript框架Amaple

    摘要:但目前來(lái)看,單頁(yè)應(yīng)用在技術(shù)實(shí)現(xiàn)和體驗(yàn)上還有更大的發(fā)展空間,而這就是所要推進(jìn)的。模塊化頁(yè)面模塊化單頁(yè)應(yīng)用的特點(diǎn)之一是將頁(yè)面劃分為多個(gè)模塊,跳轉(zhuǎn)時(shí)更新模塊的內(nèi)容。與其他單頁(yè)庫(kù)相比,它們的職責(zé)更清晰,也易于理解。 showImg(https://segmentfault.com/img/bV2wO3?w=792&h=303);單頁(yè)Web應(yīng)用作為新一代Web模式,為用戶提供了更流暢的體驗(yàn)滿足感...

    yanwei 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<