隨著現(xiàn)代 JavaScript 開發(fā) Web 應(yīng)用變得復(fù)雜,命名沖突和依賴關(guān)系也變得難以處理,因此需要模塊化。而引入模塊化,可以避免命名沖突、方便依賴關(guān)系管理、提高了代碼的復(fù)用性和和維護性,因此,在 JavaScript 沒有模塊功能的前提下,只能通過第三方規(guī)范實現(xiàn)模塊化:
它們都是基于 JavaScript 的語法和詞法特性 “偽造” 出類似模塊的行為。而 TC-39 在 ECMAScript 2015 中加入了模塊規(guī)范,簡化了上面介紹的模塊加載器,原生意味著可以取代上述的規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案,比使用庫更有效率。而 ES6 的模塊化的設(shè)計目標(biāo):
ECMAScript 在 2015 年開始支持模塊標(biāo)準(zhǔn),此后逐漸發(fā)展,現(xiàn)已經(jīng)得到了所有主流瀏覽器的支持。ECMAScript 2015 版本也被稱為 ECMAScript 6。
ES6 模塊借用了 CommonJS 和 AMD 的很多優(yōu)秀特性,如下所示:
ES6 模塊系統(tǒng)也增加了一些新行為。
瀏覽器運行時在知道應(yīng)該把某個文件當(dāng)成模塊時,會有條件地按照上述 ES6 模塊行為來施加限制。與 <script type="module"> 關(guān)聯(lián)或者通過 import 語句加載的 JavaScript 文件會被認(rèn)定為模塊。
ES6 模塊內(nèi)部的所有變量,外部無法獲取,因此提供了 export 關(guān)鍵字從模塊中導(dǎo)出實時綁定的函數(shù)、對象或原始值,這樣其他程序可以通過 import 關(guān)鍵字使用它們。export 支持兩種導(dǎo)出方式:命名導(dǎo)出和默認(rèn)導(dǎo)出。不同的導(dǎo)出方式對應(yīng)不同的導(dǎo)入方式。
在 ES6 模塊中,無論是否聲明 "use strict;" 語句,默認(rèn)情況下模塊都是在嚴(yán)格模式下運行。export 語句不能用在嵌入式腳本中。
通過在聲明的前面加上 export 關(guān)鍵字,一個模塊可以導(dǎo)出多個內(nèi)容。這些導(dǎo)出的內(nèi)容通過名字區(qū)分,被稱為命名導(dǎo)出。
// 導(dǎo)出單個特性(可以導(dǎo)出 var,let,const)
export let name="小明";
export function sayHi(name) {
console.log(`Hello, ${name}!`);
}
export class Sample {
...
}
或者導(dǎo)出事先定義的特性
let name="小明";
const age=18;
function sayHi(name) {
console.log(`Hello, ${name}!`);
}
export {name, age, sayHi}
導(dǎo)出時也可以指定別名,別名必須在 export 子句的大括號語法中指定。因此,聲明值、導(dǎo)出值和未導(dǎo)出值提供別名不能在一行完成。
export {name as username, age, sayHi}
但導(dǎo)出語句必須在模塊頂級,不能嵌套在某個塊中:
// 允許
export ...
// 不允許
if (condition) {
export ...
}
默認(rèn)導(dǎo)出就好像模塊與被導(dǎo)出的值是一回事。默認(rèn)導(dǎo)出使用 default 關(guān)鍵字將一個值聲明為默認(rèn)導(dǎo)出,每個模塊只能有一個默認(rèn)導(dǎo)出。重復(fù)的默認(rèn)導(dǎo)出會導(dǎo)致 SyntaxError。如下所示:
// 導(dǎo)出事先定義的特性作為默認(rèn)值
export default {
name: "Xiao Ming",
age: 18,
sex: "boy"
};
export {sayHi as default} // ES 6 模塊會識別作為別名提供的 default 關(guān)鍵字。此時,雖然對應(yīng)的值是使用命名語法導(dǎo)出的,實際上則會稱為默認(rèn)導(dǎo)出 等同于 export default function sayHi() {}
// 導(dǎo)出單個特性作為默認(rèn)值
export default function () {...}
export default class {...}
ES6 規(guī)范對不同形式的 export 語句中可以使用什么不可以使用什么規(guī)定了限制。某些形式允許聲明和賦值,某些形式只允許表達(dá)式,而某些形式則只允許簡單標(biāo)識符。注意,有的形式使用了分號,有的則沒有。
下面列出幾種會導(dǎo)致錯誤的 export 形式:
// 會導(dǎo)致錯誤的不同形式:
// 行內(nèi)默認(rèn)導(dǎo)出中不能出現(xiàn)變量聲明
export default const name='小劉';
// 只有標(biāo)識符可以出現(xiàn)在export 子句中
export { 123 as name }
// 別名只能在export 子句中出現(xiàn)
export const name='小紅' as uname;
注意:聲明、賦值和導(dǎo)出標(biāo)識符最好分開。這樣不容易搞錯了,同時也可以讓 export 語句集中在一塊。而且,沒有被 export 關(guān)鍵字導(dǎo)出的變量、函數(shù)或類會在模塊內(nèi)保持私有。
模塊導(dǎo)入的值還可以再次導(dǎo)出,這樣的話,可以在父模塊集中多個模塊的多個導(dǎo)出。可以使用 export from 語法實現(xiàn):
export {default as m1, name} from './module1.js'
// 等效于
import {default as m1, name} from "./module1.js"
export {m1, name}
外部模塊的默認(rèn)導(dǎo)出也可以重用為當(dāng)前模塊的默認(rèn)導(dǎo)出:
export { default } from './module1.js';
也可以在重新導(dǎo)出時,將導(dǎo)入模塊修改為默認(rèn)導(dǎo)出,如下所示:
export { name as default } from './module1.js';
而想要將所有命名導(dǎo)出可以使用如下語法:
export * from './module1.js';
該語法會忽略默認(rèn)導(dǎo)出。但這種語法也要注意導(dǎo)出名稱是否沖突。如下所示:
// module1.js
export const name="module1:name";
// module2.js
export * from './mudule1.js'
export const name="module2:name";
// index.js
import { name } from './module2.js';
console.log(name); // module2:name
最終輸出的是 module2.js 中的值,這個 “重寫” 是靜默發(fā)生的。
使用 export 關(guān)鍵字定義了模塊的對外接口以后,其它模塊就能通過 import 關(guān)鍵字加載這個模塊了。但與 export 類似,import 也必須出現(xiàn)在模塊的頂級:
// 允許
import ...
// 不允許
if (condition) {
import ...
}
模塊標(biāo)識符可以是相對于當(dāng)前模塊的相對路徑,也可以是指向模塊文件的絕對路徑。它必須是純字符串,不能是動態(tài)計算的結(jié)果。例如,不能是拼接的字符串。
當(dāng)使用 export 命名導(dǎo)出時,可以使用 * 批量獲取并賦值給保存導(dǎo)出集合的別名,而無須列出每個標(biāo)識符:
const name="Xiao Ming", age=18, sex="boy";
export {name, age, sex}
// 上面的命名導(dǎo)出可以使用如下形式導(dǎo)入(上面的代碼是在 module1.js 模塊中)
import * as Sample from "./module1.js"
console.log(`My name is ${Sample.name}, A ${Sample.sex},${Sample.age} years old.`);
也可以指名導(dǎo)入,只需要把名字放在 {} 中即可:
import {name, sex as s, age} from "./module1.js";
console.log(`My name is ${name}, A ${s},${age} years old.`);
import 引入是采用的 Singleton 模式,多次使用 import 引入同一個模塊時,只會引入一次該模塊的實例:
import {name, age} from "./module1.js";
import {sex as s} from "./module1.js";
// 等同于,并且只會引入一個 module1.js 實例
import {name, sex as s, age} from "./module1.js";
而使用默認(rèn)導(dǎo)出的話,可以使用 default 關(guān)鍵字并提供別名來導(dǎo)入,也可以直接使用標(biāo)識符就是默認(rèn)導(dǎo)出的別名導(dǎo)入:
import {default as Sample} from "./module1.js"
// 與下面的方式等效
import Sample from "./module1.js"
而模塊中同時有命名導(dǎo)出和默認(rèn)導(dǎo)出,可以在 import 語句中同時導(dǎo)入。下面三種方式都等效。
import Sample, {sayHi} from "./module1.js"
import {default as Sample, sayHi} from "./module1.js"
import Sample, * as M1 from "./module1.js"
當(dāng)然,也可以將整個模塊作為副作用而導(dǎo)入,而不導(dǎo)入模塊中的特定內(nèi)容。這將運行模塊中的全局代碼,但實際上不導(dǎo)入任何值。
import './module1.js'
import 導(dǎo)入的值與 export 導(dǎo)出的值是綁定關(guān)系,綁定是不可變的。因此,import 對所導(dǎo)入的模塊是只讀的。但是可以通過調(diào)用被導(dǎo)入模塊的函數(shù)來達(dá)到目的。
import Sample, * as M1 from "./module1.js"
Sample="Modify Sample"; // 錯誤
M1.module1="Module 1"; // 錯誤
Sample.name="小亮"; // 允許
這樣做的好處是能夠支持循環(huán)依賴,并且一個大的模塊可以拆成若干個小模塊時也可以運行,只要不嘗試修改導(dǎo)入的值。
注意:如果要在瀏覽器中原生加載模塊,則文件必須帶有 .js 擴展名,不然可能無法解析。而使用構(gòu)建工具或第三方模塊加載器打包或解析 ES6 模塊,可能不需要包含擴展名。
標(biāo)準(zhǔn)的 import 關(guān)鍵字導(dǎo)入模塊是靜態(tài)的,會使所有被導(dǎo)入的模塊,在加載時就被編譯。而最新的 ES11 標(biāo)準(zhǔn)中引入了動態(tài)導(dǎo)入函數(shù) import(),不必預(yù)先加載所有模塊。該函數(shù)會將模塊的路徑作為參數(shù),并返回一個 Promise,在它的 then 回調(diào)里使用加載后的模塊:
import ('./module1.mjs')
.then((module)=> {
// Do something with the module.
});
這種使用方式也支持 await 關(guān)鍵字。
let module=await import('./module1.js');
import() 的使用場景如下:
ES6 模塊既可以通過瀏覽器原生加載,也可以與第三方加載器和構(gòu)建工具一起加載。
完全支持 ES6 模塊的瀏覽器可以從頂級模塊異步加載整個依賴圖。瀏覽器會解析入口模塊,確定依賴,并發(fā)送對依賴模塊的請求。這些文件通過網(wǎng)絡(luò)返回后,瀏覽器會解析它們的內(nèi)容,確認(rèn)依賴,如果二級依賴還沒有加載,則會發(fā)送更多請求。這個異步遞歸加載過程會持續(xù)到整個依賴圖都解析完成。解析完依賴,應(yīng)用就可以正式加載模塊了。
模塊文件按需加載,且后續(xù)模塊的請求會因為每個依賴模塊的網(wǎng)絡(luò)延遲而同步延遲。即,module1 依賴 module2,module2 依賴 module3。瀏覽器在對 module2 的請求完成之前并不知道要請求 module3。這種架子啊方式效率高,也不需要外部工具,但加載大型應(yīng)用的深度依賴圖可能要花費很長時間。
想要在 HTML 頁面中使用 ES6 模塊,需要將 type="module" 屬性放在 <script> 標(biāo)簽中,來聲明該 <script> 所包含的代碼在瀏覽器中作為模塊執(zhí)行。它可以嵌入在網(wǎng)頁中,也可以作為外部文件引入:
<script type="module">
// 模塊代碼
</script>
<script type="module" src="./module1.js"></script>
<script type="module">模塊加載的順序與 <script defer> 加載的腳本一樣按順序執(zhí)行。但執(zhí)行會延遲到文檔解析完成,但執(zhí)行順序就是<script type="module">在頁面中出現(xiàn)的順序。
也可以給模塊標(biāo)簽添加 async 屬性。這樣影響是雙重的,不僅模塊執(zhí)行順序不再與 <script> 標(biāo)簽在頁面中的順序綁定,模塊也不會等待文檔完成解析才執(zhí)行。不過,入口模塊必須等待其依賴加載完成。
Worker 為了支持 ES6 模塊,在 Worker 構(gòu)造函數(shù)中可以接收第二個參數(shù),其 type 屬性的默認(rèn)值是 classic,可以將 type 設(shè)置為 module 來加載模塊文件。如下所示:
// 第二個參數(shù)默認(rèn)為{ type: 'classic' }
const scriptWorker=new Worker('scriptWorker.js');
const moduleWorker=new Worker('moduleWorker.js', { type: 'module' });
在基于模塊的工作者內(nèi)部,self.importScripts() 方法通常用于在基于腳本的工作者中加載外部腳本,調(diào)用它會拋出錯誤。這是因為模塊的 import 行為包含了 importScripts()。
如果瀏覽器原生支持 ES6 模塊,可以直接使用,而不支持的瀏覽器可以使用第三方模塊系統(tǒng)(System.js)或在構(gòu)建時將 ES6 模塊進行轉(zhuǎn)譯。
腳本模塊可以使用 type="module" 屬性設(shè)定,而對于不支持模塊的瀏覽器,可以使用 nomodule 屬性。此屬性會通知支持 ES6 模塊的瀏覽器不執(zhí)行腳本。不支持模塊的瀏覽器無法識別該屬性,從而忽略該屬性。如下所示:
// 支持模塊的瀏覽器會執(zhí)行這段腳本
// 不支持模塊的瀏覽器不會執(zhí)行這段腳本
<script type="module" src="module.js"></script>
// 支持模塊的瀏覽器不會執(zhí)行這段腳本
// 不支持模塊的瀏覽器會執(zhí)行這段腳本
<script nomodule src="script.js"></script>
ES6 在語言層面上支持了模塊,結(jié)束了 CommonJS 和 AMD 這兩個模塊加載器的長期分裂狀況,重新定義了模塊功能,集兩個規(guī)范于一身,并通過簡單的語法聲明來暴露。
模塊的使用不同方式加載 .js 文件,它與腳本有很大的不同:
瀏覽器對原生模塊的支持越來越好,但也提供了穩(wěn)健的工具以實現(xiàn)從不支持到支持 ES6 模塊的過渡。
、為什么用命令行模式
使用GUI方式啟動jmeter,運行線程較多的測試時,會造成內(nèi)存和CPU的大量消耗,導(dǎo)致客戶機卡死;
所以一般采用的方式是在GUI模式下調(diào)整測試腳本,再用命令行模式執(zhí)行;
命令行方式支持在多個環(huán)境下使用,windosw的dos環(huán)境下,也可以在linux環(huán)境上執(zhí)行。
注意:使用命令執(zhí)行jmeter腳本必須使用jmeter 3.0及以上版本。
2、怎么用
2.1、執(zhí)行命令
jmeter -n -t <testplan filename> -l <listener filename>
示例: jmeter -n -t testplan.jmx -l test.jtl
示例含義:表示以命令行模式運行testplan.jmx文件,輸出的日志文件為test.jtl
2.2、參數(shù)介紹
Jmeter官方手冊給的介紹如下:
-h, –help -> prints usage information and exit
-n, –nongui -> run JMeter in nongui mode
-t, –testfile <argument> -> the jmeter test(.jmx) file to run
-l, –logfile <argument> -> the file to log samples to
-r, –runremote -> Start remote servers (as defined in remote_hosts)
-H, –proxyHost <argument> -> Set a proxy server for JMeter to use
-P, –proxyPort <argument> -> Set proxy server port for JMeter to use
中文釋義:
-h 幫助 -> 打印出有用的信息并退出
-n 非 GUI 模式 -> 在非 GUI 模式下運行 JMeter
-t 測試文件 -> 要運行的 JMeter 測試腳本文件
-l 日志文件 -> 記錄結(jié)果的文件
-R 遠(yuǎn)程執(zhí)行 -> 遠(yuǎn)程執(zhí)行機的IP(ip地址)如果有多個ip時,使用-R 192.168.2.170,192.168.2.171(分布式使用)
-r 遠(yuǎn)程執(zhí)行 -> 在Jmter.properties文件中指定的所有遠(yuǎn)程服務(wù)器(分布式使用)
-H 代理主機 -> 設(shè)置 JMeter 使用的代理主機
-P 代理端口 -> 設(shè)置 JMeter 使用的代理主機的端口號
2.3、執(zhí)行過程
命令:jmeter -n -t C:\Users\yzs\Desktop\Unione_performance.jmx -l report-result.jtl
不在jmeter安卓目錄執(zhí)行腳本的前提是配置了jmeter的環(huán)境變量。
上述的命令有測試結(jié)果保存到D:\report中,在GUI模式下查看測試報告:
1、在測試計劃下,添加對應(yīng)的測試報告元件,舉例增加了:查看結(jié)果樹、聚合報告
2、在“所有數(shù)據(jù)寫入一個文件”,選擇加載對應(yīng)的結(jié)果文件
3、下面就會有對應(yīng)的表格展示,具體見下圖
2.5、命令行傳遞變量值
設(shè)置線程組的線程數(shù)和循環(huán)次數(shù)。
注意格式:
${__P(threadNum)}
${__P(threadCount)}
其中P前面是兩個下劃線,()內(nèi)就是變量名
執(zhí)行時,在命令行中用-J參數(shù)給變量賦值即可:
jmeter -n -t C:\Users\yzs\Desktop\Unione_performance.jmx -J threadNum=10 -J threadCount=2 -l report-result.jtl
此次測試相當(dāng)于:10個線程,循環(huán)2次,共計20個請求。
3、生成HTML報告
生成HTML報告有2種方式,一種是直接在命令行加上-o參數(shù),另一種是已有jtl結(jié)果文件,運行命令生成報告
3.1、命令行直接生成報告
jmeter -n -t 【Jmx腳本位置】-l 【中間文件result.jtl位置】-e -o 【報告指定文件夾】
-e:測試結(jié)束后,生成測試報告
-o:指定測試報告的存放位置
注意:-o后面跟的文件夾一定是不存在的或者是空文件夾
3.2、已有jtl結(jié)果文件,運行命令生成報告
jmeter -g【已經(jīng)存在的.jtl文件的路徑】-o 【用于存放html報告的目錄】
注意:經(jīng)實操,windows系統(tǒng)上,以上2種方法都可以生成HTML測試報告,但是在Linux系統(tǒng)上第1種方法,沒有生成報告,只有第二種方法才可以(具體原因后面在慢慢找吧)
3.3、HTML報告注解
用瀏覽器打開index.html
報告詳解
Dashboard:(重點查看)
Test and Report informations:指的是測試和報告信息
APDEX(Application Performance Index):應(yīng)用程序性能滿意度的標(biāo)準(zhǔn)
其中,
Requests Summary:請求的通過率(OK)與失敗率(KO),百分比顯示
Statistics:數(shù)據(jù)分析,基本將Summary Report和Aggrerate Report的結(jié)果合并(平均響應(yīng)時間、TPS在此查看)
Errors:錯誤情況,依據(jù)不同的錯誤類型,將所有錯誤結(jié)果展示
關(guān)于Apdex的補充:
性能指數(shù),Apdex(Application Performance Index)是一個國際通用標(biāo)準(zhǔn),Apdex 是用戶對應(yīng)用性能滿意度的量化值。它提供了一個統(tǒng)一的測量和報告用戶體驗的方法,把最終用戶的體驗和應(yīng)用性能作為一個完整的指標(biāo)進行統(tǒng)一度量。下圖表示為通用用戶滿意度區(qū)域,0代表沒有滿意用戶,1則代表所有用戶都滿意。實際業(yè)務(wù)系統(tǒng)開發(fā)過程中,1是團隊的追求目標(biāo)。
若所有請求的Apdex值都接近1,說明用戶滿意度優(yōu)秀,也從側(cè)面說明了服務(wù)器響應(yīng)速度快。
通常而言,最低要求超過0.5,當(dāng)然項目組可設(shè)定具體需求。
Charts:(輔助分析)
主要有如下特點:
(1)將測試過程中經(jīng)常使用的數(shù)據(jù),用圖表的形式展示,讓測試結(jié)果更加直觀
(2)每個圖表數(shù)據(jù),有兩種展示形式
(3)支持請求樣例過濾顯示
(4)支持導(dǎo)出PNG圖片格式
Over Time Charts:
Throughput Charts:
Response Times Charts:
3.4、HTML報告的自定義配置
JMeter3.0開始在bin目錄新增了reportgenerator.properties文件保存了所有關(guān)于圖形化HTML報告生成模塊的默認(rèn)配置,要變更配置,建議不要直接編輯該文件,而是推薦在user.properties中去配置和覆蓋。
3.4.1總體配置
總體配置都是以jmeter.reportgenerator.為前綴,如:jmeter.reportgenerator.overall_granularity=60000
# Change this parameter if you want to change the granularity of over time graphs.
jmeter.reportgenerator.overall_granularity=6000
Apdext=(Satisfied Count + Tolerating Count / 2) / Total Samples
另外,在jmeter.properties中,有關(guān)于集合報告中的三個百分位的默認(rèn)值:
aggregate_rpt_pct1 : Defaults to 50
aggregate_rpt_pct2 : Defaults to 70
aggregate_rpt_pct3 : Defaults to 99
3.5、HTML報告的定制
JMeter的HTML報告生成時是使用了固定的模板,模板文件路徑為./bin/report-template。
進入該目錄可以看到報告的每個頁面都有一個.fmkr模板文件,包括index.html.fmkr和./content/pages路徑下的幾個文件。通過查看這些模板文件,就可以知道怎樣去進行報告的輕度定制,比如將一些文本修改得更易懂,或者修改為中文等
頁面的title
默認(rèn)為"Apache JMeter Dashboard"
可以由reportgenerator.properties中的jmeter.reportgenerator.report_title來統(tǒng)一定義,這種方式就是所有頁面的title都使用同一個。
也可以直接修改對應(yīng)的.fmkr文件中的title標(biāo)簽中雙引號內(nèi)的值,如<title>${reportTitle!"想要設(shè)置的title"}</title>,這中方式可以為每個頁面單獨定義title
圖表的名稱
當(dāng)前版本下,各圖表的名稱是直接在模板文件中定義,要修改也是直接修改模板文件中對應(yīng)元素的值即可
如要修改Transactions Per Second圖表的名稱,可以直接在./content/pages/Throughput.html.fmkr文件中修改,效果如下圖
odash, Moment, Axios, Async... 這些是有用的JavaScript庫,您希望在許多Vue.js應(yīng)用程序中使用這些庫。
但是,隨著項目的發(fā)展,您將將代碼分離為單個文件組件和模塊文件。您還可能希望在不同的環(huán)境中運行您的應(yīng)用程序,以允許服務(wù)器呈現(xiàn)。
除非您找到一種簡單而健壯的方法將這些JavaScript庫包含在組件和模塊文件中,否則它們將是一個麻煩!
將庫添加到項目中的天真方法是通過將庫附加到window目的:
entry.js
JavaScript
window._=require('lodash');
MyComponent.vue
JavaScript
export default { created() { console.log(_.isEmpty() ? 'Lodash everywhere!' : 'Uh oh..'); }}
針對窗口變量的情況很長,但是,特別是在本討論中,它們不適用于服務(wù)器呈現(xiàn)。當(dāng)應(yīng)用程序在服務(wù)器上運行時,window對象將是未定義的,因此試圖訪問屬性將以錯誤結(jié)束。
另一種二流方法是將庫導(dǎo)入到每個文件中:
MyComponent.vue
JavaScript
import _ from 'lodash';
export default {
created() {
console.log(_.isEmpty() ? 'Lodash is available here!' : 'Uh oh..');
}
}
這是可行的,但它并不是很干燥,而且基本上是一種痛苦:您必須記住將它導(dǎo)入到每個文件中,如果您停止在該文件中使用它,則再次刪除它。如果您沒有正確地設(shè)置您的構(gòu)建工具,那么您的構(gòu)建中可能會有多個相同庫的副本。
在Vue項目中使用JavaScript庫的最干凈和最健壯的方法是將其代理到Vue Prototype對象的屬性。讓我們這樣做,將時間、日期和時間庫添加到我們的項目中:
entry.js
JavaScript
import moment from 'moment';
Object.definePrototype(Vue.prototype, '$moment', { value: moment });
由于所有組件都從Vue Prototype對象繼承它們的方法,這將使所有組件都可以在沒有全局變量或手動導(dǎo)入的任何組件中自動使用。可以簡單地在任何實例/組件中訪問this.$moment:
MyNewComponent.vue
JavaScript
export default {
created() {
console.log('The time is ' . this.$moment().format("HH:mm"));
}
}
現(xiàn)在讓我們花時間了解一下這是如何工作的。
我們通常會設(shè)置如下對象屬性:
JavaScript
Vue.prototype.$moment=moment;
你可以在這里做,但是Object.defineProperty相反,我們可以使用descriptor。描述符允許我們設(shè)置一些低級別的詳細(xì)信息,例如我們的屬性是否可寫,以及它是否在枚舉期間顯示在for循環(huán)等等。
在日常的JavaScript中,我們通常不會考慮這個問題,因為99%的時間我們都不需要這樣的細(xì)節(jié)來分配屬性。但是在這里,它給了我們一個明顯的優(yōu)勢:用描述符創(chuàng)建的屬性是只讀默認(rèn)情況下。
這意味著,一些缺少咖啡的開發(fā)人員(可能是您)無法在組件中做一些愚蠢的事情,從而破壞一切:
JavaScript
this.$http='Assign some random thing to the instance method';
this.$http.get('/'); // TypeError: this.$http.get is not a function
相反,我們的只讀實例方法保護我們的庫,如果您試圖覆蓋它,您將得到“TypeError:NotAssistto只讀屬性”。
您會注意到,我們將我們的庫代理到一個以美元符號“$”為前綴的屬性名。您可能還看到了其他屬性和方法,如$refs, $on, $mount,等等,它們也有這個前綴。
雖然不是必需的,但前綴被添加到屬性中,以提醒缺乏咖啡的開發(fā)人員(再次),這是一個歡迎您使用的公共API屬性或方法,與實例的其他屬性不同,這些屬性可能只是用于Vue的內(nèi)部使用。
作為一種基于原型的語言,JavaScript中沒有(真正的)類,因此它沒有“私有”和“公共”變量或“靜態(tài)”方法。這個公約是一個溫和的替代,我認(rèn)為是值得遵循的。
您還會注意到要使用您使用的庫this.libraryName這可能并不令人驚訝,因為它現(xiàn)在是一個實例方法。
但是,這樣做的一個結(jié)果是,與全局變量不同,您必須確保在使用庫時處于正確的范圍內(nèi)。在回調(diào)方法中,無法訪問this你的圖書館住的地方。
FAT箭頭回調(diào)是確保您保持在正確范圍內(nèi)的一個很好的解決方案:
JavaScript
this.$http.get('/').then(res=> {
if (res.status !==200) {
this.$http.get('/') // etc
// Only works in a fat arrow callback.
}
});
為什么不把它變成插件呢?
如果您計劃在多個Vue項目中使用一個庫,或者您想要與世界共享它,您可以將其構(gòu)建到您自己的插件中!
插件抽象了復(fù)雜性,并允許您在項目中簡單地執(zhí)行以下操作以添加所選庫:
JavaScript
import MyLibraryPlugin from 'my-library-plugin';
Vue.use(MyLibraryPlugin);
使用這兩行,我們可以在任何組件中使用庫,就像我們可以使用Vue路由器、Vuex和其他利用Vue.use.
首先,為插件創(chuàng)建一個文件。在本例中,我將制作一個插件,將Axios添加到所有Vue實例和組件中,因此我將調(diào)用該文件axios.js.
主要要了解的是,插件必須公開install方法,它將Vue構(gòu)造函數(shù)作為第一個參數(shù):
axios.js
JavaScript
export default {
install: function(Vue) {
// Do stuff
}
}
現(xiàn)在,我們可以使用前面的方法將庫添加到Prototype對象中:
axios.js
JavaScript
import axios from 'axios';
export default {
install: function(Vue,) {
Object.defineProperty(Vue.prototype, '$http', { value: axios });
}
}
這個use實例方法是將庫添加到項目中所需的全部內(nèi)容。例如,我們現(xiàn)在可以像這樣輕松地添加Axios庫:
entry.js
JavaScript
import AxiosPlugin from './axios.js';
Vue.use(AxiosPlugin);
new Vue({
created() {
console.log(this.$http ? 'Axios works!' : 'Uh oh..');
}
})
插件安裝方法可以采用可選參數(shù)。有些開發(fā)人員可能不喜歡調(diào)用他們的Axios實例方法。$http由于Vue Resource通常被命名為Vue Resource,所以讓我們使用一個可選的參數(shù)來允許他們將其更改為他們喜歡的任何東西:
axios.js
JavaScript
import axios from 'axios';
export default {
install: function(Vue, name='$http') {
Object.defineProperty(Vue.prototype, name, { value: axios });
}
}
entry.js
JavaScript
import AxiosPlugin from './axios.js';
Vue.use(AxiosPlugin, '$axios');
new Vue({
created() {
console.log(this.$axios ? 'Axios works!' : 'Uh oh..');
}
})
為感謝您對我們的認(rèn)可,特意準(zhǔn)備了一些IT入門和進階的干貨
包括:Java、UI設(shè)計、H5前端、Python+人工智能、軟件測試和新媒體運營六大學(xué)科視頻資料。以及IT就業(yè)大禮包。
線上視頻、音頻,隨時學(xué)習(xí)觀看
關(guān)注我們并私信“資料”即可獲取。
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。