天天看點

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

靜态頁面
  • 最初的網頁以HTML為主,是純靜态的網頁。網頁是隻讀的,資訊流隻能從服務的到用戶端單向流通。開發人員也隻關心頁面的樣式和内容即可。
異步重新整理,操作DOM
  • 1995年,網景工程師Brendan Eich 花了10天時間設計了JavaScript語言.

    随着JavaScript的誕生,我們可以操作頁面的DOM元素及樣式,頁面有了一些動态的效果,但是依然是以靜态為主。

  • ajax盛行:
    • 2005年開始,ajax逐漸被前端開發人員所重視,因為不用重新整理頁面就可以更新頁面的資料和渲染效果。
    • 此時的開發人員不僅僅要編寫HTML樣式,還要懂ajax與後端互動,然後通過JS操作Dom元素來實作頁面動态效果。比較流行的架構如Jquery就是典型代表。
MVVM,關注模型和視圖
  • 2008年,google的Chrome釋出,随後就以極快的速度占領市場,超過IE成為浏覽器市場的主導者。
  • 2009年,Ryan Dahl在谷歌的Chrome V8引擎基礎上,打造了基于事件循環的異步IO架構:Node.js。
    • 基于時間循環的異步IO
    • 單線程運作,避免多線程的變量同步問題
    • JS可以編寫背景diamante,前背景統一程式設計語言
  • node.js的偉大之處不在于讓JS邁向了後端開發,而是建構了一個龐大的生态系統。
  • 2010年,NPM作為node.js的包管理系統首次釋出,開發人員可以遵循Common.js規範來編寫Node.js子產品,然後釋出到NPM上供其他開發人員使用。目前已經是世界最大的包子產品管理系統。
  • 随後,在node的基礎上,湧現出了一大批的前端架構:
    Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化
MVVM模式
  • M:即Model,模型,包括資料和一些基本操作
  • V:即View,視圖,頁面渲染結果
  • VM:即View-Model,模型與視圖間的雙向操作(無需開發人員幹涉)

在MVVM之前,開發人員從後端擷取需要的資料模型,然後要通過DOM操作Model渲染到View中。而後當使用者操作視圖,我們還需要通過DOM擷取View中的資料,然後同步到Model中。

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

  • 隻要我們Model發生了改變,View上自然就會表現出來。
  • 當使用者修改了View,Model中的資料也會跟着改變。

把開發人員從繁瑣的DOM操作中解放出來,把關注點放在如何操作Model上。

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

而我們今天要學習的,就是一款MVVM模式的架構:Vue

1.認識Vue

Vue (讀音 /vjuː/,類似于 view) 是一套用于建構使用者界面的漸進式架構。與其它大型架構不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫隻關注視圖層,不僅易于上手,還便于與第三方庫或既有項目整合。另一方面,當與現代化的工具鍊以及各種支援類庫結合使用時,Vue 也完全能夠為複雜的單頁應用提供驅動。

前端架構三巨頭:Vue.js、React.js、AngularJS,vue.js以期輕量易用著稱,vue.js和React.js發展速度最快。
           

官網:https://cn.vuejs.org/

參考:https://cn.vuejs.org/v2/guide/

![1525829249048](assets/

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

Git位址:https://github.com/vuejs

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

尤雨溪,Vue.js 創作者,Vue Technology創始人,緻力于Vue的研究開發。

2.Node和NPM

前面說過,NPM是Node提供的子產品管理工具,可以非常友善的下載下傳安裝很多前端架構,包括Jquery、AngularJS、VueJs都有。為了後面學習友善,我們先安裝node及NPM工具。

2.1.下載下傳Node.js

下載下傳位址:https://nodejs.org/en/download/

![1525830686367](assets/

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

推薦下載下傳LTS版本。

課程中采用的是8.9.0版本。目前最新的是8.11.1。大家自行下載下傳。然後下一步安裝即可。

完成以後,在控制台輸入:

node -v
           

看到版本資訊:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

2.2.NPM

安裝完成Node應該自帶了NPM了,在控制台輸入

npm -v

檢視:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

npm預設的倉庫位址是在國外網站,速度較慢,建議大家設定到淘寶鏡像。但是切換鏡像是比較麻煩的。推薦一款切換鏡像的工具:nrm

我們首先安裝nrm,這裡

-g

代表全局安裝

npm install nrm -g
           

然後通過

nrm ls

指令檢視npm的倉庫清單,帶*的就是目前選中的鏡像倉庫:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

通過

nrm use taobao

來指定要使用的鏡像源:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

然後通過

nrm test npm

來測試速度:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

測試淘寶請輸入:

nrm test taobao
           

注意:

  • 安裝完成請一定要重新開機下電腦!!!
  • 安裝完成請一定要重新開機下電腦!!!
  • 安裝完成請一定要重新開機下電腦!!!

或者,直接配置倉庫:

npm config set registry http://registry.npm.taobao.org/
           

3.快速入門

接下來,我們快速領略下vue的魅力

3.1.建立工程

建立一個新的工程:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

選中一個空的:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

位置資訊:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

3.2.安裝vue

3.2.1.下載下傳安裝

下載下傳位址:https://github.com/vuejs/vue

可以下載下傳2.5.16版本https://github.com/vuejs/vue/archive/v2.5.16.zip

下載下傳解壓,得到vue.js檔案。

3.2.2.使用CDN

或者也可以直接使用公共的CDN服務:

<!-- 開發環境版本,包含了用幫助的指令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
           

或者:

<!-- 生産環境版本,優化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
           

3.2.3.npm安裝(推薦)

在idea的左下角,有個Terminal按鈕,點選打開控制台:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

先輸入:

npm init -y
           

對項目進行初始化

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

此時,會在項目目錄下出現一個package.json檔案:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

這是對項目的基本描述資訊。例如名稱、版本等,有點類似java中的pom檔案。

安裝Vue,輸入指令:

npm install vue --save
           
Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

然後就會在hello-vue目錄發現一個node_modules目錄,并且在下面有一個vue目錄。

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

node_modules是通過npm安裝的所有子產品的預設位置。

此時再檢視package.json,會發現有了變化:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

會發現,剛剛安裝的vue依賴再這裡出現了描述資訊。是不是跟pom檔案很像?

3.3.vue入門案例

3.3.1.HTML模闆

在hello-vue目錄建立一個HTML

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

在hello.html中,我們編寫一段簡單的代碼:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

h2中要輸出一句話:xx 非常帥。前面的xx是要渲染的資料。

3.3.2.vue渲染

然後我們通過Vue進行渲染:

<div id="app">
    <h2>{{name}} 非常帥</h2>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    // 生成一個Vue執行個體
    var app = new Vue({
        el:"#app", // el,即element。要渲染的的頁面元素
        data:{ // 資料
            name:"虎哥"
        }
    })
</script>
           
  • 首先通過 new Vue()來建立Vue執行個體
  • 然後構造函數接收一個對象,對象中有一些屬性:
    • el:是element的縮寫,通過id選中要渲染的頁面元素,本例中是一個div
    • data:資料,資料是一個對象,裡面有很多屬性,都可以渲染到視圖中
      • name:這裡我們指定了一個name屬性
  • 頁面中的

    h2

    元素中,我們通過{{name}}的方式,來渲染剛剛定義的name屬性。

打開頁面檢視效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

更神奇的在于,當你修改name屬性時,頁面會跟着變化:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

3.3.3.雙向綁定

我們對剛才的案例進行簡單修改:

<div id="app">
    <input type="text" v-model="num">
    <h2>
        {{name}} 非常帥,
        有{{num}}位女神為他着迷。
    </h2>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    // 生成一個Vue執行個體
    var app = new Vue({
        el:"#app", // el,即element。要渲染的的頁面元素
        data:{ // 資料
            name:"虎哥",
            num:1
        }
    })
</script>
           
  • 我們在data添加了新的屬性:

    num

  • 在頁面中有一個

    input

    元素,通過

    v-model

    num

    進行綁定。
  • 同時通過

    {{num}}

    在頁面輸出

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

我們可以觀察到,輸入框的變化引起了data中的num的變化,同時頁面輸出也跟着變化。

  • input與num綁定,input的value值變化,影響到了data中的num值
  • 頁面

    {{num}}

    與資料num綁定,是以num值變化,引起了頁面效果變化。

沒有任何dom操作,這就是雙向綁定的魅力。

3.3.4.事件處理

我們在頁面添加一個按鈕:

  • 這裡用

    v-on

    指令綁定點選事件,而不是普通的

    onclick

    ,然後直接操作num
  • 普通onclick是無法直接操作num的。

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

4.Vue執行個體

4.1.建立Vue執行個體

每個 Vue 應用都是通過用

Vue

函數建立一個新的 Vue 執行個體開始的:

var vm = new Vue({
  // 選項
})
           

在構造函數中傳入一個對象,并且在對象中聲明各種Vue需要的資料和方法,包括:

  • el
  • data
  • methods

接下來我們一 一介紹。

4.2.模闆或元素

每個Vue執行個體都需要關聯一段Html模闆,Vue會基于此模闆進行視圖渲染。

我們可以通過el屬性來指定。

例如一段html模闆:

<div id="app">
    
</div>
           

然後建立Vue執行個體,關聯這個div

var vm = new Vue({
	el:"#app"
})
           

這樣,Vue就可以基于id為

app

的div元素作為模闆進行渲染了。在這個div範圍以外的部分是無法使用vue特性的。

4.3.資料

當Vue執行個體被建立時,它會嘗試擷取在data中定義的所有屬性,用于視圖的渲染,并且監視data中的屬性變化,當data發生改變,所有相關的視圖都将重新渲染,這就是“響應式“系統。

html:

<div id="app">
    <input type="text" v-model="name"/>
</div>
           

js:

var vm = new Vue({
    el:"#app",
    data:{
        name:"劉德華"
    }
})
           
  • name的變化會影響到

    input

    的值
  • input中輸入的值,也會導緻vm中的name發生改變

4.4.方法

Vue執行個體中除了可以定義data屬性,也可以定義方法,并且在Vue的作用範圍内使用。

html:

<div id="app">
    <button @click="add">點我</button>
</div>
           

js:

var vm = new Vue({
    el:"#app",
    data:{
    },
    methods:{
        add:function(){
            console.log("彈彈彈,彈走魚尾紋")
        }
    }
})
           

4.5.生命周期鈎子

4.5.1.生命周期

每個 Vue 執行個體在被建立時都要經過一系列的初始化過程 :建立執行個體,裝載模闆,渲染模闆等等。Vue為生命周期中的每個狀态都設定了鈎子函數(監聽函數)。每當Vue執行個體處于不同的生命周期時,對應的函數就會被觸發調用。

生命周期:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

4.5.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! 我出生了!";
    }
})
           

結果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

4.5.3.this

我們可以看下在vue内部的this變量是誰,我們在created的時候,列印this

var vm = new Vue({
    el:"#app",
    data:{
        hello: '' // hello初始化為空
    },
    created(){
        this.hello = "hello, world! 我出生了!";
        console.log(this);
    }
})
           

控制台的輸出:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

總結:

this

就是目前的Vue執行個體,在Vue對象内部,必須使用

this

才能通路到Vue中定義的data内屬性、方法等。

5.指令

什麼是指令?

指令 (Directives) 是帶有

v-

字首的特殊屬性。例如我們在入門案例中的v-model,代表雙向綁定。

5.1.插值表達式

5.1.1.花括号

格式:

{{表達式}}
           

說明:

  • 該表達式支援JS文法,可以調用js内置函數(必須有傳回值)
  • 表達式必須有傳回結果。例如 1 + 1,沒有結果的表達式不允許使用,如:var a = 1 + 1;
  • 可以直接擷取Vue執行個體中定義的資料或函數

示例:

HTML:

JS:

var app = new Vue({
    el:"#app",
    data:{
        name:"Jack"
    }
})
           

5.1.2.插值閃爍

使用{{}}方式在網速較慢時會出現問題。在資料未加載完成時,頁面會顯示出原始的

{{}}

,加載完畢後才顯示正确資料,我們稱為插值閃爍。

我們将網速調慢一些,然後試試看剛才的案例:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

重新整理頁面:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.1.3.v-text和v-html

使用v-text和v-html指令來替代

{{}}

說明:

  • v-text:将資料輸出到元素内部,如果輸出的資料有HTML代碼,會作為普通文本輸出
  • v-html:将資料輸出到元素内部,如果輸出的資料有HTML代碼,會被渲染

示例:

HTML:

<div id="app">
    v-text:<span v-text="hello"></span> <br/>
    v-html:<span v-html="hello"></span>
</div>
           

JS:

var vm = new Vue({
    el:"#app",
    data:{
        hello: "<h1>大家好,我是虎哥</h1>"
    }
})
           

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

并且不會出現插值閃爍,當沒有資料時,會顯示空白。

5.2.v-model

剛才的v-text和v-html可以看做是單向綁定,資料影響了視圖渲染,但是反過來就不行。接下來學習的v-model是雙向綁定,視圖(View)和模型(Model)之間會互相影響。

既然是雙向綁定,一定是在視圖中可以修改資料,這樣就限定了視圖的元素類型。目前v-model的可使用元素有:

  • input
  • select
  • textarea
  • checkbox
  • radio
  • components(Vue中的自定義元件)

基本上除了最後一項,其它都是表單的輸入項。

舉例:

html:

<div id="app">
    <input type="checkbox" v-model="language" value="Java" />Java<br/>
    <input type="checkbox" v-model="language" value="PHP" />PHP<br/>
    <input type="checkbox" v-model="language" value="Swift" />Swift<br/>
    <h1>
        你選擇了:{{language.join(',')}}
    </h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            language: []
        }
    })
</script>
           
  • 多個

    CheckBox

    對應一個model時,model的類型是一個數組,單個checkbox值是boolean類型
  • radio對應的值是input的value值
  • input

    textarea

    預設對應的model是字元串
  • select

    單選對應字元串,多選對應也是數組

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.3.v-on

5.3.1.基本用法

v-on指令用于給頁面元素綁定事件。

文法:

v-on:事件名="js片段或函數名"
           

簡寫文法:

@事件名="js片段或函數名"
           

例如v-on:click='add’可以簡寫為@click=‘add’

示例:

<div id="app">
    <!--事件中直接寫js片段-->
    <button @click="num++">增加</button><br/>
    <!--事件指定一個回調函數,必須是Vue執行個體中定義的函數-->
    <button @click="decrement">減少</button><br/>
    <h1>num: {{num}}</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            num:1
        },
        methods:{
            decrement(){
                this.num--;
            }
        }
    })
</script>
           
Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

效果:

另外,

5.3.2.事件修飾符

在事件處理程式中調用

event.preventDefault()

event.stopPropagation()

是非常常見的需求。盡管我們可以在方法中輕松實作這點,但更好的方式是:方法隻有純粹的資料邏輯,而不是去處理 DOM 事件細節。

為了解決這個問題,Vue.js 為

v-on

提供了事件修飾符。之前提過,修飾符是由點開頭的指令字尾來表示的。

  • .stop

    :阻止事件冒泡
  • .prevent

    :阻止預設事件發生
  • .capture

    :使用事件捕獲模式
  • .self

    :隻有元素自身觸發事件才執行。(冒泡或捕獲的都不執行)
  • .once

    :隻執行一次

5.4.v-for

周遊資料渲染頁面是非常常用的需求,Vue中通過v-for指令來實作。

5.4.1.周遊數組

文法:
v-for="item in items"
           
  • items:要周遊的數組,需要在vue的data中定義好。
  • item:疊代得到的數組元素的别名
示例
<div id="app">
    <ul>
        <li v-for="user in users">
            {{user.name}} : {{user.gender}} : {{user.age}}
        </li>
    </ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            users:[
                {name:'柳岩', gender:'女', age: 21},
                {name:'虎哥', gender:'男', age: 30},
                {name:'範冰冰', gender:'女', age: 24},
                {name:'劉亦菲', gender:'女', age: 18},
                {name:'古力娜紮', gender:'女', age: 25}
            ]
        }
    })
</script>
           

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.4.2.數組角标

在周遊的過程中,如果我們需要知道數組角标,可以指定第二個參數:

文法
v-for="(item,index) in items"
           
  • items:要疊代的數組
  • item:疊代得到的數組元素别名
  • index:疊代到的目前元素索引,從0開始。
示例
<div id="app">
        <ul>
            <li v-for="(user,index) in users">
                {{index}} - {{user.name}} : {{user.gender}} : {{user.age}}
            </li>
        </ul>
    </div>
           
效果:
Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.4.3.周遊對象

v-for除了可以疊代數組,也可以疊代對象。文法基本類似

文法:
v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
           
  • 1個參數時,得到的是對象的值
  • 2個參數時,第一個是值,第二個是鍵
  • 3個參數時,第三個是索引,從0開始
示例:
<div id="app">
    <ul>
        <li v-for="(value,key,index) in user">
            {{index}} - {{key}} : {{value}}
        </li>
    </ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            user:{name:'柳岩', gender:'女', age: 21}
        }
    })
</script>
           
效果:
Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.4.4.key

當 Vue.js 用

v-for

正在更新已渲染過的元素清單時,它預設用“就地複用”政策。如果資料項的順序被改變,Vue 将不會移動 DOM 元素來比對資料項的順序, 而是簡單複用此處每個元素,并且確定它在特定索引下顯示已被渲染過的每個元素。

這個功能可以有效的提高渲染的效率。

但是要實作這個功能,你需要給Vue一些提示,以便它能跟蹤每個節點的身份,進而重用和重新排序現有元素,你需要為每項提供一個唯一

key

屬性。理想的

key

值是每項都有的且唯一的 id。

示例:

<ul>
    <li v-for="(item,index) in items" :key="index"></li>
</ul>
           
  • 這裡使用了一個特殊文法:

    :key=""

    我們後面會講到,它可以讓你讀取vue中的屬性,并指派給key屬性
  • 這裡我們綁定的key是數組的索引,應該是唯一的

5.5.v-if和v-show

5.5.1.基本使用

v-if,顧名思義,條件判斷。當得到結果為true時,所在的元素才會被渲染。

文法:
v-if="布爾表達式"
           
示例:
<div id="app">
        <!--事件中直接寫js片段-->
        <button v-on:click="show = !show">點選切換</button><br/>
        <h1 v-if="show">
            你好
        </h1>
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript">
        var app = new Vue({
            el:"#app",
            data:{
                show:true
            }
        })
    </script>
           
效果:
Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.5.2.與v-for結合

當v-if和v-for出現在一起時,v-for優先級更高。也就是說,會先周遊,再判斷條件。

示例:

<div id="app">
        <ul>
            <li v-for="(user,index) in users" v-if="user.gender === '女'">
                {{index}} - {{user.name}} : {{user.gender}} : {{user.age}}
            </li>
        </ul>
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:"#app",
            data:{
                users:[
                    {name:'柳岩', gender:'女', age: 21},
                    {name:'虎哥', gender:'男', age: 30},
                    {name:'範冰冰', gender:'女', age: 24},
                    {name:'劉亦菲', gender:'女', age: 18},
                    {name:'古力娜紮', gender:'女', age: 25}
                ]
            }
        })
    </script>
           

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.5.3.v-else

你可以使用

v-else

指令來表示

v-if

的“else 塊”:

<div id="app">
    <button @click="show=!show">點我</button>
    <ul v-if="show">
        <li v-for="(u,i) in users" :key="i"
            v-if="u.gender === '女'" style="background-color:pink;">
            {{i}}_ {{u.name + ", " + u.gender + ", " + u.age}}
        </li>
        <li v-else style="background-color: blue;">
            {{i}}_ {{u.name + ", " + u.gender + ", " + u.age}}
        </li>
    </ul>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
      el: "#app",
      data:{
        users:[
          {name:'柳岩', gender:'女', age: 20},
          {name:'虎哥', gender:'男', age: 30},
          {name:'範冰冰', gender:'女', age: 24},
          {name:'劉亦菲', gender:'女', age: 18},
          {name:'古力娜紮', gender:'女', age: 25}
        ],
        show: true
      }
    });
</script>
           

v-else

元素必須緊跟在帶

v-if

或者

v-else-if

的元素的後面,否則它将不會被識别。

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

v-else-if

,顧名思義,充當

v-if

的“else-if 塊”,可以連續使用:

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>
           

類似于

v-else

v-else-if

也必須緊跟在帶

v-if

或者

v-else-if

的元素之後。

5.5.4.v-show

另一個用于根據條件展示元素的選項是

v-show

指令。用法大緻一樣:

不同的是帶有

v-show

的元素始終會被渲染并保留在 DOM 中。

v-show

隻是簡單地切換元素的 CSS 屬性

display

示例:

<div id="app">
    <!--事件中直接寫js片段-->
    <button @click="show = !show">點選切換</button><br/>
    <h1 v-if="show">
        你好
    </h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            show:true
        }
    })
</script>
           

代碼:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.6.v-bind

5.6.1.屬性上使用vue資料

看這樣一個案例:

我們提前定義了一些CSS樣式:

#box {
    width: 100px;
    height: 100px;
    color: darkgray
}
.red{
    background-color: red;
}
.blue{
    background-color: blue;
}
           

然後定義了頁面:

<div id="app">
    <button @click="color='red'">紅</button>
    <button @click="color='blue'">藍</button>
    <div class="">
        點選按鈕,背景會切換顔色哦
    </div>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: "#app",
        data: {
            color: "red", // 代表目前的class樣式,目前是紅
        }
    })
</script>
           

解讀:

  • 頁面有兩個按鈕,點選時,會改變Vue執行個體中的color值,這個值與前面定義的CSS樣式一緻。
  • 目前div的class為空,我們希望實作點選按鈕後,div的class樣式會在.red和.blue之間切換

該如何實作?

大家可能會這麼想,既然color值會動态變化為不同的class名稱,那麼我們直接把color注入到class屬性就好了,于是就這樣寫:

這樣寫是錯誤的!因為插值表達式不能用在标簽的屬性中。

此時,Vue提供了一個新的指令來解決:v-bind,文法:

v-bind:屬性名="Vue中的變量"
           

例如,在這裡我們可以寫成:

不過,v-bind太麻煩,是以可以省略,直接寫成:

:屬性名='屬性值'

,即:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.6.2.class屬性的特殊用法

上面雖然實作了顔色切換,但是文法卻比較啰嗦。

Vue對class屬性進行了特殊處理,可以接收數組或對象格式

對象文法

我們可以傳給

:class

一個對象,以動态地切換 class:

  • 對象中,key是已經定義的class樣式的名稱,如本例中的:

    red

    blue

  • 對象中,value是一個布爾值,如果為true,則這個樣式會生效,如果為false,則不生效。

之前的案例可以改寫成這樣:

<div id="app">
    <button @click="boo=!boo">點選切換背景</button>
    <div :class="{red:boo, blue: !boo}">
        點選按鈕,背景會切換顔色哦
    </div>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: "#app",
        data: {
            boo: true, // 一個布爾标記,判斷樣式是否生效
        }
    })
</script>
           
  • 首先class綁定的是一個對象:

    {red:boo, blue: !boo}

    • red和blue兩個樣式的值分别是boo和!boo,也就是說這兩個樣式的生效标記恰好相反,一個生效,另一個失效。
    • boo預設為true,也就是說預設red生效,blue不生效
  • 現在隻需要一個按鈕即可,點選時對boo取反,自然實作了樣式的切換

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.7.計算屬性

在插值表達式中使用js表達式是非常友善的,而且也經常被用到。

但是如果表達式的内容很長,就會顯得不夠優雅,而且後期維護起來也不友善,例如下面的場景,我們有一個日期的資料,但是是毫秒值:

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();
        }
    }
})
           
  • 計算屬性本質就是方法,但是一定要傳回資料。然後頁面渲染時,可以把這個方法當成一個變量來使用。

頁面使用:

<div id="app">
       <h1>您的生日是:{{birth}} </h1>
    </div>
           

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.8.watch

5.8.1.監控

watch可以讓我們監控一個值的變化。進而做出相應的反應。

示例:

<div id="app">
    <input type="text" v-model="message">
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            message:""
        },
        watch:{
            message(newVal, oldVal){
                console.log(newVal, oldVal);
            }
        }
    })
</script>
           

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

5.8.2.深度監控

如果監控的是一個對象,需要進行深度監控,才能監控到對象中屬性的變化,例如:

<div id="app">
    姓名:<input type="text" v-model="person.name"> <br>
    年齡:<input type="text" v-model="person.age"> <button @click="person.age++">+</button> <br>
    <h1>
        {{person.name}}今年{{person.age}}歲了。
    </h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: "#app",
        data: {
            person:{
                name:"Jack",
                age:21
            }
        },
        watch:{
            person:{
                deep: true, // 開啟深度監控,可以監控到對象中屬性變化
                handler(val){ // 定義監控到以後的處理方法
                    console.log(val.name + ": " + val.age);
                }
            }
        }
    })
</script>
           

變化:

  • 以前定義監控時,person是一個函數,現在改成了對象,并且要指定兩個屬性:
    • deep:代表深度監控,不僅監控person變化,也監控person中屬性變化
    • handler:就是以前的監控處理函數

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

6.元件化

在大型應用開發的時候,頁面可以劃分成很多部分。往往不同的頁面,也會有相同的部分。例如可能會有相同的頭部導航。

但是如果每個頁面都獨自開發,這無疑增加了我們開發的成本。是以我們會把頁面的不同部分拆分成獨立的元件,然後在不同頁面就可以共享這些元件,避免重複開發。

6.1.定義全局元件

我們通過Vue的component方法來定義一個全局元件。

<div id="app">
    <!--使用定義好的全局元件-->
    <counter></counter>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    // 定義全局元件,兩個參數:1,元件名稱。2,元件參數
    Vue.component("counter",{
        template:'<button v-on:click="count++">你點了我 {{ count }} 次,我記住了.</button>',
        data(){
            return {
                count:0
            }
        }
    })
    var app = new Vue({
        el:"#app"
    })
</script>
           
  • 元件其實也是一個Vue執行個體,是以它在定義時也會接收:data、methods、生命周期函數等
  • 不同的是元件不會與頁面的元素綁定,否則就無法複用了,是以沒有el屬性。
  • 但是元件渲染需要html模闆,是以增加了template屬性,值就是HTML模闆
  • 全局元件定義完畢,任何vue執行個體都可以直接在HTML中通過元件名稱來使用元件了。
  • data的定義方式比較特殊,必須是一個函數。

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

6.2.元件的複用

定義好的元件,可以任意複用多次:

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

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

你會發現每個元件互不幹擾,都有自己的count值。怎麼實作的?

元件的data屬性必須是函數!

當我們定義這個

<counter>

元件時,它的data 并不是像這樣直接提供一個對象:

data: {
  count: 0
}

           

取而代之的是,一個元件的 data 選項必須是一個函數,是以每個執行個體可以維護一份被傳回對象的獨立的拷貝:

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

如果 Vue 沒有這條規則,點選一個按鈕就會影響到其它所有執行個體!

6.2.局部注冊

一旦全局注冊,就意味着即便以後你不再使用這個元件,它依然會随着Vue的加載而加載。

是以,對于一些并不頻繁使用的元件,我們會采用局部注冊。

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

const counter = {
    template:'<button v-on:click="count++">你點了我 {{ count }} 次,我記住了.</button>',
    data(){
        return {
            count:0
        }
    }
};
           

然後在Vue中使用它:

var app = new Vue({
    el:"#app",
    components:{
        counter:counter // 将定義的對象注冊為元件
    }
})
           
  • components就是目前vue對象子元件集合。
    • 其key就是子元件名稱
    • 其值就是元件對象的屬性
  • 效果與剛才的全局注冊是類似的,不同的是,這個counter元件隻能在目前的Vue執行個體中使用

6.3.元件通信

通常一個單頁應用會以一棵嵌套的元件樹的形式來組織:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化
  • 頁面首先分成了頂部導航、左側内容區、右側邊欄三部分
  • 左側内容區又分為上下兩個元件
  • 右側邊欄中又包含了3個子元件

各個元件之間以嵌套的關系組合在一起,那麼這個時候不可避免的會有元件間通信的需求。

6.3.1.父向子傳遞props

比如我們有一個子元件:

Vue.component("introduce",{
    // 直接使用props接收到的屬性來渲染頁面
    template:'<h3>{{title}}</h3>',
    props:[title] // 通過props來接收一個父元件傳遞的屬性
})
           
  • 這個子元件中要使用title屬性渲染頁面,但是自己并沒有title屬性
  • 通過props來接收父元件屬性,名為title

父元件使用子元件,同時傳遞title屬性:

<div id="app">
    <h1>打個招呼:</h1>
    <!--使用子元件,同時傳遞title屬性-->
    <introduce :title="msg"/>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    Vue.component("introduce",{
        // 直接使用props接收到的屬性來渲染頁面
        template:'<h1>{{title}}</h1>',
        props:['title'] // 通過props來接收一個父元件傳遞的屬性
    })
    var app = new Vue({
        el:"#app",
        data:{
            msg:"大家好,我是虎哥"
        }
    })
</script>
           

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

6.3.2.傳遞複雜資料

我們定義一個子元件:

const myList = {
    template:'\
        <ul>\
        	<li v-for="item in items" :key="item.id">{{item.id}} : {{item.name}}</li>\
        </ul>\
        ',
    props:{ // 通過props來接收父元件傳遞來的屬性
        items:{// 這裡定義items屬性
            type:Array,// 要求必須是Array類型
            default:[] // 如果父元件沒有傳,那麼給定預設值是[]
        }
	}
}
           
  • 這個子元件可以對 items 進行疊代,并輸出到頁面。
  • 但是元件中并未定義items屬性。
  • 通過props來定義需要從父元件中接收的屬性
    • items:是要接收的屬性名稱
      • type:限定父元件傳遞來的必須是數組,否則報錯
      • default:預設值

我們在父元件中使用它:

<div id="app">
    <h2>已開設如下課程:</h2>
    <!-- 使用子元件的同時,傳遞屬性,這裡使用了v-bind,指向了父元件自己的屬性lessons -->
    <my-list :items="lessons"/>
</div>
           
var app = new Vue({
    el:"#app",
    components:{
        myList // 當key和value一樣時,可以隻寫一個
    },
    data:{
        lessons:[
            {id:1, name: 'java'},
            {id:2, name: 'php'},
            {id:3, name: 'ios'},
        ]
    }
})
           

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

6.3.3.子向父的通信

來看這樣的一個案例:

<div id="app">
    <h2>num: {{num}}</h2>
    <!--使用子元件的時候,傳遞num到子元件中-->
    <counter :num="num"></counter>
</div>
<script src="./node_modules/vue/dist/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進行加或減操作

我們嘗試運作:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

好像沒問題,點選按鈕試試:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

子元件接收到父元件屬性後,預設是不允許修改的。怎麼辦?

既然隻有父元件能修改,那麼加和減的操作一定是放在父元件:

var app = new Vue({
    el:"#app",
    data:{
        num:0
    },
    methods:{ // 父元件中定義操作num的方法
        handlePlus(){
            this.num++;
        },
        handleReduce(){
            this.num--;
        }
    }
})
           

但是,點選按鈕是在子元件中,那就是說需要子元件來調用父元件的函數,怎麼做?

我們可以通過v-on指令将父元件的函數綁定到子元件上:

<div id="app">
    <h2>num: {{num}}</h2>
    <counter @plus="handlePlus" @reduce="handleReduce"></counter>
</div>
           

然後,當子元件中按鈕被點選時,調用綁定的函數:

Vue.component("counter", {
    template:`
        <div>
        <button @click="increment">加</button>
        <button @click="decrement">減</button>
        </div>
	`,
    methods:{
        increment(){
            this.$emit("plus");
        },
        decrement(){
            this.$emit("reduce");
        }
    }
})
           
  • vue提供了一個内置的this.$emit函數,用來調用父元件綁定的函數

效果:

Vue入門1.認識Vue2.Node和NPM3.快速入門4.Vue執行個體5.指令6.元件化

子元件不能直接修改父元件傳遞參數的引用或者基本類型參數值。子元件可以修改父元件對象類型參數的屬性