Vue入門篇

一  ES6語法

1  ECMAScript

  • 1995年,網景工程師Brendan Eich 花了10天時間設計了JavaScript語言。
  • 1996年,微軟發佈了JScript,實際上是JavaScript的逆向工程實現。
  • 1997年,爲了統一各類不一樣script腳本語言,ECMA(歐洲計算機制造商協會)以JavaScript爲基礎,制定了ECMAscript標準規範。JavaScript和JScript都是ECMAScript的標準實現者,隨後各大瀏覽器廠商紛紛實現了ECMAScript標準。

因此,ECMAScript是瀏覽器腳本語言的規範,而各類咱們熟知的js語言,如JavaScript則是規範的具體實現javascript

ES5和6的一些新特性

2.1  let和const命令

以前,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聲明常量,不能修改。前端

2.2    箭頭函數

var print = function (obj) {
    console.log(obj);
}
// 簡寫爲:
var print2 = obj => console.log(obj);

參數=>{方法體}vue

2.3 模塊化

好比定義一個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)

 

二  Vue入門

2.1    MVVM模式

  • M:即Model,模型,包括數據和一些基本操做
  • V:即View,視圖,頁面渲染結果
  • VM:即View-Model,模型與視圖間的雙向操做(無需開發人員干涉)

在MVVM以前,開發人員從後端獲取須要的數據模型,而後要經過DOM操做Model渲染到View中。然後當用戶操做視圖,咱們還須要經過DOM獲取View中的數據,而後同步到Model中。git

而MVVM中的VM要作的事情就是把DOM操做徹底封裝起來,開發人員不用再關心Model和View之間是如何互相影響的。es6

vue就是一款MVVM模式的框架。

Vue是一個漸進式javascript框架,既能夠只做爲一個js庫來使用,若是想將更多的業務邏輯放到前端來實現,它也有vue-router  vuex等等核心庫來幫你實現。

2.2 Node和NPM

NPM是Node提供的模塊管理工具,能夠很是方便的下載安裝不少前端框架,包括Jquery、AngularJS、VueJs都有。,咱們先安裝node及NPM工具。

2.2.1 node.js

下載地址:https://nodejs.org/en/download/

完成之後,在控制檯輸入:node –v

2.2.2 npm

安裝完成Node應該自帶了NPM了,在控制檯輸入npm -v查看:

npm默認的倉庫地址是在國外網站,速度較慢,建議設置到淘寶鏡像。可是切換鏡像是比較麻煩的。推薦一款切換鏡像的工具:nrm

首先安裝nrm,這裏-g表明全局安裝:

npm install nrm –g

而後經過nrm ls命令查看npm的倉庫列表,帶*的就是當前選中的鏡像倉庫:

經過nrm use taobao來指定要使用的鏡像源。

而後經過nrm test taobao來測試速度:

安裝完成請必定要重啓下電腦。

2.3 快速入門:

2.3.1 vue安裝

三種方式:

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

2.3.2  vue渲染

渲染.html

app.name=」春哥」

  • 首先經過 new Vue()來建立Vue實例
  • 而後構造函數接收一個對象,對象中有一些屬性:
  • el:是element的縮寫,經過id選中要渲染的頁面元素,這裏是一個div
  • data:數據,數據是一個對象,裏面有不少屬性,均可以渲染到視圖中
  • 頁面中的h2元素中,經過{{name}}的方式,來渲染剛剛定義的name屬性。

2.3.3 雙向綁定

綁定.html

  • 在data添加了新的屬性:num
  • 在頁面中有一個input元素,經過v-modelnum進行綁定。
  • 同時經過{{num}}在頁面輸出

2.3.4事件處理

事件.html

  • 用v-on指令綁定點擊事件,而不是普通的onclick,而後直接操做num
  • 普通onclick是沒法直接操做num的。

2.4 Vue的結構和生命週期

每一個 Vue 應用都是經過用 Vue 函數建立一個新的 Vue 實例開始的:

var vm = new Vue({

  // 選項

})

在構造函數中傳入一個對象,而且在對象中聲明各類Vue須要的數據和方法,包括:

  • el
  • data
  • methods
  • ...

2.4.1 模板

每一個Vue實例都須要關聯一段Html模板,Vue會基於此模板進行視圖渲染。

能夠經過el屬性來指定。

例如一段html模板:

<div id="app">

   

</div>

而後建立Vue實例,關聯這個div:

var vm = new Vue({

         el:"#app"

})

這樣,Vue就能夠基於id爲app的div元素做爲模板進行渲染了。在這個div範圍之外的部分是沒法使用vue特性的。

2.4.2數據

當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"
    }
})

 

  • name的變化會影響到input的值
  • input中輸入的值,也會致使vm中的name發生改變

2.4.3 方法

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++;
        }
    }
})

 

2.4.4生命週期:

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 :當前組件已被刪除,清空相關內容

2.5 指令

2.5.1 v-model v-if v-for v-on v-bind等等

2.5.2 計算屬性

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();
        }
    }
})

 

計算屬性本質就是方法,可是必定要返回數據。

2.5.3 watch

Watch.html

2.6組件化

在大型應用開發的時候,頁面能夠劃分紅不少部分。每每不一樣的頁面,也會有相同的部分。例如可能會有相同的頭部導航。

可是若是每一個頁面都獨自開發,這無疑增長了咱們開發的成本。因此咱們會把頁面的不一樣部分拆分紅獨立的組件,而後在不一樣頁面就能夠共享這些組件,避免重複開發。

2.6.1 全局組件

1)全局組件.html

  • 組件其實也是一個Vue實例,所以它在定義時也會接收:data、methods、生命週期函數等
  • 不一樣的是組件不會與頁面的元素綁定,不然就沒法複用了,所以沒有el屬性。
  • 可是組件渲染須要html模板,因此增長了template屬性,值就是HTML模板
  • 全局組件定義完畢,任何vue實例均可以直接在HTML中經過組件名稱來使用組件了。
  • data的定義方式比較特殊,必須是一個函數。

2)定義好的組件,能夠任意複用屢次:

<div id="app">
    <!--使用定義好的全局組件-->
    <counter></counter>
    <counter></counter>
    <counter></counter>
</div>

3)每一個組件互不干擾,都有本身的count值。怎麼實現的?

定義這個 <counter> 組件時,它的data 並非像這樣直接提供一個對象:

data: {
  count: 0
}

取而代之的是,一個組件的 data 選項必須是一個函數,所以每一個實例能夠維護一份被返回對象的獨立的拷貝:

data: function () {
  return {
    count: 0
  }
}

 

2.6.2 局部組件

一旦全局註冊,就意味着即使之後你再也不使用這個組件,它依然會隨着Vue的加載而加載。

所以,對於一些並不頻繁使用的組件,咱們會採用局部註冊。

咱們先在外部定義一個對象,結構與建立組件時傳遞的第二個參數一致:

const counter = {
    template:'<button v-on:click="count++">漲了 {{ count }} 個粉</button>',
    data(){
        return {
            count:0
        }
    }
};
var app = new Vue({
    el:"#app",
    components:{
        counter:counter // 將定義的對象註冊爲組件
    }
})

 

  • components就是當前vue對象子組件集合。
    • 其key就是子組件名稱
    • 其值就是組件對象的屬性
  • 效果與剛纔的全局註冊是相似的,不一樣的是,這個counter組件只能在當前的Vue實例中使用

2.7 組件通訊

各個組件之間以嵌套的關係組合在一塊兒,不可避免的會有組件間通訊的需求。

2.7.1 父—>子

prop 是父組件用來傳遞數據的一個自定義屬性。

父組件的數據須要經過 props 把數據傳給子組件,子組件須要顯式地用 props 選項聲明 "prop":

父子.html

2.7.2 子—>父

子父.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>

 

  • 子組件接收父組件的num屬性
  • 子組件定義點擊按鈕,點擊後對num進行加或減操做

好像沒問題,點擊按鈕報錯:

子組件接收到父組件屬性後,默認是不容許修改的。

既然只有父組件能修改,那麼加和減的操做必定是放在父組件:

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函數,用來調用父組件綁定的函數。

2.7.3 大量的組件間通訊,用到vuex。

三 路由vue-router

3.1 場景模擬

一個頁面,包含登陸和註冊,點擊不一樣按鈕,實現登陸和註冊頁切換。

3.1.1 登錄組件

3.1.2 註冊組件

3.1.3 父組件

在route.html中使用剛剛編寫的兩個組件.  效果:route.html

3.1.4

當點擊登陸或註冊按鈕,分別顯示登陸頁或註冊頁,而不是一塊兒顯示。

雖然使用原生的Html5和JS也能實現,可是官方推薦咱們使用vue-router模塊。

3.2 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},
    ]
})
  • 建立VueRouter對象,並指定路由參數
  • routes:路由規則的數組,能夠指定多個對象,每一個對象是一條路由規則,包含如下屬性:
    • path:路由的路徑
    • component:組件名稱

在父組件中引入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>
  • 經過<router-view>來指定一個錨點,當路由的路徑匹配時,vue-router會自動把對應組件放到錨點位置進行渲染
  • 經過<router-link>指定一個跳轉連接,當點擊時,會觸發vue-router的路由功能,路徑中的hash值會隨之改變

單頁應用中,頁面的切換並非頁面的跳轉。僅僅是地址值變化。

四 webpack

4.1 Webpack 是一個前端資源的打包工具,它能夠將js、image、css等資源當成一個模塊進行打包。

  • 將許多碎小文件打包成一個總體,減小單頁面內的衍生請求次數,提升網站效率。
  • 將ES6的高級語法進行轉換編譯,以兼容老版本的瀏覽器。
  • 將代碼打包的同時進行混淆,提升代碼的安全性。

4.2 webpack四個概念

  • 入口(entry)

  webpack打包的啓點,能夠有一個或多個,通常是js文件。webpack會從啓點文件開始,尋找啓點直接或間接依賴的其它全部的依賴,包括JS、CSS、圖片資源等,做爲未來打包的原始數據

  • 輸出(output)

  出口通常包含兩個屬性:path和filename。用來告訴webpack打包的目標文件夾,以及文件的名稱。目的地也能夠有多個。

  • 加載器(loader)

  webpack自己只識別Js文件,若是要加載非JS文件,必須指定一些額外的加載器(loader),例如css-loader。而後將這些文件轉爲webpack能處理的有效模塊,最後利用webpack的打包能力去處理。

  • 插件(plugins)

  插件能夠擴展webpack的功能,讓webpack不只僅是完成打包,甚至各類更復雜的功能,或者是對打包功能進行優化、壓縮,提升效率。

4.3 安裝

進入文件下,輸入命令:npm install webpack webpack-cli --save-dev

4.4編寫webpack配置

webpack.config.js

配置文件中就是要指定上面說的四個核心概念,入口、出口、加載器、插件。

加載器和插件是可選的。先編寫入口和出口

4.4.1 入口

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',  //指定打包的入口文件
}

4.4.2 出口

出口,就是輸出的目的地。通常咱們會用一個dist目錄,做爲打包輸出的文件夾。

添加出口配置:

module.exports={
    entry:'./main.js',  //指定打包的入口文件
    output:{
        // path: 輸出的目錄,__dirname是相對於webpack.config.js配置文件的絕對路徑
        path : __dirname+'/dist',  
        filename:'build.js'     //輸出的js文件名
    }
}

4.4.3 打包

在控制檯輸入如下命令:npx webpack --config webpack.config.js

查看dist目錄,嘗試打開build.js,全部的js合併爲1個,而且對變量名進行了隨機打亂,這樣就起到了 壓縮、混淆的做用。

4.5測試  

在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>

4.6 打包css和html

與上面相似,可是webpack默認只支持js加載。要加載CSS,html文件,必須安裝各自加載器:

npm install style-loader css-loader --save-dev

npm install html-webpack-plugin --save-dev

五 腳手架 vue-cli

5.1 在開發中,須要打包的東西不止是js、css、html。還有更多的東西要處理,這些插件和加載器若是咱們一一去添加就會比較麻煩。

5.2 安裝

5.3項目結構

5.4 單文件組件

後綴名爲.vue的文件,稱爲單文件組件。

每個.vue文件,就是一個獨立的vue組件。相似於剛纔寫的loginForm.js和registerForm.js

只不過,在js中編寫 html模板和樣式很是的不友好,並且沒有語法提示和高亮。

而單文件組件中包含三部份內容:

  • template:模板,支持html語法高亮和提示
  • script:js腳本,這裏編寫的就是vue的組件對象,上面的data(){}
  • style:樣式,支持CSS語法高亮和提示

每一個組件都有本身獨立的html、JS、CSS,互不干擾,真正作到可獨立複用。

5.5 運行

  • 腳本有三個:
    • dev:使用了webpack-dev-server命令,開發時熱部署使用
    • start:使用了npm run dev命令,與上面的dev效果徹底同樣
    • build:等同於webpack的打包功能,會打包到dist目錄下。

執行npm run dev 或者 npm start 均可以啓動項目。

六 最終項目

  • index.html中定義了空的div,其id爲app
  • main.js中定義了Vue對象,而且綁定經過id選擇器,綁定到index.html的div中,所以main.js的內容都將在index.htmldiv中顯示
  • 而main.js中只有一行內容:<App/>,這是使用了App組件,即App.vue,也就是說index.html中最終展示的是App.vue中的內容。
  • App.vue中也沒有內容,而是定義了vue-router的錨點:<router-view>, vue-router路由後的組件將會在錨點展現。
  • 最終的結論是:一切路由後的內容都將經過App.vueindex.html中顯示。
相關文章
相關標籤/搜索