ECMAscript
標準規範。JavaScript和JScript都是ECMAScript
的標準實現者,隨後各大瀏覽器廠商紛紛實現了ECMAScript
標準。因此,ECMAScript是瀏覽器腳本語言的規範,而各類咱們熟知的js語言,如JavaScript則是規範的具體實現。javascript
以前,js定義變量只有一個關鍵字:var。var有一個問題,就是定義的變量有時會成爲全局變量:css
for(var i = 0; i < 5; i++){ console.log(i); } console.log("循環外:" + i)//5
let所聲明的變量,只在let命令所在的代碼塊內有效。html
for(let i = 0; i < 5; i++){ console.log(i); } console.log("循環外:" + i)//not defined
const聲明常量,不能修改。前端
var print = function (obj) { console.log(obj); } // 簡寫爲: var print2 = obj => console.log(obj);
參數=>{方法體}vue
好比定義一個js文件:hello.js,裏面有一個對象:java
const util = { sum(a,b){ return a + b; } }
使用export將這個對象導出:node
const util = { sum(a,b){ return a + b; } } export util;
使用export命令定義了模塊的對外接口之後,其餘 JS 文件就能夠經過import命令加載這個模塊。webpack
// 導入util import util from 'hello.js' // 調用util中的屬性 util.sum(1,2)
在MVVM以前,開發人員從後端獲取須要的數據模型,而後要經過DOM操做Model渲染到View中。然後當用戶操做視圖,咱們還須要經過DOM獲取View中的數據,而後同步到Model中。git
而MVVM中的VM要作的事情就是把DOM操做徹底封裝起來,開發人員不用再關心Model和View之間是如何互相影響的。es6
vue就是一款MVVM模式的框架。
Vue是一個漸進式javascript框架,既能夠只做爲一個js庫來使用,若是想將更多的業務邏輯放到前端來實現,它也有vue-router vuex等等核心庫來幫你實現。
NPM是Node提供的模塊管理工具,能夠很是方便的下載安裝不少前端框架,包括Jquery、AngularJS、VueJs都有。,咱們先安裝node及NPM工具。
下載地址:https://nodejs.org/en/download/
完成之後,在控制檯輸入:node –v
安裝完成Node應該自帶了NPM了,在控制檯輸入npm -v查看:
npm默認的倉庫地址是在國外網站,速度較慢,建議設置到淘寶鏡像。可是切換鏡像是比較麻煩的。推薦一款切換鏡像的工具:nrm
首先安裝nrm,這裏-g
表明全局安裝:
npm install nrm –g
而後經過nrm ls命令查看npm的倉庫列表,帶*的就是當前選中的鏡像倉庫:
經過nrm use taobao來指定要使用的鏡像源。
而後經過nrm test taobao來測試速度:
安裝完成請必定要重啓下電腦。
三種方式:
1)下載地址:https://github.com/vuejs/vue 下載解壓,獲得vue.js文件。
2)使用cdn
<!-- 開發環境版本,包含了用幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者:
<!-- 生產環境版本,優化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
3)vue官方提供了一個快速搭建vue項目的腳手架:vue-cli
使用它能快速的構建一個web工程模板
安裝:npm install -g vue-cli
新建module 打開terminal進入目錄,
用vue-cli命令,快速搭建一個webpack的項目:vue init webpack
渲染.html
app.name=」春哥」
h2
元素中,經過{{name}}的方式,來渲染剛剛定義的name屬性。綁定.html
num
input
元素,經過v-model
與num
進行綁定。{{num}}
在頁面輸出事件.html
每一個 Vue 應用都是經過用 Vue
函數建立一個新的 Vue 實例開始的:
var vm = new Vue({
// 選項
})
在構造函數中傳入一個對象,而且在對象中聲明各類Vue須要的數據和方法,包括:
每一個Vue實例都須要關聯一段Html模板,Vue會基於此模板進行視圖渲染。
能夠經過el屬性來指定。
例如一段html模板:
<div id="app">
</div>
而後建立Vue實例,關聯這個div:
var vm = new Vue({
el:"#app"
})
這樣,Vue就能夠基於id爲app
的div元素做爲模板進行渲染了。在這個div範圍之外的部分是沒法使用vue特性的。
當Vue實例被建立時,它會嘗試獲取在data中定義的全部屬性,用於視圖的渲染,而且監視data中的屬性變化,當data發生改變,全部相關的視圖都將從新渲染,這就是「響應式「系統。
html:
<div id="app"> <input type="text" v-model="name"/> </div> Js: var vm = new Vue({ el:"#app", data:{ name:"xx" } })
Vue實例中除了能夠定義data屬性,也能夠定義方法,而且在Vue的做用範圍內使用。
html:
<div id="app">
{{num}}
<button v-on:click="add">加</button>
</div>
js:
var vm = new Vue({ el:"#app", data:{ num: 0 }, methods:{ add:function(){ // this表明的當前vue實例 this.num++; } } })
1)生命週期:
每一個 Vue 實例在被建立時都要通過一系列的初始化過程 :建立實例,裝載模板,渲染模板等等。Vue爲生命週期中的每一個狀態都設置了鉤子函數(監聽函數)。每當Vue實例處於不一樣的生命週期時,對應的函數就會被觸發調用。
2)鉤子函數:
例如:created表明在vue實例建立後;
咱們能夠在Vue中定義一個created函數,表明這個時期的構造函數:
html: <div id="app"> {{hello}} </div> js: var vm = new Vue({ el:"#app", data:{ hello: '' // hello初始化爲空 }, created(){ this.hello = "hello, world! 我出生了!"; } })
3)鉤子函數執行順序:
鉤子.html
a)created和mounted
查看console:
beforecreated:el 和 data 並未初始化
created:完成了 data 數據的初始化,el沒有
beforeMount:完成了 el 和 data 初始化
mounted :完成掛載
另外在beforemount,咱們能發現el仍是 {{message}},這裏就是應用的 Virtual DOM(虛擬Dom)技術,先把坑佔住了。到後面mounted掛載的時候再把值渲染進去。
b)update
在 chrome console裏執行命令:
app.message= 'update vue ';
c)destroy
在console裏執行下命令: app.$destroy();
對 vue實例進行銷燬。銷燬完成後,咱們再從新改變message的值,vue再也不對此動做進行響應了。可是原先生成的dom元素還存在,能夠這麼理解,執行了destroy操做,後續就再也不受vue控制了。
d)鉤子函數怎麼用:
beforecreate : 舉個栗子:能夠在這加個loading事件
created :在這結束loading,還作一些初始化,實現函數自執行
mounted : 在這發起後端請求,拿回數據,配合路由鉤子作一些事情
beforeDestroy: 你確認刪除XX嗎? destroyed :當前組件已被刪除,清空相關內容
data:{ birthday:1529032123201 // 毫秒值 }
假如但願獲得yyyy-MM-dd的樣式:
<h1>您的生日是:{{ new Date(birthday).getFullYear() + '-'+ new Date(birthday).getMonth()+ '-' + new Date(birthday).getDay() }} </h1>
雖然能獲得結果,可是很是麻煩。
Vue中提供了計算屬性,來替代複雜的表達式:
var vm = new Vue({ el:"#app", data:{ birthday:1429032123201 // 毫秒值 }, computed:{ birth(){// 計算屬性本質是一個方法,可是必須返回結果 const d = new Date(this.birthday); return d.getFullYear() + "-" + d.getMonth() + "-" + d.getDay(); } } })
計算屬性本質就是方法,可是必定要返回數據。
Watch.html
在大型應用開發的時候,頁面能夠劃分紅不少部分。每每不一樣的頁面,也會有相同的部分。例如可能會有相同的頭部導航。
可是若是每一個頁面都獨自開發,這無疑增長了咱們開發的成本。因此咱們會把頁面的不一樣部分拆分紅獨立的組件,而後在不一樣頁面就能夠共享這些組件,避免重複開發。
1)全局組件.html
2)定義好的組件,能夠任意複用屢次:
<div id="app"> <!--使用定義好的全局組件--> <counter></counter> <counter></counter> <counter></counter> </div>
3)每一個組件互不干擾,都有本身的count值。怎麼實現的?
定義這個 <counter>
組件時,它的data 並非像這樣直接提供一個對象:
data: { count: 0 }
取而代之的是,一個組件的 data 選項必須是一個函數,所以每一個實例能夠維護一份被返回對象的獨立的拷貝:
data: function () { return { count: 0 } }
一旦全局註冊,就意味着即使之後你再也不使用這個組件,它依然會隨着Vue的加載而加載。
所以,對於一些並不頻繁使用的組件,咱們會採用局部註冊。
咱們先在外部定義一個對象,結構與建立組件時傳遞的第二個參數一致:
const counter = { template:'<button v-on:click="count++">漲了 {{ count }} 個粉</button>', data(){ return { count:0 } } }; var app = new Vue({ el:"#app", components:{ counter:counter // 將定義的對象註冊爲組件 } })
各個組件之間以嵌套的關係組合在一塊兒,不可避免的會有組件間通訊的需求。
prop 是父組件用來傳遞數據的一個自定義屬性。
父組件的數據須要經過 props 把數據傳給子組件,子組件須要顯式地用 props 選項聲明 "prop":
父子.html
子父.html
<div id="app"> <h2>num: {{num}}</h2> <!--使用子組件的時候,傳遞num到子組件中--> <counter :num="num"></counter> </div> <script src="vue.js"></script> <script type="text/javascript"> Vue.component("counter", {// 子組件,定義了兩個按鈕,點擊數字num會加或減 template:'\ <div>\ <button @click="num++">加</button> \ <button @click="num--">減</button> \ </div>', props:['num']// count是從父組件獲取的。 }) var app = new Vue({ el:"#app", data:{ num:0 } }) </script>
好像沒問題,點擊按鈕報錯:
子組件接收到父組件屬性後,默認是不容許修改的。
既然只有父組件能修改,那麼加和減的操做必定是放在父組件:
var app = new Vue({ el:"#app", data:{ num:0 }, methods:{ // 父組件中定義操做num的方法 increment(){ this.num++; }, decrement(){ this.num--; } } })
可是,點擊按鈕是在子組件中,那就是說須要子組件來調用父組件的函數,怎麼作?
咱們能夠經過v-on指令將父組件的函數綁定到子組件上:
<div id="app"> <h2>num: {{num}}</h2> <counter :count="num" @inc="increment" @dec="decrement"></counter> </div>
而後,當子組件中按鈕被點擊時,調用綁定的函數:
Vue.component("counter", { template:'\ <div>\ <button @click="plus">加</button> \ <button @click="reduce">減</button> \ </div>', props:['count'], methods:{ plus(){ this.$emit("inc"); }, reduce(){ this.$emit("dec"); } } })
vue提供了一個內置的this.$emit函數,用來調用父組件綁定的函數。
一個頁面,包含登陸和註冊,點擊不一樣按鈕,實現登陸和註冊頁切換。
在route.html中使用剛剛編寫的兩個組件. 效果:route.html
當點擊登陸或註冊按鈕,分別顯示登陸頁或註冊頁,而不是一塊兒顯示。
雖然使用原生的Html5和JS也能實現,可是官方推薦咱們使用vue-router模塊。
在route.html中引入依賴:
<script src="vue-router.js"></script>
新建vue-router對象,而且指定路由規則:
// 建立VueRouter對象 const router = new VueRouter({ routes:[ // 編寫多個路由規則 { path:"/login", // 請求路徑 component:loginForm // 組件名稱 }, {path:"/register",component:registerForm}, ] })
在父組件中引入router對象:
var vm = new Vue({ el:"#app", components:{// 引用登陸和註冊組件 loginForm, registerForm }, router // 引用上面定義的router對象 })
頁面跳轉控制:
<div id="app"> <!--router-link來指定跳轉的路徑--> <span><router-link to="/login">登陸</router-link></span> <span><router-link to="/register">註冊</router-link></span> <hr/> <div> <!--vue-router的錨點--> <router-view></router-view> </div> </div>
單頁應用中,頁面的切換並非頁面的跳轉。僅僅是地址值變化。
webpack打包的啓點,能夠有一個或多個,通常是js文件。webpack會從啓點文件開始,尋找啓點直接或間接依賴的其它全部的依賴,包括JS、CSS、圖片資源等,做爲未來打包的原始數據
出口通常包含兩個屬性:path和filename。用來告訴webpack打包的目標文件夾,以及文件的名稱。目的地也能夠有多個。
webpack自己只識別Js文件,若是要加載非JS文件,必須指定一些額外的加載器(loader),例如css-loader。而後將這些文件轉爲webpack能處理的有效模塊,最後利用webpack的打包能力去處理。
插件能夠擴展webpack的功能,讓webpack不只僅是完成打包,甚至各類更復雜的功能,或者是對打包功能進行優化、壓縮,提升效率。
進入文件下,輸入命令:npm install webpack webpack-cli --save-dev
webpack.config.js
配置文件中就是要指定上面說的四個核心概念,入口、出口、加載器、插件。
加載器和插件是可選的。先編寫入口和出口
webpack打包的起點,能夠有一個或多個,通常是js文件。全部的東西都集中在route.html,不是一個js,那怎麼辦?
新建一個js,把route.html中的部份內容進行集中,而後在index.html中引用這個js。
新建main.js, 而後把原來route.html中的js代碼所有移動到main.js中:
// 使用es6的語法導入js模塊 import Vue from './vue'; import VueRouter from './vue-router' import loginForm from './login' import registerForm from './register' Vue.use(VueRouter) // 建立VueRouter對象 const router = new VueRouter({ routes:[ // 編寫多個路由規則 { path:"/login", // 請求路徑 component:loginForm // 組件名稱 }, {path:"/register",component:registerForm}, ] }) var vm = new Vue({ el:"#app", components:{// 引用登陸和註冊組件 loginForm, registerForm }, router })
要使用import,就須要在login.js和register.js中添加export導出語句:
export default loginForm;
export default registerForm;
vue-router使用模塊話加載後,必須增長一句:Vue.use(VueRouter)
這樣,main.js就成了咱們整個配置的入口了。
在webpack.config.js中添加如下內容:
module.exports={ entry:'main.js', //指定打包的入口文件 }
出口,就是輸出的目的地。通常咱們會用一個dist目錄,做爲打包輸出的文件夾。
添加出口配置:
module.exports={ entry:'./main.js', //指定打包的入口文件 output:{ // path: 輸出的目錄,__dirname是相對於webpack.config.js配置文件的絕對路徑 path : __dirname+'/dist', filename:'build.js' //輸出的js文件名 } }
在控制檯輸入如下命令:npx webpack --config webpack.config.js
查看dist目錄,嘗試打開build.js,全部的js合併爲1個,而且對變量名進行了隨機打亂,這樣就起到了 壓縮、混淆的做用。
在route.html中引入剛剛生成的build.js文件,運行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--router-link來指定跳轉的路徑--> <span><router-link to="/login">登陸</router-link></span> <span><router-link to="/register">註冊</router-link></span> <hr/> <div> <!--vue-router的錨點--> <router-view></router-view> </div> </div> <script src="./dist/build.js"></script> </body> </html>
與上面相似,可是webpack默認只支持js加載。要加載CSS,html文件,必須安裝各自加載器:
npm install style-loader css-loader --save-dev
npm install html-webpack-plugin --save-dev
5.1 在開發中,須要打包的東西不止是js、css、html。還有更多的東西要處理,這些插件和加載器若是咱們一一去添加就會比較麻煩。
5.2 安裝
後綴名爲.vue的文件,稱爲單文件組件。
每個.vue文件,就是一個獨立的vue組件。相似於剛纔寫的loginForm.js和registerForm.js
只不過,在js中編寫 html模板和樣式很是的不友好,並且沒有語法提示和高亮。
而單文件組件中包含三部份內容:
每一個組件都有本身獨立的html、JS、CSS,互不干擾,真正作到可獨立複用。
執行npm run dev 或者 npm start 均可以啓動項目。
div
,其id爲app
。<App/>
,這是使用了App組件,即App.vue,也就是說index.html中最終展示的是App.vue中的內容。<router-view>
, vue-router路由後的組件將會在錨點展現。