vue的三個特點:
Ø Mvvm
Ø 元件化
Ø 子產品化
子產品化是指檔案的組織,管理,使用的方式 。
代碼的開發階段:把一個大的檔案,拆分成幾個小檔案,它們之間互相引用,依賴。
代碼釋出之後:把這些小檔案打包成一個大檔案webpack。
1.1. 為什麼要用子產品化開發
以下面代碼為例:
這個index.html檔案中一共引入了8個 js檔案。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX5FEVPhXVq1UeRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TN4IjM0UjMzITNyUDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
這樣組織至少會有兩個問題:
(1)全局變量污染
(2)檔案之間互相依賴的問題:Balloon.js檔案必須要依賴于myjquery.js(這是我們自己寫一個庫),因為balloon.js中産生随機數所用的函數GetR來自于myjquery.js的。
解決:
(1)全局變量污染的問題,我們可以通過立即執行的函數表達式來解決。
(2)我們之前組織代碼的方式,就不能很友善地看出來,哪個檔案依賴于哪個檔案。就算我們事先知道A.js依賴于B.js(可能A.js中用了B.js中的方法),我們也沒有辦法在浏覽器端保證:B.js會在A.js之前加載完成。
1.2. 子產品化的發展
子產品化的思想主要是從後端的程式中引入的。
php -- include ”header.php”
1.2.1. 了解css中的子產品化
Css -- @import
在es6之前,它不支援在一個js中直接去引入另一個js檔案。
Ø 原始方式 --- 無子產品時代
Ø 萌芽時代 --- 閉包+自執行函數、命名空間、人肉方式、配置參數
Ø CommonJS規範 --- CommonJs社群制定了Modules/1.0規範
Ø AMD規範 --- 革新派,RequireJS
Ø CMD規範 --- 中間派,seajs
Ø es6子產品化 --- 終極解決方案
1.3. 閉包+立即執行函數的方式
它隻是解決了檔案之間的互相依賴關系的描述:
你一看到這個iife就可以知道,目前的這個子產品(js檔案)是依賴于哪些子產品(js檔案)的。
zepto就是這樣做的
1.4. CommonJS規範
CommonJS規範源于Modules/1.0,在node.js中率先實作了。
核心内容有如下幾點:
Ø 使用require方法引入其他子產品(js檔案),執行的結果即為别的子產品(js檔案)暴漏出來的API。
Ø 子產品通過變量module.exports導出API,exports隻能是一個對象,暴漏的API須作為此對象的屬性。
Ø 如果require函數引入的子產品中也包含依賴,則依次加載這些依賴。
Ø 如果引入子產品失敗,那麼require函數應該報一個異常。
1.4.1. 定義子產品
1.4.1.1. 格式
module.exports={
鍵值對
}
1.4.2. 引入子產品
Let obj = require(“子產品名’)
require函數,會傳回一個對象,傳回的是在子產品中使用module.exports導出的對象
1.4.2.1. 引入子產品的格式
子產品名的路徑,有兩種:
Ø 自定義子產品:使用相對路徑,以./或../開頭 子產品名後可以加.js,也可以不加;你不能直接寫子產品名,就算是兩個檔案在同一個目錄下,也加./
Ø 第三方子產品:隻需要寫上子產品名即可。這裡的第三方子產品,其實就是使用npm來安裝的那些子產品。
例如,你安裝了vue子產品。則在node_modules下會多一個檔案夾:
你要想使用vue子產品,隻需要:
1.4.3. 示例
1.4.3.1. 浏覽器端 不支援
現在有一個簡單的需求,有三個檔案如下:
Ø Index.html:它引入index.js檔案
Ø Index.js:它執行一些功能,但它要入unit.js
Ø Unit.js:它就是一個庫,提供一些方法
如果你現在去打開index.html檔案,則浏覽器一定會報錯:
因為commonjs規則在浏覽器端不支援。
但,在node.js中是支援commonjs規則的,即,上面的index.js檔案可以直接通過node去運作。
1.4.3.2. 在nodejs中是支援的
1.4.4. 用browserify工具,把代碼編譯打包一下,讓浏覽器也能用
先通過npm安裝。
(1)建議先在根目錄,建立好package.json檔案。
(2)全局安裝和本地安裝都可以。
npm install browserify -g (在任何一個小黑窗下都可以使用browserify指令)
或者是
npm install browserify --save (隻能在目前的目錄下使用這個指令)
(3)運作browserify 指令去轉碼
格式:
Browserify 要轉碼的.js -o 轉碼之後的.js
示例:
這裡的blunder.js會自動建立的。
如下:
(4)在html中引入這個blunder.js即可。(之前引的是index.js,它不能用)
效果如下:
1.4.5. 應用:對前面的打氣球遊戲的js代碼進行子產品化處理
1.4.5.1. 把之前的立即執行的函數表達式的寫法,改成commonjs的定義子產品
改成:
把
改成:
其它的js檔案的寫法都類似。
對game.js
1.4.5.2. 用browserify對game.js進行轉碼
在html中引入轉碼之後的檔案即可。
commonjs主要是在伺服器端使用,在浏覽器端雖然可以用browserify進行轉碼,但,并沒有展現出浏覽器與伺服器端的差別:
浏覽器端的代碼是異步的,而伺服器端是同步的。在浏覽器端,提出 amd規範。
1.5. amd 規範 require.js
Asynchronous Module Definition
"異步子產品定義"。它采用異步方式加載子產品,子產品的加載不影響它後面語句的運作。所有依賴這個子產品的語句,都定義在一個回調函數中,等到加載完成之後,這個回調函數才會運作。
amd是一種規範。require.js實作了這種規範。
1.5.1. 代表産品:require.js
1.5.2. Require.js的使用
1.定義子產品
2.在主檔案中引用子產品
3.html中引入require.js
1.5.2.1. requirejs 定義子產品(不是入口檔案)
define(['子產品1',’'子產品2'’],function(變量1,變量2){
return {
}
});
(1)這裡的變量就是這個子產品的别名。
(2)如果目前子產品不依賴其它的子產品,則不需要寫第一個參數,第二個參數中的形參清單也不要。
(3)這裡也是使用子產品。
示例:
1.5.2.2. requirejs 定義入口檔案
require([“子產品1”,“子產品2”],function(變量1,變量2){
//你的代碼
});
示例
Index.js需要使用unit.js這個子產品
1.5.2.3. 在html頁面中引入requirejs并指定入口檔案
<script src="js/require.js" data-main="js/main" ></script>
(1)data-main是指定的主入口的名字。類似于c語言中的main函數一樣。
(2)可以省略.js字尾。
效果如下:
1.5.3. 應用 :用require.js去改寫對前面的打氣球遊戲的js代碼
部分代碼如下:
1.6. cmd規範 sea.js
“Common Module Definition”的縮寫,意思就是"通用子產品定義"。
cmd是一種子產品化規範。
CMD推崇依賴就近,延遲執行
sea.js是推動cmd規範的産物。
1.6.1. 代表産品sea.js
1.6.1.1. seajs 定義子產品--不需要引用其它子產品
define(function(require,exports,module){
//你的代碼,函數,變量,對象
//導出子產品有三種方式
exports.屬性名=值。//方式一
module.exports.屬性名=值。//方法二
return 對象//方法三
});
(1)define是seajs定義的全局函數
1.6.1.2. seajs 定義子產品--需要引用其它子產品
define(function(require,exports,module){
//你的代碼,函數,變量,對象
Var obj = require(‘子產品名’)
//導出模闆有三種方式
exports.屬性名=值。//方式一
module.exports.屬性名=值。//方法二
return 對象//方法三
});
1.6.1.3. 主入口
<script >
seajs.use(["子產品1",“子產品2”],function(變量1,變量2){
});
1.6.1.4. html頁面中引入sea.js,和入口檔案
1.6.2. 應用 :用sea.js去改寫對前面的打氣球遊戲的js代碼
注意一下:sea.js檔案最好是和你的子產品放在同一級目錄下。
1.7. 檢視jquery的代碼
1.8. es6子產品化
Import:導入。在自己目前的子產品去使用其它子產品
Export:導出。在定義子產品時,決定把哪些内容暴露出去:當别的子產品去引入目前子產品,别人會得到什麼東西。
1.8.1. 示例
Ø Index.html:引入index.js
Ø Index.js:要去引用unit.js
Ø Unit.js
現在,直接打開浏覽器去通路index.html會得到一個錯誤:
由于import是es6的文法。在浏覽器中不支援的,但我們可以通過babel進行轉碼。
下面,就要開始去轉下碼。
1.8.1.1. babel轉碼
Ø 安裝bable
npm install babel-cli -g
Ø 安裝兩個包
npm install babel-preset-es2015 babel-preset-stage-2 --save-dev
Ø 編寫配置檔案
.babelrc
{
"presets":["es2015","stage-2"]
}
運作轉碼指令:
現在我們的檔案如下::
細節:
在index.es5.js中,我們引入的檔案應該要從unit.js改成unit.es5.js
在index.html中,把index.js 改成 index.es5.js。結果還是報錯:require不認識。
我們通過babel從es6 --> es5之後:
實際是es6規範 ---> common規範
Es6 | Es5 |
| |
| |
Es6規範 | commonjs規範 |
commonjs規範:它還是不能在浏覽器工作。但它可以直接在nodejs中運作。
子產品化開發詳細介紹及詳細用法2. 子產品化總結
為了讓代碼能夠在浏覽器中運作,我們還需要對index.es5.js檔案進行browserify處理。
1.8.1.2. browserify處理
對入口檔案(這個它引用其它的子產品)進行處理:
browserify會分析index.es5.js檔案,找出這個檔案中依賴了哪些其它的檔案,把它的依賴檔案全部裝到一個檔案中:bundle.js。
修改index.html檔案,把bundle.js引入:
成功啦!!!
1.8.2. Export
你在定義子產品時,你可以決定,當你的模闆被其它模闆引入時,你暴露出去的内容是什麼。
1.8.2.1. 逐個導出
1.8.2.2. 批量導出
1.8.2.3. 别名導出
1.8.3. Import
格式:
Import {變量名1,變量名2.... } from “子產品名”
1.8.3.1. 逐個導出和批理導出
對于上面unit子產品,它的兩種導出方式,我們都可以用如下的方式進行導入:
(1)導入時,你使用的變量名data,name必須要與unit子產品中導出時用的名字要一緻。
(2)兩個變量之間先後順序是沒有的關系的(對象是屬性的無序集合)
(3)上面的子產品的路徑的寫法(”./unit”)與commonjs中的require的要求是一樣的:
Ø 如果自己定義的子產品,則一定要加 ./(表示目前目錄) ../(上一級目錄)
Ø 如果是第三方的子產品,則直接寫子產品名。
如上代碼說明,vue這個子產品是預設導出的。
1.8.3.2. 别名導入
在導入資料時,取個别名。
1.8.4. Export default
在導出和導入我們需要保持屬性名是一緻,這就比較麻煩。
我們通過通過exprot default來把取名的工作交給引用子產品:即我導出時,不取名字,你導入時,愛取什麼名字就取什麼名字。
1.8.4.1. 定義子產品
1.8.4.2. 引入子產品
1.8.4.3. Export default和批量導出可以一起用
導出子產品
導入子產品
1.8.5. 子產品的整體加載
Import * as
子產品還是正常地批量導出:
導入時
2. 子產品化總結
子產品化
Ø 一個js檔案就是一個子產品;
Ø 把很多個子產品通過互相引用的方式組合在一起 ;
Ø 在index.html中,隻引入一個子產品
有四種規範
Ø Commonjs:在nodejs中支援的。在伺服器端工作。
Ø Amd:在浏覽器端工作 。代表産品是:require.js
Ø Cmd:在浏覽器端工作 。代表産品是:sea.js
Ø ES6 :正宗。完全可以建構 伺服器端 和浏覽器 都支援的 方案。
方案名 | 定義子產品 | 使用子產品 | 主入口 | |
commonjs | modules.exports={} | require() obj =require(‘./子產品名’) | browserify轉碼 | |
amd-seajs | defind(require,export,module) | defined(require,export,module){ require (./子產品名)} | seajs.use([],functin(){ }) | sea.js |
cmd-require | define(function(){return {} }); | define(['子產品'],function(變量){return {} }); | require(["game"],function(g){}) data-main | common.js |
es6 | export | import | babel browserify |