Vue 學(xué)習(xí)歸納

一筹麸、簡介

Vue (讀音 /vju?/耸携,類似于 view) 是一套用于構(gòu)建用戶界面的漸進式框架纵诞。與其它大型框架不同的是忙干,Vue 被設(shè)計為可以自底向上逐層應(yīng)用器予。Vue 的核心庫只關(guān)注視圖層,易于上手捐迫。
Vue 有個特點是響應(yīng)式乾翔,當(dāng)數(shù)據(jù)發(fā)生變化時,視圖會自動響應(yīng)弓乙,元素會匹配新的數(shù)據(jù)末融。
在 JS 中叮贩,需要text = "hello world"; document.getElementById("id").innerHTML = text;才能改變元素的值谨湘;
而 Vue 中侮穿,只需要text = "hello world"安拟,元素的值就會自動改變访诱。
參考了Vue教程Vue API泽示。

二贪染、使用 Vue

  1. 使用html
    需要先使用<script></script>引入Vue壕翩,再在之后的<script></script>中使用new Vue()創(chuàng)建 Vue涂乌。
<body>
        <!-- 最新版本 -->
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <!-- 指定版本 -->
        <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script> -->
        <div id="div">
            
        </div>
        <script type="text/javascript">
            var vm = new Vue({
                el: "#div"
            })
        </script>
    </body>

el: "#div"表示將 Vue 掛載到id = "div"的元素上艺栈。

  1. 使用 main.js
    先使用npm install vue下載 Vue,在 main.js 中使用new Vue()初始化湾盒。
import Vue from 'vue'
import App from './App.vue'

new Vue({
    el: "#app",
    render: h => h(App)
})

App.vue是主頁面湿右,render: h => h(App)表示用主頁面來渲染 Vue,el: "#app"表示將該 Vue 掛載到id="app"的元素上罚勾,該元素一般在 index.html 里毅人。
注:通常使用第二種方式創(chuàng)建 Vue吭狡,界面代碼寫在.vue文件中,通過 Vue Router 跳轉(zhuǎn)界面丈莺。

  1. 使用.vue文件
<template>
    <div>
    </div>
</template>

<script>
    export default {

    }
</script>

<style scoped="scoped">
</style>

.vue文件叫做單文件組件划煮,<template></template>中為 html 語句。要在 div 中寫界面代碼缔俄,不然會報錯弛秋,因為每個組件必須只有一個根元素。
<script></script>中為 JS 語句俐载,export default { }中為 Vue 語句蟹略。
<style></style>中為 CSS 語句,通常添加scoped="scoped"瞎疼,表示樣式只在當(dāng)前組件中生效科乎。
注:后面的介紹語法都是在單文件組件使用的,而不是官方教程那樣在 html 中使用贼急。

三茅茂、模板語法

1、修改文本
使用{{ }}為一個元素添加動態(tài)的內(nèi)容太抓。里面是一個變量空闲,變量為data選項中的key。

<template>
    <div>
        <div>{{ name }}</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                name: "zhangsan",
            };
        }
    }
</script>
  • 表達(dá)式
    {{ }}里面可以使用變量走敌,也可以使用表達(dá)式碴倾。實際上,變量也是表達(dá)式掉丽。
    算術(shù)表達(dá)式跌榔,如{{ name + "lisi" }}
    三元表達(dá)式捶障,如{{ isOk ? "zhangsan" : "lisi" }}僧须,isOk是一個值為布爾的變量。
    函數(shù)表達(dá)式项炼,如{{ name.toUpperCase() }}担平。
  • v-text
    可使用v-text指令來代替{{ }}插值的功能,如<div v-text="name"></div>相當(dāng)于<div>{{ name }}</div>锭部。
  • v-once
    因為 Vue 的響應(yīng)式暂论,當(dāng)變量name的值發(fā)生改變時,div 的內(nèi)容會自動改變拌禾;
    若不想自動改變取胎,可使用v-once指令,如<div v-once>{{ name }}</div>湃窍。
    使用v-once指令后元素/組件及其子元素/組件只會渲染一次扼菠。
  • v-html
    變量的值通常是字符串摄杂、數(shù)字等坝咐,若想使用 html 語句循榆,可使用v-html指令。
<template>
    <div>
        <div v-html="age"></div>
    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                age: "<b>20</b>"
            };
        }
    }
</script>
<style scoped="scoped">
    b {
        color: red;
    }
</style>

修改了 DOM 中的element.innerHTML墨坚。此時相當(dāng)于<div><b>20</b></div>秧饮。
注:scoped的樣式不能應(yīng)用于v-html指令中的元素。如上面的 b 元素字體不會變?yōu)榧t色泽篮。

  • 響應(yīng)式數(shù)據(jù)
    寫在data選項中的數(shù)據(jù)就是響應(yīng)式數(shù)據(jù)盗尸,選項是一個對象或返回對象的函數(shù),可通過this.$data獲取該對象帽撑。
    因為使用的是單文件組件泼各,所以選項必須使用函數(shù)。
    插值時必須使用響應(yīng)式數(shù)據(jù)亏拉,其它全局變量無效扣蜻。
    使用this.$data.age獲取數(shù)據(jù),因為 Vue 實例代理了data選項中的所有變量及塘,所以可使用this.age獲取數(shù)據(jù)莽使。
    有前綴_$的變量不會被 Vue 實例代理,所以只能使用this.$data._age獲取數(shù)據(jù)笙僚。
    • 新增響應(yīng)式數(shù)據(jù)
      若有一個響應(yīng)式數(shù)據(jù)info: { title: "hello" }芳肌,當(dāng)使用this.info.content = "world"給對象添加一個新鍵值對時,該鍵值對并不是響應(yīng)式的肋层,{{ info.content }}是沒有效果的亿笤。
      可使用this.$set()方法為對象新增響應(yīng)式的鍵值對,如this.$set(this.info, "content", "world")栋猖,此時{{ info.content }}才有效果净薛。
      $set()方法有三個參數(shù):
      • 參數(shù)一為一個對象或數(shù)組,必須是響應(yīng)式的掂铐。
      • 參數(shù)二為對象的鍵或數(shù)組的索引罕拂。
      • 參數(shù)三為數(shù)據(jù)的值。
    • 刪除響應(yīng)式數(shù)據(jù)
      使用this.info.title = nullthis.info.title = undefined刪除一個數(shù)據(jù)全陨。
      也可使用this.$delete()方法刪除數(shù)據(jù)爆班,能夠保證 Vue 知道某數(shù)據(jù)被刪除。
      方法有兩個參數(shù)辱姨,與$set()方法的前兩個參數(shù)相同柿菩。
  1. 修改屬性
    在 html 中,通常元素的屬性會賦值為字符串雨涛。使用v-bind指令枢舶,可為屬性綁定一個表達(dá)式懦胞。
<template>
    <div>
        <div v-bind:title="detailAderss">{{ adress }}</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                adress: "cd",
                detailAderss: "成都成華區(qū)"
            };
        }
    }
</script>

鼠標(biāo)指著cd時


v-bind指令可簡寫成:,如<div :title="detailAderss">{{ adress }}</div>凉泄。

  1. 指令
    指令(Directives)是帶有v-前綴的特殊屬性躏尉,如v-bind
    指令的值通常是一個表達(dá)式后众,除了v-for胀糜,如v-bind:title="detailAderss"后面的detailAderss
    指令也有參數(shù)蒂誉,在:后面教藻,如v-bind:title="detailAderss"后面的title就是指令的參數(shù)。
    查看全部指令右锨。
  • 動態(tài)參數(shù)
    使用[]為指令綁定一個變量括堤,變量的值即為指令的參數(shù)。
<template>
    <div>
        <div v-bind:[attName]="detailAderss">{{ adress }}</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                adress: "cd",
                detailAderss: "成都成華區(qū)",
                attName: "title"
            };
        }
    }
</script>

此時相當(dāng)于<div v-bind:title="detailAderss">{{ adress }}</div>绍移。
指令參數(shù)的值通常是一個字符串悄窃,值為null則可以被顯性地用于移除綁定。

  • 修飾符
    使用.為指令添加一個修飾符登夫,修飾符用于指出指令應(yīng)該實現(xiàn)某個功能广匙,如v-on:click.prevent="".prevent修飾符的作用是讓事件對象調(diào)用event.preventDefault()恼策。
    可同時添加多個修飾符鸦致,如v-on:click.prevent.once=""
    不同的指令有不同的修飾符涣楷,查看v-on修飾符分唾。

四、事件

  1. 綁定事件
    在 html 中狮斗,使用<div onclick="clickAction()"></div>來綁定 DOM 事件绽乔。
    在 Vue 中,使用v-on指令綁定 DOM 事件碳褒,如<div v-on:click="clickAction">折砸。

    • 要注意的是,要刪除原事件前面的on沙峻,如onclick -> click睦授。
    • 當(dāng)表達(dá)式是一個函數(shù)調(diào)用時,在 html 中要使用()摔寨,如onclick="clickAction()"去枷。
    • 而在 Vue 中可以不用,但當(dāng)需要傳入?yún)?shù)時,則必須添加()删顶,如v-on:click="clickAction"竖螃、v-on:click="clickAction('a', 'b')"
    • 函數(shù)傳入的參數(shù)可為$event逗余,即為事件對象特咆,如v-on:click="clickAction('a', $event)"

    v-on指令可簡寫成@猎荠,如<div @click="clickAction">坚弱。

<template>
    <div>
        <div @click="clickAction">{{ funName }}</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                funName: "click me"
            };
        },
        methods: {
            clickAction: function(a) {
                alert(event.type +" " + this.$data.funName)
            }
        }
    }
</script>

方法要寫在methods選項中,它是一個對象关摇,而每個方法則是對象中的一組鍵值對。
函數(shù)有兩個寫法碾阁,如clickAction: function() { }输虱、clickAction() { }
若函數(shù)有參數(shù)脂凶,則寫成clickAction: function(a, b) { }宪睹、clickAction(a, b) { }

  • 箭頭函數(shù)
    函數(shù)還有一種寫法是箭頭函數(shù)蚕钦,如clickAction: () => {}亭病、clickAction: (a, b) => {}
    若只有一個參數(shù)嘶居,可省略()罪帖,如clickAction: a => {}
    若函數(shù)里只有一句代碼邮屁,可省略{}整袁,如clickAction: a => alert(a)
    注:在普通函數(shù)中佑吝,this指向 Vue 實例坐昙;但在箭頭函數(shù)中,this不指向任何值芋忿。
  • 可使用對象
    在函數(shù)中炸客,event對象表示函數(shù)的事件對象,this對象則表示當(dāng)前的 Vue 實例戈钢。
    當(dāng)未傳入?yún)?shù)時痹仙,函數(shù)默認(rèn)有一個傳入?yún)?shù),值為事件對象逆趣。
    與 JS 一樣蝶溶,函數(shù)中也能使用arguments對象,arguments[0]表示傳入的第一個參數(shù),arguments[1]表示傳入的第二個參數(shù)抖所,以至類推梨州。
  1. 鍵盤事件
    使用@keydown、@keyup田轧、@keypress綁定鍵盤事件暴匠,分別為按鍵按下、按鍵抬起傻粘、按鍵按下并抬起每窖。
    在 JS 中,在函數(shù)中使用事件對象的keykeyCode屬性判斷按下了哪一個按鍵弦悉;在 Vue 中窒典,使用修飾符判斷按鍵,如<input @keyup.enter=""></input>稽莉,表示在按下回車鍵時觸發(fā)瀑志。
  • 普通按鍵
    修飾符是事件對象的key屬性的值通過kebab-case方式轉(zhuǎn)換而來的,如Enter->enter污秆、ArrowUp->arrow-up劈猪。
    修飾符也可以使用數(shù)字,即事件對象的keyCode屬性的值良拼,如@keyup.enter=""相當(dāng)于@keyup.13=""战得。
    Vue 內(nèi)置了一些修飾符:.enter .tab .delete (刪除或退格鍵) .esc .space .up .down .left .right
<template>
    <div>
        <input @keyup.enter="keyupAction"></input>
    </div>
</template>

<script>
    export default {
        methods: {
            keyupAction: function() {
                alert(event.key + " " + event.keyCode)
            }
        }
    }
</script>

有些舊瀏覽器的keykeyCode的對應(yīng)關(guān)系可能與新的不一致庸推,可以使用全局屬性Vue.config.keyCodes修改常侦,如Vue.config.keyCodes.f1 = 112

  • 粘滯鍵
    在 JS 中予弧,通過事件對象的ctrlKey刮吧、altKey、shiftKey掖蛤、metaKey屬性判斷是否按下了這幾種按鍵杀捻。
    在 Vue 中,使用修飾符.ctrl .alt .shift .meta判斷是否按下蚓庭,如@keyup.shift.enter=""致讥,表示按下shift+enter時觸發(fā)。
    注:在不同系統(tǒng)中器赞,alt垢袱、meta鍵可能不代表的按鍵不同,需要具體測試港柜。
  • 精準(zhǔn)按鍵
    使用修飾符.exact判斷是否精確按下了按鈕请契,如@keyup.shift.enter.exact=""只有在按下shift+enter時觸發(fā)咳榜,按下shitf+alt+enter時不會觸發(fā)。
  1. 鼠標(biāo)事件
    在 JS 中爽锥,使用事件對象的button屬性判斷哪個鼠標(biāo)按鍵被按下涌韩,012分別表示左鍵、中鍵氯夷、右鍵臣樱。
    在 Vue 中,使用修飾符.left .right .middle判斷哪個鼠標(biāo)按鍵被按下腮考,如@click.right=""雇毫。

  2. 綁定多個方法
    v-on指令的值可以是一個對象,可用于綁定多個方法踩蔚,如v-on="{ click: clickAction, dblclick: dblclickAction }"棚放。
    但這種方式不支持修飾符,也不支持給函數(shù)傳入?yún)?shù)寂纪。

五席吴、計算屬性

模板語法插值時,可向里面?zhèn)魅胍粋€表達(dá)式捞蛋,表達(dá)式可為一個變量,可為一個方法柬姚,也可為一個計算屬性拟杉。
<div>{{ name }}</div>name是一個變量量承,值通常是一個簡單的值搬设,如{name: "zhangsan"}
<div>{{ getName() }}</div>撕捍,getName()是一個方法拿穴,可在函數(shù)里實現(xiàn)復(fù)雜的運算,最后返回一個值忧风。

      methods: {
            getName: function() {
                //一系列運算
                return "zhangsan"
            }
        }

<div>{{ getName1 }}</div>默色,getName1是一個計算屬性,也可在里面實現(xiàn)復(fù)雜的運算狮腿,最后返回一個值腿宰。

        computed: {
            getName1: function() {
                //一系列運算
                return "zhangsan"
            }
        }
  1. 計算屬性與方法
    計算屬性與方法實際上都是函數(shù),但方法是寫在methods選項中缘厢,而計算屬性寫在computed選項中吃度,選項是一個對象。
    在調(diào)用方法時贴硫,每調(diào)用一次都會執(zhí)行一次函數(shù)椿每。
    在調(diào)用計算屬性時,只會執(zhí)行一次函數(shù),再次調(diào)用時則使用之前的返回值间护;若函數(shù)中使用的響應(yīng)式變量發(fā)生了變化亦渗,才會重新調(diào)用一次函數(shù)。如computed: { getName1: function() { return this.name.toUpperCase() } }兑牡,只有當(dāng)name的值變化時才會重新執(zhí)行函數(shù)衣撬。
    注:響應(yīng)式變量指的是data選項中的變量。

  2. 何時使用計算屬性
    計算屬性可以節(jié)約系統(tǒng)資源崇堰,當(dāng)使用了一個大數(shù)組時虚青,使用方法則會每次調(diào)用都遍歷一次數(shù)組,而使用計算屬性則只會遍歷一次苞也。

  3. 計算屬性的setter

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[1]
    }
  }
}

執(zhí)行fullName = "Sherlock Holmes"時會調(diào)用set方法洛勉,使firstName和lastName變量更新;由于這兩變量發(fā)生了變化如迟,所以下次使用計算屬性fullName時會重新執(zhí)行一次函數(shù)收毫。

六、偵聽

  1. 偵聽屬性
    響應(yīng)式變量改變時計算屬性會重新調(diào)用一次函數(shù)殷勘,這實現(xiàn)了變量的被動監(jiān)聽此再,但這并不好用。
    而使用偵聽屬性可以實現(xiàn)變量的主動監(jiān)聽玲销。
export default {
        data() {
            return {
                watchProperty: ""
            };
        },
        watch: {
            watchProperty: function(val, oldval) {
                alert("新值為" + val + "输拇,舊值為" + oldval)
            }
        }
}

偵聽屬性需要寫在watch選項中,選項是一個對象贤斜。
對象鍵值對的值可以是一個函數(shù)策吠,函數(shù)會傳入兩個參數(shù),參數(shù)為變量的新值和舊值瘩绒。
還可以是字符串猴抹、數(shù)組、對象锁荔,詳見watch蟀给。

  • 實例方法
    除了寫在watch選項中,還可以使用實例方法this.$watch()堕战。
    $watch()一般寫在mounted選項中坤溃,選項是一個函數(shù),它會在 Vue 實例被掛載后調(diào)用嘱丢。
<script>
    export default {
        data: function() {
            return {
                message: "message"
            }
        },
        mounted: function() {
            this.$watch("message", function(newVal, oldVal) {
                alert(newVal+" "+oldVal)
            }, {})
        }
    }
</script>

$watch()有三個參數(shù):

  • 參數(shù)一是一個表達(dá)式或函數(shù)薪介。
    • 表達(dá)式通常是一個變量,會監(jiān)聽變量值是否發(fā)生了變化越驻。若要監(jiān)聽對象中的鍵值對汁政,可使用表達(dá)式a.b.c道偷。
    • 為函數(shù)時,會監(jiān)聽函數(shù)的返回值是否發(fā)生了變化记劈。
  • 參數(shù)二是一個回調(diào)函數(shù)勺鸦,會在監(jiān)聽的值發(fā)生變化時回調(diào)。函數(shù)有兩個參數(shù)目木,分別為新值與舊值换途。
  • 參數(shù)三是一個對象,可使用兩個鍵deep刽射、immediate军拟,它們都是布爾值。
    • deep為true誓禁,當(dāng)監(jiān)聽一個對象時懈息,對象中任意鍵值對變化,就能觸發(fā)回調(diào)摹恰。為數(shù)組時不需這樣設(shè)置辫继。
    • immediate為true,會立即觸發(fā)一次回調(diào)函數(shù)俗慈。
  • $watch()有一個返回值姑宽,返回值是一個函數(shù),調(diào)用這個函數(shù)能取消監(jiān)聽闺阱。
    var unwatch = this.$watch("message", function() {});unwatch();低千。
  1. 偵聽事件
    通常,在組件上使用$emit()觸發(fā)一個自定義事件馏颂,在父組件上使用v-on指令監(jiān)聽這個事件。詳見 十一棋傍、組件 -- 3. 事件方法救拉。
    那么,在本組件中怎么監(jiān)聽由$emit()觸發(fā)的自定義事件呢瘫拣?可以使用實例方法this.$on()實現(xiàn)亿絮。
<template>
    <div>
        <div @click="$emit('tap')">title</div>
    </div>
</template>

<script>
    export default {
        mounted: function() {
            this.$on("tap", function() {
                alert(123)
            })
        }
    }
</script>

$on()一般寫在mounted選項中,選項是一個函數(shù)麸拄,它會在 Vue 實例被掛載后調(diào)用派昧。
$on()有兩個參數(shù):

  • 參數(shù)一為一個字符串或數(shù)組。
    • 字符串為$emit()觸發(fā)的事件名拢切。
    • 數(shù)組為多個事件名組成的數(shù)組蒂萎。
  • 參數(shù)二為回調(diào)函數(shù),回調(diào)函數(shù)會接收所有$emit()觸發(fā)函數(shù)的參數(shù)淮椰。

$on(eventName, eventHandler) 偵聽一個事件
$once(eventName, eventHandler) 一次性偵聽一個事件五慈,事件名不支持?jǐn)?shù)組纳寂。
$off(eventName, eventHandler) 停止偵聽一個事件

七、class與style的綁定

在 html 中泻拦,通過<div class="class1 class2" style="width: 100px;height: 30px;"></div>來綁定元素的 CSS 類名和樣式毙芜。
在 Vue 中,則使用v-bind指令動態(tài)地綁定類名或樣式争拐。

  1. 對象語法
    v-bind指令可為屬性綁定一個變量腋粥,當(dāng)屬性為classstyle時,這個變量可以是一個對象架曹。
  • 變量寫法
    • class
      <div :class="classObject"></div>隘冲,變量classObject為classObject: { class1: true, class2: true , class3: flase }。此時相當(dāng)于<div class="class1 class2"></div>音瓷。
    • style
      <div :style="styleObject"></div>对嚼,變量styleObject為styleObject: { color: 'red', fontSize: '16px' }。此時相當(dāng)于<div style="color: red;font-size: 16px;"></div>绳慎。
      在對象中纵竖,font-size要寫成駝峰式fontSize,也可以寫成'font-size'杏愤。
  • 內(nèi)聯(lián)寫法
    • class
      <div :class="{ class1: enable1, class2: enable2, class3: enable3 }"></div>靡砌,變量為enable1: true, enable2: true, enable3: false。此時也相當(dāng)于<div class="class1 class2"></div>珊楼。
    • style
      <div :style="{color: color, fontSize: size}"></div>通殃,變量為color: 'red', size: '16px'。此時也相當(dāng)于<div style="color: red;font-size: 16px;"></div>厕宗。
      font-size要寫成駝峰式fontSize画舌,也可以寫成'font-size'
  • 使用計算屬性
    變量不僅可以是一個對象已慢,也可以是計算屬性曲聂。
<template>
    <div>
        <div v-bind:class="classObject"></div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                pageIndex: 5
            }
        },
        computed: {
            classObject: function() {
                return {
                    class1: this.pageIndex%3 == 0,
                    calss2: this.pageIndex%3 == 1,
                    calss3: this.pageIndex%3 == 2
                }
            }
        }
    }
</script>

變量為計算屬性時,可以通過一系列判斷后再返回對象佑惠。上面的作用是根據(jù)pageIndex來使用不同的類名朋腋。
當(dāng)然,style也可以像上面一樣使用計算屬性膜楷。

  1. 數(shù)組語法
    v-bind指令可為屬性綁定一個變量旭咽,當(dāng)屬性為classstyle時,這個變量可以是一個數(shù)組赌厅。
  • 變量寫法
    <div :class="classArray"></div>穷绵,變量classArray為classArray: ['class1', 'class2']。此時相當(dāng)于<div class="class1 class2"></div>察蹲。
    與對象語法一樣请垛,變量也可以是一個計算屬性催训,不同點在于返回值是一個數(shù)組。
  • 內(nèi)聯(lián)寫法
    • class
      <div :class="['class1', 'class2']"></div>宗收。
      <div :class="[className, className2]"></div>漫拭,變量為className1: "class1", className2: "class2"
      <div :class="[isok1 ? 'class1' : '', {class2: isok2}]"></div>混稽,變量為isok1: true, isok2: true采驻。
      上面三種都相當(dāng)于<div class="class1 class2"></div>
    • style
      <div :style="[colorstyle, fontstyle]"></div>匈勋,變量為colorstyle: { color: 'red' }, fontstyle: { fontSize: '16px' }礼旅,相當(dāng)于<div style="color: red;font-size: 16px;"></div>
      font-size要寫成駝峰式fontSize洽洁,也可以寫成'font-size'痘系。

注:使用v-bind指令時,Vue 會在 CSS 屬性前自動添加上各種瀏覽器的前綴饿自。

八汰翠、條件渲染

  1. v-if
    與 JS 中的if、else if昭雌、else一樣复唤,在 Vue 中也能通過指令v-if、v-else-if烛卧、v-else來條件渲染不同的元素佛纫。
    三個指令的值都是一個表達(dá)式,且表達(dá)式的結(jié)果應(yīng)該是一個布爾值总放。
    必須按順序書寫呈宇,在一組元素中,帶有v-else-if指令的元素可存在零個或多個局雄,帶有v-else指令的元素可存在至多一個攒盈。
<template>
    <div>
        <div v-if="show1">if</div>
        <div v-else-if="show2">else if</div>
        <div v-else>else</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                show1: true,
                show2: true
            }
        }
    }
</script>

當(dāng)show1為true,渲染第一個div哎榴;當(dāng)show1為false,show2為true僵蛛,渲染第二個div尚蝌;當(dāng)都為false,渲染最后一個div充尉。

  • template
    當(dāng)需要條件渲染多個元素時飘言,可以使用 template。
    <div v-if="show1"><div>1</div><div>2</div></div>驼侠,當(dāng) show1 改變時姿鸿,實際上是切換最外層帶有v-if指令的這個 div谆吴,只不過是該div中有兩個子div。
    若想同時切換多個元素苛预,可將最外層改成 template句狼,如<template v-if="show1"><div>1</div><div>2</div></template>,此時實際上是在切換里面的兩個div热某。
  • 元素的復(fù)用
<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" />
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" />
</template>

Vue 會盡可能高效地渲染元素腻菇,通常會復(fù)用已有元素而不是從頭開始渲染。
上面例子的 label 元素和 input 元素在切換時昔馋,實際上是修改 label 元素的內(nèi)容和 input 元素的占位符筹吐。

若在輸入框中輸入了字符串,你會發(fā)現(xiàn)在切換時字符串并不會變化秘遏。
但這種情況有時并不符合要求丘薛。給需要重新渲染的元素設(shè)置不同的key值,就能解決這個問題邦危。

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email">
</template>

此時 laebl 元素會復(fù)用洋侨,input 元素會重新渲染。

  1. v-show
    使用v-show指令也可以實現(xiàn)條件渲染铡俐,如<div v-show="show">show</div>凰兑。
    v-show指令的值也是一個表達(dá)式,表達(dá)式的結(jié)果是一個布爾值审丘。
    結(jié)果為true則顯示吏够,為false則不顯示,實際上是將元素的CSS切換成display: none滩报。

v-if在初始渲染時條件為假時什么也不做锅知;直到條件第一次變?yōu)檎鏁r,才會開始渲染脓钾。v-show不管初始條件是什么售睹,元素都會被渲染。
v-if有更高的切換開銷可训,而v-show有更高的初始渲染開銷昌妹。因此,如果要頻繁地切換握截,則使用v-show較好飞崖。
v-if支持 template 元素,而v-show則不支持谨胞。

九固歪、循環(huán)渲染

在 JS 中,使用for來循環(huán)執(zhí)行代碼胯努;在 Vue 中牢裳,可以使用v-for指令來循環(huán)渲染元素逢防。
通常,指令的值都是一個表達(dá)式蒲讯,而v-for指令的值為alias in expression忘朝。
其中expression的值可為數(shù)組、對象伶椿、數(shù)字辜伟、字符串、Iterable(詳見迭代協(xié)議)脊另。

  • 在v-for中使用數(shù)組
    v-for指令的值為item in items导狡,itemsdata選項中的變量,是一個數(shù)組偎痛;item則是數(shù)組的元素旱捧,通常是一個對象。
<template>
    <div>
        <div v-for="item in items" :key="item.id">{{item.content}}</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                items: [
                    {
                        id: "id1",
                        content: "item1"
                    },
                    {
                        id: "id2",
                        content: "item2"
                    }
                ]
            }
        }
    }
</script>

v-for指令的值還可以為"item,index in items"踩麦,index為元素的索引枚赡。
in可以替換成of,如item of items谓谦、"item,index of items"

  • 在v-for中使用對象
    v-for指令的值為value in object贫橙,objectdata選項中的變量,是一個對象反粥,value為對象的鍵值對的值卢肃。
    v-for指令的值還可以為value,key in objectvalue,key,index in objectkey為對象的鍵值對的鍵才顿,index為索引莫湘。
    in也可以替換成of
    注:遍歷對象時郑气,會按Object.keys()的結(jié)果遍歷幅垮。
  • 在v-for中使用數(shù)字
    v-for指令的值為num in 10,則會重復(fù)對應(yīng)次數(shù)尾组。
  • 在v-for中使用字符串
    v-for指令的值為charStr in 'string'忙芒,則會重復(fù)字符串長度的次數(shù),charStr為每一個字符讳侨。
    v-for指令的值了也可為charStr,index in 'string'匕争,index為索引值。
  • 使用key
    當(dāng)更新使用v-for指令渲染的元素列表時爷耀,它默認(rèn)使用 就地更新 的策略。如果數(shù)據(jù)項的順序被改變拍皮,Vue 不會移動 DOM 元素來匹配數(shù)據(jù)項的順序歹叮,而是就地更新每個元素跑杭,并且確保它們在每個索引位置正確渲染。
    為了重用和重新排序現(xiàn)有元素咆耿,可以給每項提供一個key屬性德谅,如<div v-for="item in items" :key="item.id">{{item.content}}</div>
    注:
    key的值應(yīng)該是一個字符串或數(shù)字萨螺,并且值不能夠重復(fù)窄做。
    在組件上使用v-for指令時,key是必須的慰技。如<custom v-for="item in items" :key="item.id"></custom>椭盏。
  • 使用template
    v-for指令可以用在 template 元素上,如<template v-for="item in items" :key="item.id"><div>{{ item.id }}</div><div>{{ item.content }}</div></template>吻商。
    v-if指令一樣掏颊,當(dāng)需要循環(huán)渲染多個元素,可以使用 template艾帐。
  • v-for與v-if
    當(dāng)兩個指令同時使用時乌叶,如<div v-for="item in items" v-if="show" :key="item.id">{{item.content}}</div>
    v-for指令的優(yōu)先級比v-if指令高柒爸,即先遍歷再判斷准浴。
    注:Vue 不推薦這兩個指令組合使用。

十捎稚、表單綁定

在 html 中乐横,給一個輸入框設(shè)定初始值,如<input value="hello"></input>阳藻。
當(dāng)在輸入框修改值后晰奖,實際上value的值并沒有改變⌒饶啵可以監(jiān)聽oninput事件匾南,在函數(shù)使用element.setAttribute()來改變value的值。
在 Vue 中蛔外,使用v-model指令來實現(xiàn)雙向綁定蛆楞,實際上也是通過監(jiān)聽輸入事件以更新數(shù)據(jù)。

v-model指令針對不同類型的 input 元素使用不同的值與事件夹厌。
text 和 textarea 使用 value 屬性和 input 事件豹爹;
checkbox 和 radio 使用 checked 屬性和 change 事件;
select 使用 value 屬性和 input 事件矛纹。

  • 使用v-model
    <input v-model="inputValue"></input>
    inputValuedata選項中的一個變量臂聋,必須設(shè)置初始值,即使是一個""
    checkbox 綁定的值是一個數(shù)組或布爾孩等,radio 綁定的值是一個布爾仁连,其他類型綁定的值則是一個字符串倘是。
  • 修飾符
    text 和 textarea 綁定的值默認(rèn)在input事件中更新喊递,使用.lazy修飾符砸狞,使其在change事件中更新,如<input v-model.lazy="inputValue"></input>权她。
    text 和 textarea 綁定的值默認(rèn)是字符串虹茶,使用.number修飾符,可以讓綁定的值變?yōu)閿?shù)字隅要,如<input v-model.number="age" type="number"></input>蝴罪。
    使用.trim修飾符,可以自動去除字符串前后的空格拾徙,如<input v-model.trim="inputValue"></input>洲炊。

十一、組件

組件是可復(fù)用的 Vue 實例尼啡,.vue文件就是一個單文件組件暂衡。

  1. 使用組件
<template>
    <div>
        <CustomComponent></CustomComponent>
        <Custom-Component></Custom-Component>
        <custom-component></custom-component>
        
        <CustomComponent1></CustomComponent1>
        <custom-component1></custom-component1>

        <custom-component2></custom-component2>
    </div>
</template>

<script>
    import CustomComponent from './CustomComponent.vue'
    export default {
        components: {
            CustomComponent,
            CustomComponent1: {
                template: "<div>1234</div>",
                data: function() {
                    return {}
                }
            }
            'custom-component2': {
                template: "<div>1234</div>",
            }
        }
    }
</script>

可使用import引入其他的.vue文件,如組件CustomComponent崖瞭;也可以在當(dāng)前文件中直接創(chuàng)建組件狂巢,如組件CustomComponent1。
組件要寫在components選項中书聚,選項是一個對象唧领。當(dāng)對象的鍵值對的鍵值相同時,可以省略值雌续,如{ CustomComponent }相當(dāng)于{ CustomComponent: CustomComponent }斩个。

使用組件時,可以使用大駝峰CustomComponent驯杜,也可以使用分隔式Custom-Component受啥,也可以使用小寫分隔式custom-component,建議使用小寫分隔式鸽心,如<custom-component></custom-component>滚局。
若注冊組件時就使用的小寫分隔式(此時兩端要加引號),如'custom-component2'顽频,使用時也就只能使用小寫分隔式藤肢。

  • 全局組件
    上面的組件只能在當(dāng)前文件中使用,可使用Vue.component('name', {})注冊全局組件糯景。要注意的是嘁圈,必須寫在new Vue({})之前省骂。
  1. 組件屬性
    每個元素都有屬性,自定義的組件在props選項中聲明自定義屬性最住,可使用this.$props獲取選項的值冀宴。
    props選項中聲明的屬性可以像data選項中的變量一樣,直接在組件中使用温学。
<template>
    <div>
        <h1>{{ title }}</h1>
        <p>{{ content }}</p>
    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                title: "component"
            }
        },
        props: ['content']
    }
</script>

組件的data選項必須為一個函數(shù),它返回一個對象甚疟。這樣可以保證每個組件實例有只屬于自己的數(shù)據(jù)仗岖。

  • 使用屬性
    通過<custom-component content="message"></custom-component>使用自定義的屬性,當(dāng)然也可以使用:content=""為屬性綁定一個表達(dá)式览妖。
    <custom-component content></custom-component>轧拄,表示content的值為true。

  • v-bind
    當(dāng)組件中聲明的屬性很多時讽膏,如果都使用的話代碼就會很長檩电,如<custom-component name="" age="" adress="" phone=""></custom-component>
    使用v-bind指令可將所有屬性集中在一個對象中府树,如<custom-component v-bind="datas"></custom-component>俐末,變量為datas: { name: "", age: "", adress: "", phone: "" }

  • sync
    上面不管是:content=""還是v-bind=""綁定變量時奄侠,都是單向的卓箫。當(dāng)組件內(nèi)的屬性值改變時,不會改變父組件變量的值垄潮。
    若要進行雙向綁定烹卒,可使用.sync修飾符,如:content.sync=""弯洗、v-bind.sync=""旅急。
    注:.sync修飾符只支持變量,不支持表達(dá)式牡整。

  • 屬性命名
    自定義的屬性通常使用小駝峰命名藐吮,在使用時,可使用小駝峰或分隔式果正,如<custom-component contentValue=""></custom-component>炎码、<custom-component content-value=""></custom-component>

  • prop選項的類型
    prop選項可為數(shù)組或?qū)ο蟆?/p>

    • 為數(shù)組時秋泳,如props: ['title', 'likes', 'isPublished']潦闲。
    • 為對象時,如props: { title: String, likes: Number, isPublished: Boolean}迫皱。
      • 對象鍵值對的值為數(shù)據(jù)類型歉闰,可使用String辖众、Number、Boolean和敬、Array凹炸、Object、Date昼弟、Function啤它、Symbol
      • 也支持構(gòu)造函數(shù)舱痘,如function Person (firstName, lastName) { this.firstName = firstName;this.lastName = lastName }变骡,通過props: { person: Person}來使用。
  • props類型驗證
    當(dāng)props選項為對象時:

    • 可讓一個屬性支持一種數(shù)據(jù)類型芭逝,如title: String塌碌。
    • 也可支持多種數(shù)據(jù)類型,如title: [String, Number]旬盯。
    • 鍵值對的值也可以是一個對象台妆,如title: { type: String },相當(dāng)于title: String
      這個對象有多種鍵:
      • type表示屬性的數(shù)據(jù)類型胖翰,如title: { type: String }接剩。
      • required表示屬性是否必填,如title: { type: String, required: true }泡态。
      • default表示默認(rèn)值搂漠,如title: { type: String, default: "標(biāo)題" }
        若數(shù)據(jù)類型為數(shù)組或?qū)ο竽诚遥仨毷褂煤瘮?shù)桐汤,如title: { type: Array, default: function() { return [] } }
      • validator表示驗證函數(shù)靶壮,如title: {type: String, validator: function(value) { return value.length > 6 } }怔毛,表示title的值的字符長度必須大于6。

    注:props選項中的屬性會在組件實例創(chuàng)建之前進行驗證腾降,所以實例thisdefaultvalidator的函數(shù)中是不可用的拣度。

  • 使用非props的屬性
    <custom-component title=""></custom-component>
    若組件中并沒有聲明title屬性,使用時螃壤,Vue 會將title自動添加到組件的根元素上抗果。若根元素上已經(jīng)設(shè)定了該屬性,會被覆蓋奸晴。但style冤馏、class會發(fā)生合并。
    若想讓未聲明的屬性不自動添加到組件的根元素上寄啼,需要設(shè)置inheritAttrs選項為false逮光。
    該選項并不會影響class代箭、style的合并。

<script>
    export default {
        inheritAttrs:false
    }
</script>

使用$attrs屬性可獲取所有已使用且未在props中聲明的屬性涕刚,它是一個對象嗡综,里面不包括class、style杜漠。

<template>
    <div>
        <div val1="$attrs['val1']"></div>
        <div val2="$attrs['val2']"></div>
        <div v-bind="$attrs"></div>
        <div>{{ $attrs["val1"] }}</div>
    </div>
</template>

<script>
    export default {
    }
</script>

使用<custom-component val1="" val2=""></custom-component>設(shè)置未聲明的屬性极景,在組件中也可使用$attrs屬性來實現(xiàn)props的功能,但不推薦驾茴。

  1. 事件方法
    每個元素都有事件方法戴陡,自定義組件中使用實例方法$emit()來聲明自定義方法。
<template>
    <div>
        <h1 @click="$emit('tap', 1, 2)">{{ title }}</h1>
        <p>{{ content }}</p>
    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                title: "component"
            }
        },
        props: ['content']
    }
</script> 

<h1 @click="$emit('tap', 1, 2)">{{ title }}</h1>的功能是沟涨,當(dāng)點擊 h1 元素時,觸發(fā)一個名為 tap 的事件异吻,并為事件提供了兩個參數(shù)1和2裹赴;$emit中事件名必須的。
當(dāng)然诀浪,也可以將$emit()寫在@click="clickAction"綁定的函數(shù)中棋返。

父組件通過<custom-component @tap="tapAction"></custom-component>來監(jiān)聽 tap 事件,并通過tapAction: function(val1, val2) { }使用這兩個參數(shù)雷猪,或在函數(shù)中通過arguments[0]睛竣、arguments[1]使用這兩參數(shù)。

  • native
    在組件上監(jiān)聽原生事件時求摇,如<custom-component @click="clickAction"></custom-component>射沟,會發(fā)現(xiàn)點擊時并不會調(diào)用 clickAction 函數(shù),因為只能監(jiān)聽$emit()觸發(fā)的事件与境。
    為了能順利調(diào)用函數(shù)验夯,需要使用.native修飾符,如@click.native="clickAction"摔刁。
  • listeners
    .native修飾符可以監(jiān)聽根元素上的原生事件挥转,若根元素是一個div,監(jiān)聽的事件是input共屈,這當(dāng)然不會有作用绑谣。
    可以使用$listeners屬性獲取所有v-on指令綁定的事件(不包括.native修飾符的事件)。
    這樣就能將父組件要監(jiān)聽的input事件綁定到子組件的 input 元素上拗引,如<input v-on:input="$listeners.input"></input>借宵。
    也可以將所有事件都綁定到 input 元素上,如<input v-on="$listeners"></input>寺擂。
  1. 組件使用v-model
    使用v-model指令時暇务,text 和 textarea 綁定的是 value 屬性 和 input 事件泼掠,相當(dāng)于<input :value="text" @input="text = $event.target.value">
    組件也能使用v-model指令垦细,也默認(rèn)綁定 value 屬性與 input 事件择镇,相當(dāng)于<custom-component :value="text" @input="text = $event">
    在 input 元素中括改,$event表示事件對象腻豌;而在組件中,$event表示$emit()的第二個參數(shù)嘱能。
  • 更改默認(rèn)
    組件使用v-model指令時默認(rèn)綁定valueinput事件吝梅,可使用model選項更改默認(rèn)值。
    選項是一個對象惹骂,對象有兩個鍵prop苏携、event,分別為要綁定的屬性和事件对粪。
<script>
    export default {
        model: {
            prop: "content",
            event: "change"
        },
        props: ['content']
    }
</script>

此時變更為綁定content屬性與change事件右冻。

  1. 插槽
    html 元素大都可以通過<div>message</div>在開始和結(jié)束標(biāo)簽中添加內(nèi)容。
    而對于組件著拭,<custom-component>message</custom-component>標(biāo)簽中的內(nèi)容是沒有任何效果的纱扭。
    為了使添加的內(nèi)容生效,可以使用 slot 元素儡遮。
<template>
    <div>
        <h1 @click="$emit('tap', 1, 2)">{{ title }}</h1>
        <slot></slot>
        <p>{{ content }}</p>
    </div>
</template>

此時乳蛾,<custom-component>message</custom-component>標(biāo)簽中的message就會替換到<slot></slot>的位置。

  • 默認(rèn)值
    <slot></slot>中添加默認(rèn)值鄙币,如<slot>hello</slot>肃叶,那么當(dāng)<custom-component></custom-component>時,就相當(dāng)于<custom-component>hello</custom-component>十嘿。
  • 具名插槽
    有時候被环,我們可能需要添加多個插槽,它們在組件的不同位置详幽。
    這時需要使用插槽的name屬性筛欢。
<template>
    <div>
        <slot name="a"></slot>
        <slot></slot>
        <slot name="b"></slot>
    </div>
</template>

<slot></slot>是一個默認(rèn)插槽,name默認(rèn)為default唇聘,相當(dāng)于<slot name="default"></slot>版姑。

<custom-component2>
            <div>default</div>
            <template v-slot:a>aaa</template>
            <template v-slot:b>bbb</template>
        </custom-component2>

使用時具名插槽的內(nèi)容必須寫在 template 元素中,通過v-slot指令的參數(shù)來匹配插槽的名字迟郎。
若為默認(rèn)插槽剥险,可省略<template v-slot:default></template>


內(nèi)容顯示的順序只與組件中各插槽的順序有關(guān)宪肖。

  • 簡寫
    v-bind表制、v-on指令可以簡寫成: @一樣健爬,v-slot指令可以簡寫成#,如<template v-slot:default></template>簡寫成<template #default></template>么介。
  • 作用域插槽
    通常娜遵,給插槽添加內(nèi)容時,都是使用當(dāng)前文件中的數(shù)據(jù)壤短。如<custom-component2>{{ value }}</custom-component2>设拟。
    但組件內(nèi)部也提供了許多數(shù)據(jù)給外面的插槽使用,使用v-slot指令來獲取組件提供的數(shù)據(jù)久脯。
<template>
    <div>
        <slot name="a"></slot>
        <slot age="20" v-bind:adress="adressV"></slot>
        <slot name="b"></slot>
    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                adressV: "cd"
            }
        }
    }
</script>

在插槽 slot 上添加屬性 age 和 adress纳胧,也可使用v-bind指令為屬性綁定一個表達(dá)式。

<custom-component2>
            <template v-slot:default="value">
                {{ value }}
            </template>
        </custom-component2>

v-slot:default="value"表示給name="default"的插槽(即默認(rèn)插槽)提供一個變量 value帘撰。
插槽就能夠使用變量 value 的數(shù)據(jù)跑慕,而 value 的值為{ "age": "20", "adress": "cd" },即在 slot 上添加的屬性與屬性值摧找。
若只有默認(rèn)插槽相赁,有另一種寫法,如<custom-component2 v-slot="value">{{ value }}</custom-component2>

  • 使用部分?jǐn)?shù)據(jù)
    上面 value 的值是一個對象{ "age": "20", "adress": "cd" }慰于,若想只返回對應(yīng)屬性的值,可寫成v-slot:default="{age: a, adress: b}"唤衫,這時a為20婆赠,b為cd。
    因為當(dāng)對象中的鍵值相同時可以省略值佳励,所以可以寫成v-slot:default="{age, adress}"休里,相當(dāng)于v-slot:default="{age: age, adress: adress}",這時age為20赃承,adress為cd妙黍。
  • 動態(tài)插槽名
    和其他指令一樣,可以使用[]為指令設(shè)定動態(tài)的參數(shù)瞧剖,而v-slot的參數(shù)即表示插槽名拭嫁。如v-slot:[name]="value"{ name: 'default' }時相當(dāng)于v-slot:default="value"抓于。
  1. 動態(tài)組件
    使用 component 元素和is屬性來使用動態(tài)組件做粤。
    <component is="custom-component"></component>相當(dāng)于<custom-componen></custom-componen>,通常使用v-bind:is=""綁定一個變量捉撮,就可以改變變量的值來切換不同的組件怕品。
    除了使用組件,也可以用在普通的 html 元素上巾遭,如<component is="div"></component>肉康。
  • 贝彻溃活組件
    動態(tài)組件通常用于多標(biāo)簽欄切換界面。你會發(fā)現(xiàn)吼和,切換不同界面時界面都會重置涨薪;這是因為在切換時,Vue 都會創(chuàng)建一個新的組件實例纹安。
    但有時候尤辱,我們希望創(chuàng)建的組件能緩存下來,可以使用 keep-alive 元素厢岂,如<keep-alive><component :is="componentName"></component></keep-alive>光督。
    在不同組件同切換時,組件中的activateddeactivated這兩個生命周期鉤子函數(shù)會執(zhí)行塔粒,組件的子組件中的這兩個鉤子函數(shù)也會執(zhí)行结借。
    keep-alive 元素有三個屬性:

    • include 字符串或正則表達(dá)式,名稱匹配的組件會被緩存卒茬。
      名稱為組件name選項的值或父組件components選項的鍵值對的鍵船老。
    • exclude 字符串或正則表達(dá)式。名稱匹配的組件不會被緩存圃酵。
    • max 數(shù)字柳畔。最多可以緩存多少組件實例,數(shù)字達(dá)到了郭赐,會釋放最久沒有訪問的實例薪韩。

    注:keep-alive 元素只能用在有一個子組件的情形;若子組件使用了v-for捌锭,keep-alive 元素也沒有效果俘陷。

  1. 異步組件
    通常,我們都是在本地創(chuàng)建組件观谦,然后在本地直接使用組件拉盾。
    有時候,組件的代碼在服務(wù)器端豁状,則需要先從服務(wù)器獲取組件代碼捉偏,這時就要使用異步組件。
        components: {
            ServiceComponent: function(resolve, reject) {
                var http = new XMLHttpRequest()
                http.onreadystatechange = function() {
                    if (http.readyState == 4&&http.status == 200) {
                        const component = {
                            template: http.responseText
                        }
                        resolve(component)
                    } else {
                        reject("組件獲取失敗")
                    }
                }
                http.open("GET", "http_url", true)
                http.send()
            }
        }

Vue 允許你以一個函數(shù)的方式定義你的組件泻红,這個函數(shù)會異步解析你的組件告私。
Vue 只有在這個組件需要被渲染的時候才會觸發(fā)該函數(shù),且會把結(jié)果緩存起來供以后再次渲染承桥。
函數(shù)有兩個回調(diào)參數(shù)驻粟,調(diào)用resolve()表示組件加載成功,調(diào)用reject()表示組件加載失敗,

  1. 訪問子組件
    使用ref屬性為元素或子組件注冊引用信息蜀撑,如<custom-component ref="custom"></custom-component>挤巡。
    再使用$refs引用就會指向子組件的實例,如this.$ref.custom酷麦。
    若用在 html 元素上矿卑,引用就會指向 DOM 元素。
    注:$refs 只會在組件渲染完成之后生效沃饶,并且它不是響應(yīng)式的母廷。應(yīng)該避免在 template 或計算屬性中訪問它。

  2. 訪問父組件
    使用$parent可訪問父組件的實例糊肤,如this.$parent琴昆。

  • 依賴注入
    子組件不應(yīng)該主動訪問父組件的實例,可以使用provide馆揉、inject選項來依賴注入业舍,讓子組件能訪問父組件提供的數(shù)據(jù)或方法。
    在父組件中使用provide選項提供數(shù)據(jù)升酣,它是一個對象或返回對象的函數(shù)舷暮,如provide: {age: this.age};
    在子組件中使用inject選項接收數(shù)據(jù),它是一個對象或數(shù)組噩茄,如inject: ['age']下面。
    這樣就能在子組件中通過age來使用父組件中的this.age琳骡。

相比$parent來說豌注,依賴注入可以讓我們在任意后代組件中訪問數(shù)據(jù)颇蜡,而不需要暴露整個父組件實例祟蚀。
后代組件不需要知道被注入的數(shù)據(jù)來自哪里。
父組件不需要知道哪些后代組件使用了它提供的數(shù)據(jù)钉稍。
注入的數(shù)據(jù)是非響應(yīng)式的。

十二、過渡

使用 transition 元素蓄髓,給其他元素或組件添加進入、離開過渡/動畫效果舒帮。
將要過渡/動畫的元素放在 transition 中会喝,如<transition name=""><div></div></transition>
然后在CSS類名中添加過渡/動畫效果。

  1. 類名
    在進入/離開的過渡中玩郊,會有6個類名切換肢执。
    v-enter定義進入過渡/動畫的開始狀態(tài)。在元素插入之前生效译红,在元素插入之后的下一幀移除预茄。為動畫時會在animationend事件觸發(fā)時移除。
    v-enter-active定義進入過渡/動畫生效時的狀態(tài)。在這里設(shè)定進入過渡/動畫的過程時間耻陕、延遲和曲線函數(shù)拙徽。
    v-enter-to定義進入過渡/動畫的結(jié)束狀態(tài)。在元素插入之后下一幀生效 (v-enter移除之時)诗宣,在過渡/動畫完成之后移除膘怕。
    v-leave定義離開過渡/動畫的開始狀態(tài)。在元素刪除之前生效召庞,在元素刪除之后的下一幀移除岛心。為動畫時會在animationend事件觸發(fā)時移除。
    v-leave-active定義離開過渡/動畫生效時的狀態(tài)篮灼。被用來定義離開過渡/動畫的過程時間忘古、延遲和曲線函數(shù)。
    v-leave-to定義離開過渡/動畫的結(jié)束狀態(tài)穿稳。在元素刪除之后的下一幀生效 (v-leave移除之時)存皂,在過渡/動畫完成之后移除。

    前面的v表示 transition 元素的name的值逢艘,如<transition name="div"></transition>時使用div-enter-active旦袋。
    當(dāng)沒有設(shè)置name時,默認(rèn)使用v它改。


    v-enter-active表示元素插入疤孕、執(zhí)行過渡/動畫、過渡/動畫結(jié)束這三個階段央拖。
    v-enter-active = v-enter + v-enter-to祭阀,大概相當(dāng)于v-enterv-enter-active的前1%,v-enter-to占后面99%鲜戒。
    v-leave-activev-enter-active類同专控。

<template>
    <div>
        <button @click="show = !show">switch</button>
        <transition name="div">
            <div v-if="show">animation</div>
        </transition>
        <transition name="div1">
            <div v-if="show">transtion</div>
        </transition>
    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                show: true
            }
        }
    }
</script>

<style>
    /* 過渡 */
    .div1-enter-active, .div1-leave-active {
      transition: all 1s ease;
    }
    /* 設(shè)置進入過渡執(zhí)行前或離開過渡執(zhí)行后的CSS,通常這兩個時間點CSS相同 */
    .div1-enter, .div1-leave-to  {
      opacity: 0;
      transform: translateX(60px);
    }
    
    /* 動畫 */
    .div-enter-active {
      animation: framename 2s;
    }
    /* 通常離開動畫是進入動畫的反向 */
    .div-leave-active {
        animation: framename 2s reverse;
    }
    /* from中設(shè)置動畫的初始狀態(tài)CSS to中設(shè)置結(jié)束狀態(tài)CSS */
    @keyframes framename{
        from{
            transform: translate(0px, 0px);
        }
        25% {
            transform: translate(50px, 0px)
        }
        50% {
            transform: translate(50px, 50px)
        }
        75% {
            transform: translate(0px, 50px)
        }
        to{
            transform: translate(0px, 0px);
        }
    }
</style>
  • 自定義類名
<transition name="div1" enter-active-class="aaa" leave-active-class="bbb">
    <div v-if="show">transtion</div>
</transition>

.aaa, .bbb {
    transition: all 1s ease;
}

使用屬性enter-class遏餐、enter-active-class伦腐、enter-to-class、leave-class失都、leave-active-class柏蘑、leave-to-class自定義過渡/動畫的類名。
如上粹庞,aaa咳焚、bbb相當(dāng)于div1-enter-active、div1-leave-active類名庞溜。

  1. 監(jiān)聽類型
    Vue 會監(jiān)聽transitionendanimationend事件來確定過渡/動畫的結(jié)束革半。若為一個元素同時設(shè)定過渡和動畫,Vue 并不知道監(jiān)聽哪一個事件來確定過渡/動畫的結(jié)束。
    可以將type屬性設(shè)為animation督惰、transition來確定監(jiān)聽哪一個事件不傅,如<transition type="animation"></transition>

  2. 持續(xù)時間
    過渡/動畫的持續(xù)時間通常是在CSS屬性中設(shè)置赏胚,也可以使用duration屬性設(shè)定持續(xù)時間访娶,如<transition duration="1000"></transition>
    可以分別設(shè)定進入和離開的持續(xù)時間觉阅,如<transition duration="{ enter: 500, leave: 800 }"></transition>崖疤。
    duration屬性設(shè)定的持續(xù)時間優(yōu)先度更高。當(dāng)?shù)搅嗽O(shè)定的持續(xù)時間典勇,即使過渡或動畫還在執(zhí)行劫哼,也會立即結(jié)束過渡或動畫。

  3. 事件
    transition 元素有before-enter割笙、enter权烧、after-enter、enter-cancelled伤溉、before-leave般码、leave、after-leave乱顾、leave-cancelled這幾種事件板祝,會在過渡前、過渡時走净、過渡后券时、過渡取消時觸發(fā),如<transition @before-enter="beforeEnter" @enter="enter"></transition>伏伯。
    事件可以與 CSS 類名一起使用橘洞,建議單獨使用。使用<transition :css="false"></transition>可屏蔽 CSS说搅。

    • 事件會給綁定的函數(shù)提供一個參數(shù)炸枣,參數(shù)值為執(zhí)行過渡/動畫的元素。
    • 若為enter蜓堕、leave事件抛虏,還會多提供一個參數(shù)博其,參數(shù)為一個回調(diào)函數(shù)套才。
      需要在過渡/動畫完成時執(zhí)行回調(diào)函數(shù),如enter: function(el, done) { done() }慕淡。
      若不執(zhí)行回調(diào)背伴,過渡/動畫就不會結(jié)束,就不會觸發(fā)after-enter事件;執(zhí)行回調(diào)函數(shù)后傻寂,過渡/動畫會立即結(jié)束息尺。
  4. 初始渲染過渡
    當(dāng)元素初次渲染到界面時,也可以執(zhí)行過渡疾掰。使用appear屬性來實現(xiàn)初始渲染過渡搂誉。

<template>
    <div>
        <button @click="show = !show">switch</button>
        <transition name="div" appear="appearname">
            <div v-if="show">transtion init1</div>
        </transition>
    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                show: true
            }
        }
    }
</script>

<style scoped="scoped">
    .div-enter-active, .div-leave-active {
      transition: all 1s ease;
    }
    .div-enter, .div-leave-to  {
      opacity: 0;
      transform: translateX(60px);
    }

    .div-appearname  {
      opacity: 0;
      transform: translateX(60px);
    }
    .div-appearname-active {
      transition: all 1s ease;
    }
    .div-appearname-to {
        
    }
</style>

初始渲染過渡有三個類名,默認(rèn)為v-appear静檬、v-appear-active炭懊、v-appear-to,表示初始渲染過渡前拂檩、初始渲染過渡中侮腹、初始渲染過渡完成。
根據(jù)name屬性和appear屬性的值決定類名稻励,若<transition name="div" appear="appearname">父阻,那么類名為div-appearname、div-appearname-active望抽、div-appearname-to加矛。

初始渲染過渡也可以通過appear-class、appear-active-class糠聪、appear-to-class使用自定義類名荒椭,如<transition appear appear-active-class="" appear-class="" appear-to-class=""></transition>
初始渲染過渡也可以使用事件before-appear舰蟆、appear趣惠、after-appear、appear-cancelled身害。表示初始渲染過渡前味悄、初始渲染過渡時、初始渲染過渡后塌鸯、初始渲染過渡取消侍瑟。

  1. 元素切換的過渡
    上面介紹的都是單個元素的進入與離開過渡,若想使用多個元素間切換時的過渡丙猬,可使用v-if涨颜、v-else-if、v-else茧球。
<template>
    <div>
        <button @click="show = !show">switch</button>
        <transition name="div">
            <div v-if="show" key="init1">transtion init1</div>
            <div v-else key="init2">transtion init2</div>
        </transition>
    </div>
</template>


此時就會在兩個 div 中切換庭瑰。
必須給每個元素的key屬性設(shè)置不同的值,否則 Vue 會直接改變元素的內(nèi)容抢埋,就不會產(chǎn)生過渡效果弹灭。
若兩個元素是不同的元素督暂,也可以不設(shè)置key屬性,但建議設(shè)置穷吮。

  • 過渡模式
    你會發(fā)現(xiàn)兩個元素它們會同時過渡逻翁,即離開與進入過渡同時進行〖裼悖可以使用mode屬性修改過渡模式八回。

    • in-out新元素先進行過渡,完成之后當(dāng)前元素過渡驾诈。
    • out-in當(dāng)前元素先進行過渡辽社,完成之后新元素過渡。(經(jīng)常使用)

    當(dāng)不設(shè)置mode時翘鸭,兩者會同時過渡滴铅。
    設(shè)置<transition name="div" appear="appearname" mode="out-in">

  • 組件切換的過渡
    通過動態(tài)組件實現(xiàn)組件切換的過渡,動態(tài)組件詳見 十一就乓、組件 -- 6. 動態(tài)組件汉匙。
    這里因為是不同的組件,所以可以不設(shè)置key屬性生蚁。

<template>
    <div>
        <button @click="name == 'component1' ? 'component2' : 'component1'">switch</button>
        <transition name="div" mode="out-in">
            <component :is="name"></component>
        </transition>
    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                name: "component1"
            }
        },
        components: {
            component1: {
                template: '<div>Component 1</div>'
            },
            component2: {
                template: '<div>Component 2</div>'
            }
        }
    }
</script>

<style scoped="scoped">
    .div-enter-active, .div-leave-active {
      transition: all 1s ease;
    }
    .div-enter, .div-leave-to  {
      opacity: 0;
      transform: translateX(60px);
    }
</style>
  1. 列表元素的過渡
    上面我們過渡的噩翠,實際上都是單一元素或組件的過渡;若同時要過渡多個元素邦投,需要使用 transition-group 元素伤锚,且多個元素必須設(shè)置不同的key
    不同于 transition 元素志衣,transition-group 會以一個真實元素呈現(xiàn)屯援,默認(rèn)為一個 span,使用tag屬性更換為其他元素念脯。
<template>
    <div>
        <button @click="click">add</button>
        <br>
        <transition-group>
            <div v-for="item in datas" :key="item" style="display: inline-block;">{{ item }}</div>
        </transition-group>
    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                datas: [1, 2, 3, 4, 5],
                next: 6
            }
        },
        methods: {
            click: function() {
                var num = Math.floor(Math.random() * this.datas.length)
                this.datas.splice(num, 0, this.next++)
            }
        }
    }
</script>

<style scoped="scoped">
    .v-enter-active, .v-leave-active {
      transition: all 1s ease;
    }
    .v-enter, .v-leave-to  {
      opacity: 0;
      transform: translateY(30px);
    }
</style>
  • 平滑過渡
    可以看出狞洋,當(dāng)添加一個元素時,周圍的元素會瞬間移動到他們的新布局的位置绿店。
    為了讓周圍元素能平滑的移動到新位置吉懊,可以使用v-move類名。
    像其他類名一樣假勿,可以使用name屬性改變類名借嗽,也可以使用move-class屬性自定義類名。
    上面的例子添加.v-move { transition: all 1s ease; }

    注:要使用平滑過渡转培,元素不能為display: inline恶导。
  1. 狀態(tài)過渡
    上面都是元素的進入或離開過渡,若想讓數(shù)據(jù)元素本身產(chǎn)生動效堡距,可以使用狀態(tài)過渡甲锡。如數(shù)字從0變到100的漸增式效果。
    詳見狀態(tài)過渡羽戒。

十三缤沦、混入

混入 (mixin) 提供了一種非常靈活的方式,來分發(fā) Vue 組件中的可復(fù)用功能易稠,一個混入對象包含任意的組件選項缸废。

export default {
    data: function() {
        return {
            b: 22,
            c: 33
        }
    },
    created: function() {
        console.log('hello!11')
        this.action()
    },
    methods: {
        action: function() {
            console.log('action11')
        }
    }
}

.js文件中添加要混入的選項。

<template>
    <div>
        <div>{{ a }}</div>
        <div>{{ b }}</div>
        <div>{{ c }}</div>
    </div>
</template>

<script>
    import Test from './Test11.js'
    export default {
        data: function() {
            return {
                a: 1,
                b: 2//同名沖突時 使用組件中的數(shù)據(jù)
            }
        },
        mixins: [Test],
        //生命鉤子 同名沖突 兩個函數(shù)都會調(diào)用 優(yōu)先調(diào)用混入中的函數(shù)
        created: function() {
            console.log('hello!22')
            this.action()
        },
        //方法 同名沖突 優(yōu)先使用組件中的方法
        methods: {
            action: function() {
                console.log('action22')
            }
        }
    }
</script>

在單文件組件中通過import引入.js文件驶社,混入的對象寫在mixins選項中企量,選項是一個數(shù)組。

  1. 選項合并
    當(dāng)組件和混入對象含有同名選項時亡电,這些選項會進行合并届巩。
  • data選項里的數(shù)據(jù)對象會遞歸合并,若遇到同名沖突份乒,以組件的數(shù)據(jù)優(yōu)先恕汇。
  • 值為對象的選項(methods、components或辖、directives等)瘾英,將被合并為同一個對象。若遇到同名沖突颂暇,以組件的數(shù)據(jù)優(yōu)先缺谴。
  • 生命周期鉤子函數(shù)(created、beforeCreate耳鸯、mounted等)湿蛔,若遇到同名沖突,兩個函數(shù)會合并為一個數(shù)組县爬,它們都會調(diào)用煌集,但混入對象中的函數(shù)優(yōu)先調(diào)用。
  1. 全局混入
    使用Vue.mixin({})來注冊全局混入捌省,需要寫在new Vue()前面苫纤。

  2. 自定義合并
    混入數(shù)據(jù)與組件數(shù)據(jù)合并時,有一個默認(rèn)的合并策略纲缓。使用Vue.config.optionMergeStrategies可修改合并策略卷拘,詳見自定義選項合并策略

  3. 擴展
    擴展(extend)和混入功能差不多祝高,都是給組件添加其他的選項功能栗弟。
    混入使用mixins選項,它是一個數(shù)組工闺;而擴展使用extend選項乍赫,它是一個對象或函數(shù)瓣蛀。

<script>
    export default {
        extends: {
            created: function() {
                
            },
            methods: {
                click: function() {
                    
                }
            }
        }
    }
</script>

擴展與混入的選項合并策略相同,不同點在于mixins可同時混入多組對象雷厂,而extend只能擴展一組對象惋增。
擴展的優(yōu)先級比混入高,但都低于組件本身改鲫。

  • 全局?jǐn)U展
    使用Vue.extend({})來注冊全局?jǐn)U展诈皿,需要寫在new Vue()前面。

十四像棘、自定義指令

Vue 有自帶的指令稽亏,但也可以使用directives選項來自定義指令,選項是一個對象缕题。

<template>
    <div>
        <div v-redtext></div>
    </div>
</template>

<script>
    export default {
        directives: {
            redtext: {
                inserted: function (el) {
                  el.style.color = "red"
                  el.innerText = "default text"
                }
              }
        }
    }
</script>
  • 全局指令
    使用Vue.directive('name', {})注冊全局指令截歉,必須寫在new Vue()前面。
  1. 鉤子函數(shù)
    自定義指令有幾個鉤子函數(shù):
    • bind 只調(diào)用一次烟零,指令第一次綁定到元素時調(diào)用怎披。在這里可以進行一次性的初始化設(shè)置。
    • inserted 元素插入父節(jié)點時調(diào)用 (僅保證父節(jié)點存在瓶摆,但不一定已插入到文檔中)凉逛。
    • update 元素的 VNode 更新時調(diào)用,可能發(fā)生在其子 VNode 更新之前群井。指令的值可能發(fā)生了改變状飞,也可能沒有。
    • componentUpdated 元素的 VNode 及其子 VNode 全部更新后調(diào)用书斜。
    • unbind只調(diào)用一次诬辈,指令與元素解綁時調(diào)用。
  • 鉤子函數(shù)參數(shù)
    鉤子函數(shù)有4個參數(shù)荐吉,其中el是可讀寫的焙糟,其他都是只讀的。
    • el 指令綁定的元素样屠,可以用來直接操作 DOM穿撮。
    • binding 一個對象,包含以下的鍵痪欲。
      • name 指令名悦穿,不包括 v-前綴。
      • value 指令的綁定值业踢,如v-directive="1 + 1"中的2栗柒。
      • oldValue 指令綁定的前一個值,僅在update知举、componentUpdated鉤子中可用瞬沦。無論值是否改變都可用太伊。
      • expression 指令的表達(dá)式。如v-directive="1 + 1"中的1 + 1逛钻。
      • arg 指令的參數(shù)僚焦,可選。如v-directive:arg中的arg绣的。
      • modifiers 一個包含修飾符的對象。如v-directive.mod1.mod2欲账,修飾符對象為{ mod1: true, mod2: true }屡江。
    • vnode Vue 編譯生成的虛擬節(jié)點。詳見 VNode赛不。
    • oldVnode 上一個虛擬節(jié)點惩嘉,僅在update、componentUpdated鉤子中可用踢故。
  1. 動態(tài)參數(shù)
    指令可使用[]設(shè)置動態(tài)參數(shù)文黎,如v-on:[dynamic]=""
    自定義的指令也可以使用動態(tài)參數(shù)殿较,如v-redtext:[dynamic]耸峭,在鉤子函數(shù)中通過binding.arg獲取參數(shù)。

十五淋纲、渲染函數(shù)

通常使用模板來創(chuàng)建組件劳闹,也可以使用render選項來創(chuàng)建組件。

<script>
    export default {
        render: function (createElement) {
            return createElement('div', {}, [
                createElement("h1", {}, "title")
            ])
        }
    }
</script>

<style>
</style>

上面例子相當(dāng)于<template><div><h1>title</h1></div></template>洽瞬。
使用render選項來創(chuàng)建組件時需要刪除最上面的<template></template>本涕,也會忽略template選項的值。

  • render選項是一個函數(shù)伙窃,函數(shù)需要返回一個 VNode菩颖。函數(shù)有一個參數(shù),參數(shù)是一個回調(diào)函數(shù)为障,可通過這個回調(diào)函數(shù)來創(chuàng)建 VNode晦闰。
  • render選項可以使用箭頭函數(shù),如render: createElement => createElement()鳍怨。
    回調(diào)函數(shù)通常使用字母h鹅髓,即render: h => h(),可看到 main.js 中就是這種寫法京景。
  1. VNode
    每個元素都是一個節(jié)點窿冯,每段文字也是一個節(jié)點,注釋和屬性也都是節(jié)點确徙。一個節(jié)點就是頁面的一個部分醒串,每個節(jié)點都可以有子節(jié)點 执桌。
    Vue 通過建立一個虛擬 DOM 來追蹤自己要如何改變真實 DOM,虛擬 DOM 由虛擬節(jié)點(virtual node)組成芜赌,即VNode仰挣。
    回調(diào)函數(shù)createElement()可以創(chuàng)建一個虛擬節(jié)點 。它包含的信息會告訴 Vue 需要渲染什么樣的節(jié)點缠沈,包括節(jié)點及其子節(jié)點的描述信息膘壶。
    VNode 必須是唯一的,下面是錯誤的洲愤。
render: function (createElement) {
  var myParagraphVNode = createElement('p', 'hi')
  return createElement('div', [
    // 錯誤 - 重復(fù)的 VNode
    myParagraphVNode, myParagraphVNode
  ])
}

但可以寫成:

render: function (createElement) {
  return createElement('div', [
    createElement('p', 'hi'), createElement('p', 'hi')
  ])
}
  1. 參數(shù)
    createElement()需要傳三個參數(shù)颓芭,如createElement("h1", {}, "title")
    • 參數(shù)一是必填項柬赐,可為一個 HTML 標(biāo)簽名亡问、組件選項對象,或者 resolve 了上述任何一種的async函數(shù)肛宋。
    • 參數(shù)二是一個對象州藕,為元素的各種屬性,如props酝陈、class床玻、id等。
    • 參數(shù)三是一個由子 VNode 組成的數(shù)組沉帮,如createElement("div", {}, [createElement("h1", "title"), createElement("p", "content")])笨枯。
      或為一個字符串,內(nèi)容為元素的innerHTML遇西。
  • 參數(shù)二
{
  // 與 `v-bind:class` 的 API 相同馅精,
  // 接受一個字符串、對象或字符串和對象組成的數(shù)組
  'class': {
    foo: true,
    bar: false
  },
  // 與 `v-bind:style` 的 API 相同粱檀,
  // 接受一個字符串洲敢、對象,或?qū)ο蠼M成的數(shù)組
  style: {
    color: 'red',
    fontSize: '14px'
  },
  // 普通的 HTML attribute
  attrs: {
    id: 'foo'
  },
  // 組件 prop
  props: {
    myProp: 'bar'
  },
  // DOM property
  domProps: {
    innerHTML: 'baz'
  },
  // 事件監(jiān)聽器在 `on` 內(nèi)茄蚯,
  // 但不再支持如 `v-on:keyup.enter` 這樣的修飾器具被。
  // 需要在處理函數(shù)中手動檢查 keyCode碍沐。
  on: {
    click: this.clickHandler
  },
  // 僅用于組件壳咕,用于監(jiān)聽原生事件由缆,而不是組件內(nèi)部使用
  // `vm.$emit` 觸發(fā)的事件。
  nativeOn: {
    click: this.nativeClickHandler
  },
  // 自定義指令皱碘。注意询一,你無法對 `binding` 中的 `oldValue`
  // 賦值,因為 Vue 已經(jīng)自動為你進行了同步。
  directives: [
    {
      name: 'my-custom-directive',
      value: '2',
      expression: '1 + 1',
      arg: 'foo',
      modifiers: {
        bar: true
      }
    }
  ],
  // 作用域插槽的格式為
  // { name: props => VNode | Array<VNode> }
  scopedSlots: {
    default: props => createElement('span', props.text)
  },
  // 如果組件是其它組件的子組件健蕊,需為插槽指定名稱
  slot: 'name-of-slot',
  // 其它特殊頂層 property
  key: 'myKey',
  ref: 'myRef',
  // 如果你在渲染函數(shù)中給多個元素都應(yīng)用了相同的 ref 名菱阵,
  // 那么 `$refs.myRef` 會變成一個數(shù)組。
  refInFor: true
}
  • 事件修飾符
    在參數(shù)二的 on 中可設(shè)置事件監(jiān)聽缩功,但事件名后是不能添加修飾符的晴及,如on { click.once: this.clickAction }是錯誤的。為了解決這個問題嫡锌,Vue 提供了一些前綴虑稼。

    • &表示.passive修飾符。
    • !表示.capture修飾符势木。
    • ~表示.once修飾符蛛倦。
    • ~!表示.capture.once、.once.capture修飾符跟压。

    on { !click: this.clickAction }相當(dāng)于@click.capture="clickAction"胰蝠。
    而其他修飾符歼培,可以在函數(shù)中實現(xiàn)相同的功能震蒋。

    • event.stopPropagation()相當(dāng)于.stop修飾符。
    • event.preventDefault()相當(dāng)于.prevent修飾符躲庄。
    • if (event.target !== event.currentTarget) return相當(dāng)于.self修飾符查剖。
    • if (event.keyCode !== 13) return相當(dāng)于.enter、.13修飾符噪窘。
    • if (!event.ctrlKey) return相當(dāng)于.ctrl修飾符笋庄。
  1. 插槽
  • 使用this.$slots訪問插槽,每個插槽都是一個 VNode 組成的數(shù)組倔监。
    render: function (h) { return h('div', this.$slots.default) }相當(dāng)于<div><slot></slot></div>直砂。
    render: function (h) { return h('div', [this.$slots.header, this.$slots.default]) }相當(dāng)于<div><slot name="header"></slot><slot></slot></div>
    注:使用插槽時不能用箭頭函數(shù)浩习,因為不能訪問this静暂。
  • 使用this.$scopedSlots訪問作用域插槽。
data: function() {
            return {
                title: "標(biāo)題",
                content: "內(nèi)容"
            }
        },
        render: function (h) {
          return h('div', [this.$scopedSlots.header({
              title: this.title
          }), this.$scopedSlots.default({
              content: this.content
          })])
        }

相當(dāng)于<div><slot :title="title" name="header"></slot><slot :content="content"></slot></div>谱秽。

  1. JSX
    JSX是一個插件洽蛀,可使用模板來代替渲染函數(shù)。詳見JSX疟赊。
    render: h =>h("div", [h("h1", "title"), h("div", "contnet")])可寫成redder: h=> (<div><h1>title</h1><div>content</div></div>)郊供。

  2. 函數(shù)式組件
    組件比較簡單時,即沒有管理任何狀態(tài)近哟,沒有監(jiān)聽任何傳遞給它的狀態(tài)驮审,也沒有生命周期方法,它相當(dāng)于一個接受一些props的函數(shù)。
    在這樣的場景下头岔,我們可以將組件的functional選項設(shè)為true塔拳,這意味它無狀態(tài),沒有響應(yīng)式數(shù)據(jù)(即沒有data選項)峡竣,也沒有實例 (即沒有this)靠抑。

functional: true,
        props: {
            
        },
        render: function(createElement, context) {
            createElement("div", context.data, context.children)
        }

因為函數(shù)式組件只是函數(shù),所以渲染開銷也低很多适掰。

  • context
    因為在函數(shù)式組件中this不可用颂碧,所以所有屬性都保存在參數(shù)context中。
    它是一個對象类浪,包含下列字段:
    • props 提供所有自定義屬性的對象载城。
    • children 子虛擬節(jié)點的數(shù)組,通常作為createElement()的第三個參數(shù)傳入組件费就。
    • slots 一個函數(shù)诉瓦,返回了包含所有插槽的對象。
    • scopedSlots 一個包含的作用域插槽的對象力细。
    • data 傳遞給組件的數(shù)據(jù)對象睬澡,通常作為createElement()的第二個參數(shù)傳入組件。
    • parent 對父組件的引用眠蚂。
    • listeners 一個包含了所有父組件為當(dāng)前組件注冊的事件監(jiān)聽器的對象煞聪。data.on的別名。
    • injections 如果使用了inject選項逝慧,則該對象包含了被注入的屬性昔脯。注入詳見 十一、組件 -- 9. 訪問父組件 笛臣。

十六云稚、過濾器

過濾器用于一些常見的文本格式化。過濾器可以用在兩個地方:{{ }}插值和 v-bind指令的值沈堡,如<div>{{ mesage | filter }}</div>静陈、<div :title="message | filter"></div>
過濾器寫在filters選項中踱蛀,選項是一個對象窿给。

<template>
    <div>
        <div>{{ message | lowercase | uppercase }}</div>
    </div>
</template>

<script>
    export default {
        data: function () {
            return {
                message: "Hello World"
            }
        },
        filters: {
            lowercase: function(value) {
                return value.toLowerCase()
            },
            uppercase: function(value) {
                return value.toUpperCase()
            }
        }
    }
</script>

過濾器使用|與表達(dá)式相連,過濾器對象的鍵值對的值是一個函數(shù)率拒,且表達(dá)式為函數(shù)的第一個參數(shù)崩泡。
可多個過濾器串聯(lián)使用,如{{ message | lowercase | uppercase }}猬膨,前面過濾器得出的結(jié)果變?yōu)楹竺孢^濾器的第一個參數(shù)角撞。
過濾器可傳入其他參數(shù)呛伴,如{{ message | lowercase(arg1, arg2) }},第一個參數(shù)為message谒所,參數(shù)二三為arg1热康、arg2。

  • 全局過濾器
    使用Vue.filter('name', function (value) {})注冊全局過濾器劣领,必須寫在new Vue()前面姐军。
    當(dāng)全局過濾器與局部過濾器重名時,優(yōu)先使用局部過濾器尖淘。

十七奕锌、生命周期

整個 Vue 實例初始化到銷毀會經(jīng)歷如下過程。


生命周期分為多個階段村生,每個階段都會觸發(fā)相應(yīng)的鉤子惊暴。
鉤子有beforeCreate、created趁桃、beforeMount辽话、mounted、beforeUpdate卫病、updated油啤、beforeDestroy、destroyed這幾種忽肛,詳見生命周期鉤子村砂。
它們都是函數(shù)烂斋,使用時不要用箭頭函數(shù)屹逛,因為箭頭函數(shù)中this不指向 Vue 實例。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汛骂,一起剝皮案震驚了整個濱河市罕模,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帘瞭,老刑警劉巖淑掌,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蝶念,居然都是意外死亡抛腕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門媒殉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來担敌,“玉大人,你說我怎么就攤上這事廷蓉∪猓” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長刹悴。 經(jīng)常有香客問我行楞,道長,這世上最難降的妖魔是什么土匀? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任子房,我火速辦了婚禮,結(jié)果婚禮上就轧,老公的妹妹穿的比我還像新娘池颈。我一直安慰自己,他們只是感情好钓丰,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布躯砰。 她就那樣靜靜地躺著,像睡著了一般携丁。 火紅的嫁衣襯著肌膚如雪琢歇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天梦鉴,我揣著相機與錄音李茫,去河邊找鬼。 笑死肥橙,一個胖子當(dāng)著我的面吹牛魄宏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播存筏,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼宠互,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了椭坚?” 一聲冷哼從身側(cè)響起予跌,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎善茎,沒想到半個月后券册,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡垂涯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年烁焙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耕赘。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡骄蝇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鞠苟,到底是詐尸還是另有隱情乞榨,我是刑警寧澤秽之,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站吃既,受9級特大地震影響考榨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鹦倚,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一河质、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧震叙,春花似錦掀鹅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至划址,卻和暖如春扔嵌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夺颤。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工痢缎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人世澜。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓独旷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親寥裂。 傳聞我的和親對象是個殘疾皇子嵌洼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容