前端開發中提到的「腳手架」是一個形象的比喻,比喻各種語言的前期工做環境。javascript
在軟件開發中(包括前端開發)的腳手架指的是:有人幫你把開發過程當中要用到的工具、環境都配置好了,讓程序員能夠方便地直接開始作開發,專一於業務,而不用再花時間去配置這個開發環境,這個開發環境就是腳手架。css
好比vue.js就有個vue-cli腳手架,基於node.js的開發環境,做者將開發環境大部分東西都配置好,將腳手架下載下來就能夠直接開發了,不用再考慮搭建這些工具環境。html
vue-cli 是一個官方發佈 vue.js 項目腳手架,爲單頁面應用(SPA)快速搭建繁雜的腳手架。VueCLI官方地址前端
GitHub地址是:https://github.com/vuejs/vue-clivue
Vue CLI 致力於將 Vue 生態中的工具基礎標準化。它確保了各類構建工具可以基於智能的默認配置便可平穩銜接,這樣你能夠專一在撰寫應用上,而沒必要花好幾天去糾結配置的問題。與此同時,它也爲每一個工具提供了調整配置的靈活性,無需 eject。java
Vue CLI由幾個獨立的部分組成。在github倉庫中同時管理了多個單獨發佈的包。node
CLI (@vue/cli
) 是一個全局安裝的 npm 包,提供了終端裏的 vue
命令。python
經過 vue create
快速建立一個新項目的腳手架,或者直接經過 vue serve
構建新想法的原型。也能夠經過 vue ui
經過一套圖形化界面管理你的全部項目。webpack
CLI 服務 (@vue/cli-service
) 是一個開發環境依賴。它是一個 npm 包,局部安裝在每一個 @vue/cli
建立的項目中。git
CLI服務構建於 webpack 和 webpack-dev-server 之上。包含以下功能:
CLI 插件是向你的 Vue 項目提供可選功能的 npm 包,例如 Babel/TypeScript 轉譯、ESLint 集成、單元測試和 end-to-end 測試等。Vue CLI 插件的名字以 @vue/cli-plugin-
(內建插件) 或 vue-cli-plugin-
(社區插件) 開頭,很是容易使用。
當你在項目內部運行 vue-cli-service
命令時,它會自動解析並加載 package.json
中列出的全部 CLI 插件。
vue-cli 是一個官方發佈 vue.js 項目腳手架,爲單頁面應用(SPA)快速搭建繁雜的腳手架。VueCLI官方地址
它爲現代前端工做流提供了 batteries-include 的構建設置。 使用 vue-cli 能夠快速建立 vue 項目。只須要幾分鐘時間就能夠運行起來並帶有熱重載、保存時 lint 校驗,以及生產環境可用的構建版本。
GitHub地址是:https://github.com/vuejs/vue-cli
首先須要安裝Node環境,詳見:
安裝完成以後,能夠在命令行工具中輸入node -v 和 npm -v,若是能顯示出版本號,就說明安裝成功。
MacBook-Pro:~ hqs$ node -v v6.10.3 MacBook-Pro:~ hqs$ npm -v 3.10.10
安裝好node以後,咱們就能夠直接全局安裝vue-cli:
MacBook-Pro:~ hqs$ npm install -g vue-cli
npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
/usr/local/bin/vue-init -> /usr/local/lib/node_modules/vue-cli/bin/vue-init
/usr/local/bin/vue -> /usr/local/lib/node_modules/vue-cli/bin/vue
/usr/local/bin/vue-list -> /usr/local/lib/node_modules/vue-cli/bin/vue-list
/usr/local/lib
`-- vue-cli@2.9.6
+-- async@2.6.1
| `-- lodash@4.17.11
+-- chalk@2.4.1
| +-- ansi-styles@3.2.1
| | `-- color-convert@1.9.3
| | `-- color-name@1.1.3
使用這種方式可能會安裝比較慢,推薦你們使用國內的淘寶鏡像來安裝。
cnpm install -g vue-cli
若是安裝失敗,可使用 npm cache clean 清理緩存,而後再從新安裝。後面的安裝過程當中,若有安裝失敗的狀況,也須要先清理緩存。
安裝完成後,可使用vue -V(大寫的V)查看vue的版本,來驗證vue-cli是否安裝成功。
MacBook-Pro:~ hqs$ vue -V 2.9.6
# 首先卸載已經全局安裝了舊版本的 vue-cli (1.x或2.x): npm uninstall vue-cli -g # 安裝 3.x 版本的 vue-cli 腳手架: npm install -g @vue/cli # 安裝 2.x 版本的 vue-cli 腳手架: npm install -g @vue/cli-init
此時電腦上經過終端就可使用2.x版本和3.x版本的腳手架工具了。
在全局安裝好vue-cli後,就能夠在命令行中訪問 vue 命令。
MacBook-Pro:~ hqs$ vue -help Usage: vue <command> [options] Options: -V, --version output the version number -h, --help output usage information Commands: init generate a new project from a template list list available official templates build prototype a new project create (for v3 warning only) help [cmd] display help for [cmd]
MacBook-Pro:~ hqs$ vue list Available official templates: ★ browserify - A full-featured Browserify + vueify setup with hot-reload, linting & unit testing. ★ browserify-simple - A simple Browserify + vueify setup for quick prototyping. ★ pwa - PWA template for vue-cli based on the webpack template ★ simple - The simplest possible Vue setup in a single HTML file ★ webpack - A full-featured Webpack + vue-loader setup with hot reload, linting, testing & css extraction. ★ webpack-simple - A simple Webpack + vue-loader setup for quick prototyping.
Vue.js官方提供了兩種類型的模板項目:
vue cli是Vue.js官方提供的命令行建立Vue.js項目腳手架的工具。這兩種類型的項目模板分別提供了簡單模式和徹底模式。
簡單模式僅包含基於vue.js開發必要的一些資源和包,能夠快速地投入到開發。徹底模式則還包括ESLink、單元測試等功能。
由於webpack比較厲害,在這裏使用webpack的項目模板。
首先必定要先使用命令行工具切換到項目當前的目錄下。
MacBook-Pro:vue_webpack_test hqs$ pwd /Users/hqs/PycharmProjects/vue_webpack_test
MacBook-Pro:vue_webpack_test hqs$ vue init webpack-simple my-project
? Project name my-project
? Project description A Vue.js project
? Author hhh
? License MIT
? Use sass? No
vue-cli · Generated "my-project".
To get started:
cd my-project
npm install
npm run dev
MacBook-Pro:vue_webpack_test hqs$ cd my-project/ MacBook-Pro:my-project hqs$ ls README.md package.json webpack.config.js index.html src MacBook-Pro:my-project hqs$ pwd /Users/hqs/PycharmProjects/vue_webpack_test/my-project
MacBook-Pro:my-project hqs$ npm install
MacBook-Pro:my-project hqs$ npm run dev > my-project@1.0.0 dev /Users/hqs/PycharmProjects/vue_webpack_test/my-project > cross-env NODE_ENV=development webpack-dev-server --open --hot Project is running at http://localhost:8080/ webpack output is served from /dist/ 404s will fallback to /index.html
項目啓動後,自動彈出以下頁面,如此證實項目啓動成功了。
App.vue是入口組件,可是在入口組件中會有多個a標籤,每一個a標籤渲染對應的一個子組件並放在對應的文件夾(src/components)下。
在components/Home/目錄下建立Home.vue組件。
<template> <div class="home"> 我是首頁 </div> </template> <script> export default { name: "Home", data(){ return{ }; }, }; </script> <style scoped> </style>
<template> <!-- 組件的頁面結構 --> <div id="app"> <h3>{{msg}}</h3> <div v-html="title"></div> <ul> <!-- key綁定key的時候,若是數據中有id就綁定id,沒有id綁定index --> <li v-for="(item, index) in datas" :key="index">{{item}}</li> </ul> <!-- 引入首頁 --> <Home/> </div> </template> <script> // 導入 import Home from './components/Home/Home.vue' // 組件內部的業務邏輯 export default { name: 'app', data () { return { msg: '來開始學習vue-cli腳手架項目', title: "<h3>皇家騎士</h3>", datas: [ '抽菸','喝酒','燙頭','泡妞' ] } }, components:{ Home // 掛載home組件 } } </script>
在通訊中,不管是子組件向父組件傳值仍是父組件向子組件傳值,他們都有一個共同點就是有中間介質,子向父的介質是自定義事件,父向子的介質是props中的屬性。
將父組件的內容傳遞到子組件:
將要傳遞給子組件的值進行v-bind動態綁定。
<template> <!-- 組件的頁面結構 --> <div id="app"> <h3>{{msg}}</h3> <div v-html="title"></div> <ul> <!-- key綁定key的時候,若是數據中有id就綁定id,沒有id綁定index --> <li v-for="(item, index) in datas" :key="index">{{item}}</li> </ul> <!-- 引入首頁, --> <Home :text="text" /> </div> </template> <script> // 導入 import Home from './components/Home/Home.vue' // 組件內部的業務邏輯 export default { name: 'app', data () { return { msg: '來開始學習vue-cli腳手架項目', title: "<h3>皇家騎士</h3>", datas: [ '抽菸','喝酒','燙頭','泡妞' ], text: "我是父組件的內容" } }, components:{ Home // 掛載home組件 } } </script>
子組件在props中建立一個屬性,接收父組件傳遞的值。
<template> <div class="home"> 我是首頁===={{text}} </div> </template> <script> export default { name: "Home", data(){ return{ }; }, props:['text'] }; </script>
子組件向父組件傳值:
Home.vue內容以下所示:
<template> <div class="home"> 我是首頁===={{text}} <button @click="addHandler">觸發</button> </div> </template> <script> export default { name: "Home", methods:{ addHandler(){ this.$emit('add', '哈哈哈') } }, data(){ return{ }; }, props:['text'] }; </script>
在點擊事件的函數中使用$emit來觸發一個自定義事件,並傳遞一個參數,這裏傳遞的是:「哈哈哈」。
App.vue內容以下所示:
<template> <!-- 組件的頁面結構 --> <div id="app"> <h3>{{msg}}</h3> <div v-html="title"></div> <ul> <!-- key綁定key的時候,若是數據中有id就綁定id,沒有id綁定index --> <li v-for="(item, index) in datas" :key="index">{{item}}</li> </ul> <!-- 引入首頁, --> <Home :text="text" @add="addHandler"/> </div> </template> <script> // 導入 import Home from './components/Home/Home.vue' // 組件內部的業務邏輯 export default { name: 'app', data () { return { msg: '來開始學習vue-cli腳手架項目', title: "<h3>皇家騎士</h3>", datas: [ '抽菸','喝酒','燙頭','泡妞' ], text: "我是父組件的內容" } }, components:{ Home // 掛載home組件 }, methods:{ addHandler(data){ console.log(data); } } } </script>
除了監聽該自定義事件外,還添加了一個響應該事件的處理方法。
build 文件夾:用於存放 webpack 相關配置和腳本。開發中僅 偶爾使用 到此文件夾下 webpack.base.conf.js 用於配置 less、sass等css預編譯庫,或者配置一下 UI 庫。
config 文件夾:主要存放配置文件,用於區分開發環境、線上環境的不一樣。 經常使用到此文件夾下 config.js 配置開發環境的 端口號、是否開啓熱加載 或者 設置生產環境的靜態資源相對路徑、是否開啓gzip壓縮、npm run build 命令打包生成靜態資源的名稱和路徑等。
dist 文件夾:默認 npm run build 命令打包生成的靜態資源文件,用於生產部署。
node_modules文件夾:存放npm命令下載的開發環境和生成環境資源包。
src文件夾:存放項目源碼及須要引用的資源文件。
src/assets文件夾:存放項目中須要使用的靜態資源文件。
src/componnents文件夾:存放vue開發的公共組件。
src/router文件夾:vue-router vue路由的配置文件。
src/App.vue文件:使用標籤<route-view></router-view>渲染整個工程的.vue組件。
src/main.js文件:vue-cli工程的入口文件。
index.html文件:項目的承載文件(首頁文件)。
package.json文件:node_modules資源部署、啓動、打包項目的npm命令管理。
.DS_Store node_modules/ dist/ npm-debug.log yarn-error.log # Editor directories and files .idea *.suo *.ntvs* *.njsproj *.sln
編寫代碼tab默認縮進爲2個空格,indent_size = 4就是tab縮進的大小,默認是2,將其修改成4。
root = true [*] charset = utf-8 indent_style = space indent_size = 4 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true
在終端中執行 npm run dev,會找到package.json中的scripts配置裏的"dev"關鍵字對應的內容。
package.json文件中,dependencies是當前項目必須依賴的模塊;而devDependencies是經過腳手架搭建後必須依賴的包,開發環境依賴。
須要注意的是json文件是不能用//或者/**/來添加註釋的。
{
"name": "my-project",
"description": "A Vue.js project",
"version": "1.0.0",
"author": "hhh",
"license": "MIT",
"private": true,
"scripts": {
// npm run dev
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
// webpack打包用的東西
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": { // 項目依賴
"vue": "^2.5.11"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": { // 開發依賴
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1"
}
}
找到dev命令下的webpack-dev-server工具後,默認打開配置文件webpack.config.js。
webpack.config.js
是webpack默認的配置文件名,webpack默認會去尋找根目錄下的webpack.config.js文件。若是要指定webpack取讀取配置文件,只需添加 --config 參數指定便可。
module.exports = { entry: './src/main.js', // 進入入口 output: { // 輸出入口 path: path.resolve(__dirname, './dist'), publicPath: '/dist/', filename: 'build.js' }, module: { // loader rules: [ { test: /\.css$/, use: [ 'vue-style-loader', // 讓組件支持樣式加載 'css-loader' // css支持 ], }, { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { } // other vue-loader options go here } }, { test: /\.js$/, loader: 'babel-loader', // 支持ES6語法 exclude: /node_modules/ }, { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', // png、jpg等文件支持打包 options: { name: '[name].[ext]?[hash]' } } ] }, resolve: { alias: { // 爲vue/dist/vue.esm.js起別名:vue$ 'vue$': 'vue/dist/vue.esm.js' }, extensions: ['*', '.js', '.vue', '.json'] // 文件後綴名爲js/vue/json的,能夠省略不寫 }, devServer: { historyApiFallback: true, noInfo: true, overlay: true }, performance: { hints: false }, devtool: '#eval-source-map' }
由配置文件中 entry 配置找到項目入口文件 src 目錄下的 main.js 文件。
main.js是整個項目的入口啓動文件。
注意導入npm下載的模塊和導入本身編寫模塊的方式是不同的。不一樣之處在於:npm下載的 from 後面不加路徑直接寫名稱;本身編寫的組件,from 後面須要使用相對路徑引入。
import Vue from 'vue' // 引入vue的文件,這是npm下載的文件。from 後面的字符不要加路徑 import App from './App' // 引入自定義的組件 new Vue({ el: '#app', // DOM直接渲染 // appendChild() render: h=>h(App) })
render: h->h(App):這是es 6 的語法,是以下內容的縮寫:
render: function (createElement) { return createElement(App); }
表示Vue 實例選項對象的 render 方法做爲一個函數,接受傳入的參數h 函數,返回h(App)的函數調用結果。而後Vue在建立 Vue 實例時,經過調用 render 方法來渲染實例的 DOM 樹。最後在調用render方法時,傳入一個createElement函數做爲參數。
createElement 函數的做用就是生成一個 VNode節點,render 函數獲得這個 VNode 節點以後,返回給 Vue.js 的 mount 函數,渲染成真實 DOM 節點,並掛載到根節點上
App.vue是項目的主組件,全部頁面都在App.vue下進行切換
<template> <div id="app"> <img src="./assets/logo.png"> <h1>{{ msg }}</h1> <h2>Essential Links</h2> <ul> <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li> <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li> <li><a href="https://chat.vuejs.org" target="_blank">Community Chat</a></li> <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li> </ul> <h2>Ecosystem</h2> <ul> <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li> <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li> <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li> <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li> </ul> </div> </template> <script> export default { name: 'app', data () { return { msg: 'Welcome to Your Vue.js App' } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } h1, h2 { font-weight: normal; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } </style>
在webpack-simple模板中,包括webpck模板。一個.vue文件就是一個組件。
爲何會這樣呢?由於webpack幹活了!webpack的將咱們全部的資源文件進行打包。同時webpack還能將咱們的html(template)、css、js文件經過模板編譯的方式將這些文件打包成一個.vue的文件。
App.vue代碼 有三部分,template標籤中就是咱們要寫的組件結構,script標籤中就是咱們要寫的業務邏輯,style標籤中就是咱們要寫的該組件的樣式。這三部分,咱們經過vue-loader這個插件,將這三部分共同組合成了一個.vue文件。咱們稱這種.vue的文件就是一個組件。
另外上面的代碼,咱們發現有個export default語法,其實呢,這個東西,跟咱們的python模塊化有點相似。在es6 Module中,webpack這個工具經過babel-loader這個loader將咱們的es6 Module語法進行解析,從而讓咱們的export default語法和import 'xxx'語法在瀏覽器中識別。
總結:export default xxx 就是拋出一個模塊(一個js文件就是一個模塊), import 'xxx' from 'aaa'就是從剛剛拋出的文件路徑中,導入此模塊。有import就必定有export default.
<template>
<!--頁面的結構-->
<div class=""></div>
</template>
<script>
// 頁面的業務邏輯,注意這裏並非js,不要添加type='javascript'
</script>
<style>
/*該組件的樣式屬性*/
</style>
export default xxx 就是拋出一個模塊(一個js文件就是一個模塊),import App from './App.vue' 就是從剛剛拋出的文件路徑中,導入此模塊。有import就必定有export default.
由於在main.js中有:
import App from './App.vue'
因此,咱們必須在當前組件中寫入export default,那麼後面的書寫就是用到了我們以前的學習的語法。
<template> <!--頁面的結構--> <div class="app"> <h3>{{msg}}</h3> </div> </template> <script> // 頁面的業務邏輯,注意這裏並非js,不要添加type='javascript' export default { // 拋出來一個對象 name: 'App', // 代指組件名字 data(){ // 數據屬性 return { // 必須是一個函數,要有返回值,返回空對象也是有返回值 msg:'hello 組件' } } } </script> <style> /*該組件的樣式屬性*/ </style>
MacBook-Pro:my-project hqs$ npm run dev > my-project@1.0.0 dev /Users/hqs/PycharmProjects/vue_webpack_test/my-project > cross-env NODE_ENV=development webpack-dev-server --open --hot Project is running at http://localhost:8080/
頁面效果顯示以下:
那麼接下來咱們就能夠在App.vue組件中將咱們以前學習到的知識運用進來。
首先建立/src/components文件夾。再建立頁首、頁中、頁腳三個組件:
編輯各組件代碼:
############Vheader.vue########### <template> <header class="nav"> 我是header </header> </template> <script> export default { name: "vheader", data(){ return { } } } </script> <style scoped> </style> ############Vcontent.vue########### <template> <div class="wrap"> 我是中心內容 </div> </template> <script> export default { name: "vcontent", data(){ return { } } } </script> <style scoped> </style> ############Vfooter.vue########### <template> <footer class="foot"> 我是footer </footer> </template> <script> export default { name: "vfooter", data(){ return { } } } </script> <style scoped> </style>
<template> <!--頁面的結構--> <div class="app"> <h3>{{msg}}</h3> <p>嘿嘿</p> <Vheader></Vheader> <Vcontent></Vcontent> <Vfooter></Vfooter> </div> </template> <script> // 在父組件中引入子組件 import Vheader from './components/Vheader.vue' import Vcontent from './components/Vcontent' import Vfooter from './components/Vfooter' // 頁面的業務邏輯,注意這裏並非js,不要添加type='javascript' export default { // 拋出來一個對象 name: 'App', // 代指組件名字 data() { // 數據屬性 return { //必須是一個函數,要有返回值,返回空對象也是有返回值 msg: 'hello 組件' } }, components:{ // 掛載組件 // Vheader:Vheader Vheader, Vcontent, Vfooter } } </script> <style scoped> /*該組件的樣式屬性*/ </style>
寫每一個組件style都要加 scoped ,當前的樣式屬性僅對當前的標籤結構起做用,與其餘組件無關。對樣式完成解耦。