前端開發(fā)3年了,竟然不知道什么是 Vue 腳手架?(上)
一、腳手架認識和使用前提
CLI 是什么意思?
CLI -- Command-Line Interface 命令行界面,俗稱腳手架。
腳手架就是一個大概的框架,是建筑學(xué)上的一個概念。
1.1、什么是Vue-cli?
Vue-cli 是官方發(fā)布 vue.js 項目腳手架,使用 Vue-cli 可以快速搭建 vue 開發(fā)環(huán)境,以及對應(yīng)的 webpack 配置。
1.2、使用腳手架的前提有哪些?
1、安裝 node.js,同時安裝 npm。
npm(Node Package Manager),是 Node.js 包管理和分發(fā)工具,已成為非官方的發(fā)布 Node 包標(biāo)準(zhǔn),現(xiàn)在經(jīng)常使用 npm 進行安裝一些開發(fā)過程中依賴包。
由于國內(nèi)使用 npm 官方鏡像非常慢,推薦使用淘寶鏡像,淘寶定制的 cnpm 代替 npm。使用
- npm install -g cnpm --registry = https://registry.npm.taobao.org
安裝完成之后就可以使用 cnpm 了。
cnpm 與 npm 使用命令是一樣的,只是在執(zhí)行命令時將 npm 改為 cnpm。
2、安裝 webpack
對所有的資源都會壓縮等優(yōu)化操作,在開發(fā)過程中,提供了一套完整的功能,能夠使開發(fā)效率更高。
使用命令進行安裝
- npm install webpack -g //全局安裝
- npm install webpack --save //當(dāng)前目錄安裝
3、安裝腳手架
- npm install @vue-cli -g //全局安裝
安裝完成之后,輸入 vue 回車,就能看到 vue 中的命令行,如圖:

官網(wǎng)文檔介紹 vue-cli 安裝時,可以使用的命令有兩種:

yarn 工具,類似 npm 的基本使用,在性能上比 npm 更好。相同意義命令可能不同。
二、Vue CLI 2.x 初始化項目
vue-cli 3 已經(jīng)發(fā)布一段時間了,現(xiàn)在安裝腳手架,都會安裝 Vue-cli 3.x 版本,如果我們想要使用 vue-cli 2.x 版本時,需要拉去 vue-cli 2.x 的模板,使用命令如下:
- npm intstall -g @vue/cli-init
此時,就可以開始使用 vue-cli 2 創(chuàng)建項目了。
1、創(chuàng)建項目文件夾 vue-cli 2
2、在文件夾內(nèi)打開 cmd 窗口,輸入命令:
- vue init webpack learn

此時已經(jīng)開始下載模板。
根據(jù)提示信息,輸入對應(yīng)的信息內(nèi)容,如圖:

vue 項目打包的時候,Runtime+compiler 與 Runtime-only 是有區(qū)別的,第一個解釋,該命令適用大多數(shù)用戶,所以我們先選擇第一個,后邊講解區(qū)別。
回車繼續(xù)創(chuàng)建項目:

提示是否使用 vue-router(路由)、Eslint(代碼規(guī)范化檢測工具),最后提示我們選擇使用什么命令進行項目管理,最后一個是手動處理,我們選擇大家熟悉的 npm 就好了。
現(xiàn)在等著項目創(chuàng)建完成之后,會提示我們進入項目,然后使用命令運行環(huán)境。

三、Vue-cli 2.x 項目結(jié)構(gòu)解析
首先從 配置文件 webpack.json 文件入手:尋找 scripts ,scripts 中存放的都是一些項目運行、打包、測試等腳本。代碼如下:
- "scripts": {
- "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
- "start": "npm run dev",
- "build": "node build/build.js"
- }
3.1、為什么使用 npm run dev 啟動服務(wù)?
webpack-dev-server 是啟動一個webpack本地服務(wù)。
--inline 運行本地命令
--progress 進度
--config build/webpack.dev.conf.js 配置執(zhí)行腳本入口文件
所以我們執(zhí)行 npm run dev 的時候,其實執(zhí)行的是:
- webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
啟動一個本地服務(wù)。啟動服務(wù)的時候,展示項目進度。如果把 --progress 去掉之后,啟動服務(wù)的時候就不會顯示進度了。
3.2、項目運行后,為啥端口號是8080
找到 config 文件夾內(nèi)的 index.js 文件,查找 dev中的配置項,就是專門為 npm run dev 執(zhí)行時的配置項。
- dev: {
- //編譯輸出的二級目錄
- assetsSubDirectory: 'static',
- //編譯發(fā)布的根目錄,可配置為資源服務(wù)器或cdn域名
- assetsPublicPath: '/',
- //使用 proxyTable代理的接口
- proxyTable: {},
- // 開發(fā)時候的訪問域名,可通過環(huán)境變量自己設(shè)置
- host: 'localhost',
- //開發(fā)時候的端口號,如果被占用會隨機分配
- port: 8080,
- //瀏覽器是否自動打開項目
- autoOpenBrowser: false,
- //是否使用eslint loader檢查代碼
- useEslint: true,
- //在瀏覽器展示錯誤蒙層
- errorOverlay: true,
- // 是否展示錯誤
- notifyOnErrors: true,
- poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
- devtool: 'cheap-module-eval-source-map',
- cacheBusting: true,
- cssSourceMap: true
- }
3.3、為何使用 npm run build 能夠自動打包項目?
npm run build 運行時,其實執(zhí)行的是: "node build/build.js"。
我們之前開發(fā)的網(wǎng)頁,執(zhí)行 js 文件的時候,必須引入 某個 html 文件內(nèi),瀏覽器訪問 html 文件,渲染的時候才會執(zhí)行js文件。
在node中:node 為 js 執(zhí)行提供了環(huán)境,node 是 C++ 開發(fā)的 V8引擎,可以直接把 js 文件運行成二進制代碼,所以運行起來很快。node 中執(zhí)行 js 的時候,直接使用:node xx.js 文件就可以運行了。
所以打包項目的時候,執(zhí)行的是 build 文件夾內(nèi)的 build.js 文件。
四、項目其他文件介紹
整體的項目目錄結(jié)構(gòu)很簡單,如圖所示:

- build - 存放執(zhí)行腳本入口
- config - 文件夾內(nèi)的 index.js ,更多的dev、build配置
- node_moudles - 存放依賴包資源
- src - 存放開發(fā)資源
- static - 存放靜態(tài)資源
- .babelrc - 對 ES6轉(zhuǎn)ES5的限制
- editorconfig - 編輯器配置
- .gitignore - 提交 git 時忽略內(nèi)容
- index.html - 單頁面應(yīng)用的主入口
- package-lock.json - 記錄依賴包的真實版本
- README.md - 使用文檔
五、Runtime+compiler 與 Runtime-only 區(qū)別
我們再新建一個 runtime-only 的項目,發(fā)現(xiàn)兩個項目只有 main.js 中有區(qū)別。兩個 main.js 對比如下圖:

要問 template 與 render 的區(qū)別,這就需要了解 vue 程序的運行過程:
- template 經(jīng)過解析(parse) 成 語法抽象樹(abstract system tree)
- 再通過 render 函數(shù)進行渲染操作虛擬 DOM (Virtual dom)
- 然后虛擬 DOM 操作全部完成之后生成真實 DOM
通過 vue 運行過程,我們不難發(fā)現(xiàn),使用 template 時,多了第一步操作,使用 render 時直接進行第二步。
Runtime+compiler 與 Runtime-only 相比,runtime-only 性能更高,寫的代碼量更少。命令行中已經(jīng)提示我們,能夠壓縮 6kb 的代碼。
render 到底是什么呢?
render 函數(shù)實質(zhì)就是生成 template 模板,通過調(diào)用一個方法生成,而這個方法又是通過 render 的參數(shù)來傳遞的。
用法1:普通用法
傳遞的 createrElement 方法有三個參數(shù),分別提供:標(biāo)簽名、標(biāo)簽屬性、標(biāo)簽內(nèi)容
- render:function(createElement){
- return createElement('h2',{class:'box'},['內(nèi)容'])
- }
通過上述方法,就可以生成一個完整的模板。
用法2:組件用法
傳入的是一個組件對象
- import App from './App'
- render:function(createElement){
- return createElement(App)
- }
我們實際 main.js 中,其實是對上邊的簡寫,改寫成箭頭函數(shù)。
- render: h => h(App)