Vue學(xué)習(xí)——指令(一)

概述

指令是帶有v-前綴的特殊屬性摊腋,其值限定為單個(gè)表達(dá)式沸版。指令的作用是,當(dāng)表達(dá)式的值發(fā)生改變時(shí)兴蒸,將其產(chǎn)生的連帶影響應(yīng)用到DOM上视粮。

此外,一些指令還可以帶有參數(shù)橙凳,在指令名稱(chēng)之后以冒號(hào)表示蕾殴。從Vue.js 2.6.0版本開(kāi)始,指令的參數(shù)可以是動(dòng)態(tài)參數(shù)岛啸,語(yǔ)法為指令:[JavaScript表達(dá)式]钓觉。

內(nèi)置指令

Vue.js針對(duì)一些常用的頁(yè)面功能提供了以指令來(lái)封裝的使用形式,以HTML元素屬性的方式使用坚踩,這些指令數(shù)量并不是很多荡灾。

v-show

v-show指令根據(jù)表達(dá)式的值的真假,來(lái)顯示或隱藏HTML元素瞬铸。

代碼示例如下

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>v-show 指令</title>
    </head>
    <body>
        <div id="app">
            <h1 v-show="yes">Yes!</h1>
            <h1 v-show="no">No!</h1>
            <h1 v-show="age <= 25">Age: {{age}}</h1>
            <h1 v-show="name.indexOf('John') >= 0">Name: {{name}}</h1>
        </div>

        <script src="vue.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    yes: true,
                    no: false,
                    age: 18,
                    name: 'Will John'
                }
            })
        </script>
    </body>
</html>

我們用Chrome瀏覽器打開(kāi)上述頁(yè)面批幌,使用開(kāi)發(fā)者工具展開(kāi)div元素,結(jié)果如下圖所示:


image

從上圖中可以看到嗓节,因?yàn)閿?shù)據(jù)對(duì)象中的no屬性為false荧缘,因此使用v-show指令計(jì)算no表達(dá)式的<h1>元素沒(méi)有顯示;其他表達(dá)式的值計(jì)算都為true赦政,所以這些表達(dá)式所在的<h1>元素都正常顯示了胜宇。

從Chrome瀏覽器的Elements窗口中可以看到,使用v-show指令恢着,元素本身是要被渲染的桐愉,至于顯示與否是通過(guò)設(shè)置css樣式屬性display來(lái)控制的,如果表達(dá)式的值計(jì)算為false掰派,則設(shè)置樣式"display: none"从诲。接下來(lái)切換到Console窗口,修改age屬性的值為28(vm.age = 28)靡羡,然后切換回Elements窗口系洛,如下圖所示:


image

由此可以進(jìn)一步確認(rèn)v-show指令是通過(guò)css樣式屬性displa來(lái)控制元素的顯示與否俊性。

指令都是在某個(gè)元素上使用,如果要顯示或隱藏多個(gè)元素描扯,其實(shí)并不需要在每個(gè)元素上都使用v-show指令定页。我們可以使用HTML 5新增的<template>元素來(lái)包裹需要切換顯示與隱藏的多個(gè)元素,然后在<template>元素上使用v-show指令绽诚,最終的渲染結(jié)果中是不會(huì)包含<template>元素的典徊。實(shí)際上,<template>元素是被當(dāng)作一個(gè)不可見(jiàn)的包裹元素恩够,主要用于分組的條件判斷和列表渲染卒落。

使用<template>標(biāo)簽實(shí)現(xiàn)多個(gè)元素顯示隱藏

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>v-show 指令</title>
    </head>
    <body>
        <div id="app">
            <template v-show="!isLogin">
                <form>
                    <p>username: <input type="text"></p>
                    <p>password: <input type="password"></p>
                </form>
            </template>
        </div>

        <script src="vue.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    isLogin: false
                }
            })
        </script>
    </body>
</html>

渲染結(jié)果如圖所示:


image

v-if / v-else-if / v-else

v-if、v-else-if蜂桶、v-else這三個(gè)指令用于實(shí)現(xiàn)條件判斷儡毕。

1. v-if

v-if指令根據(jù)表達(dá)式的值的真假來(lái)生成或刪除一個(gè)元素。

代碼示例如下

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>v-if 指令</title>
    </head>
    <body>
        <div id="app">
            <h1 v-if="yes">Yes!</h1>
            <h1 v-if="no">No!</h1>
            <h1 v-if="age <= 25">Age: {{age}}</h1>
            <h1 v-if="name.indexOf('John') >= 0">Name: {{name}}</h1>
        </div>

        <script src="vue.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    yes: true,
                    no: false,
                    age: 18,
                    name: 'Will John'
                }
            })
        </script>
    </body>
</html>

使用Chrome瀏覽器打開(kāi)頁(yè)面扑媚,如下圖所示:


image

從上圖可以看到腰湾,包含no表達(dá)式(值為false)的<h1>元素并沒(méi)有生成,其他表達(dá)式的值為true的<h1>元素正常生成了钦购。也就是說(shuō)檐盟,v-if指令在HTML元素的顯示與否的實(shí)現(xiàn)機(jī)制上與v-show指令不同,當(dāng)表達(dá)式的值計(jì)算為false時(shí)押桃,v-if指令不會(huì)創(chuàng)建該元素葵萎,只有當(dāng)表達(dá)式的值為true時(shí),v-if指令才會(huì)真正創(chuàng)建該元素唱凯;而v-show指令不管表達(dá)式的值是真是假羡忘,元素本身都會(huì)被創(chuàng)建。

切換到Console窗口磕昼,修改age屬性的值為28(vm.age = 28)卷雕,然后切換回Elements窗口,如下圖所示:


image

與v-show指令一樣票从,如果v-if需要控制多個(gè)元素的創(chuàng)建或刪除漫雕,可以用<template>元素來(lái)包裹這些元素,然后在<template>元素上使用v-if指令峰鄙。

一般來(lái)說(shuō)浸间,v-if有更高的切換開(kāi)銷(xiāo),而v-show有更高的出事渲染開(kāi)銷(xiāo)吟榴。因此魁蒜,如果需要非常頻繁地切換元素的顯示或隱藏,則使用v-show較好;如果在運(yùn)行時(shí)條件很少改變兜看,則使用v-if較好锥咸。

2. v-else-if / v-else

v-else-if指令是在Vue.js 2.1.0版本中新增的,與v-if一起使用细移,可以實(shí)現(xiàn)互斥的條件判斷搏予。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <span v-if="score >= 85">優(yōu)秀</span>
            <span v-else-if="score >= 75">良好</span>
            <span v-else-if="score >= 60">及格</span>
            <span v-else>不及格</span>
        </div>

        <script src="vue.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    score: 90
                }
            })
        </script>
    </body>
</html>

當(dāng)一個(gè)條件滿足時(shí),后續(xù)的條件都不會(huì)再判斷弧轧。

  • 使用時(shí)缔刹,v-else-if和v-else要緊跟在v-if或v-else-if之后
3. 用key管理可復(fù)用的元素

Vue會(huì)盡可能高效地渲染元素,通常會(huì)復(fù)用已有元素而不是從頭開(kāi)始渲染劣针,這么做使Vue渲染效率變得非常高。

不使用key的情況

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>v-if-key</title>
    </head>
    <body>
        <div id="app">
            <template v-if="loginType === 'username'">
                <label>用戶名:</label>
                <input placeholder="請(qǐng)輸入你的用戶名">
            </template>
            <template v-else>
                <label>Email:</label>
                <input placeholder="請(qǐng)輸入你的Email">
            </template>
            <p><button v-on:click="changeLoginType">切換登陸方式</button></p>
        </div>

        <script src="vue.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    loginType: 'username'
                },
                methods: {
                    changeLoginType() {
                        if (this.loginType === 'username') {
                            this.loginType = "email"
                        } else {
                            this.loginType = "username"
                        }
                    }
                }
            })
        </script>
    </body>
</html>

使用瀏覽器打開(kāi)上述頁(yè)面亿扁,初始顯示的是用戶名輸入框捺典,可以在其中任意輸入些內(nèi)容,在點(diǎn)擊“切換登陸方式”按鈕后从祝,之前輸入的內(nèi)容會(huì)被保留下來(lái)襟己。如下圖所示:


image

image

這是因?yàn)樵趦蓚€(gè)模版中使用了相同的<input>元素,Vue為了提高渲染效率牍陌,復(fù)用了<input>元素擎浴,因此,在切換登陸時(shí)毒涧,<input>不會(huì)被替換掉贮预,僅僅是替換了它的placeholder屬性。

但有時(shí)這并不是我們想要的契讲,我們不希望在Email輸入框中看到之前輸入的用戶名仿吞,這時(shí)我們可以通過(guò)為<input>元素添加一個(gè)具有唯一值的key屬性,來(lái)取消復(fù)用捡偏。

修改上述代碼唤冈,為<input>標(biāo)簽添加key屬性

<template v-if="loginType === 'username'">
    <label>用戶名:</label>
    <input placeholder="請(qǐng)輸入你的用戶名" key="username-input">
</template>
<template v-else>
    <label>Email:</label>
    <input placeholder="請(qǐng)輸入你的Email" key="email-input">
</template>

使用瀏覽器再次打開(kāi)該頁(yè)面,可以發(fā)現(xiàn)切換時(shí)银伟,輸入框會(huì)被重新渲染你虹。

v-for

顧名思義,v-for指令就是通過(guò)循環(huán)的方式來(lái)渲染一個(gè)列表彤避,循環(huán)的對(duì)象可以是數(shù)組傅物,也可以是一個(gè)JavaScript對(duì)象。

1. v-for遍歷數(shù)組

表達(dá)式的語(yǔ)法形式為item in times,其中items是源數(shù)據(jù)數(shù)組忠藤,而item則是被迭代的數(shù)組元素的別名

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <ul>
                <li v-for="book in books">{{book.title}}</li>
            </ul>
        </div>

        <script src="vue.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    books: [
                        {title: 'Book1'},
                        {title: 'Book2'},
                        {title: 'Book3'}
                    ]
                }
            })
        </script>
    </body>
</html>

Vue實(shí)例的數(shù)據(jù)對(duì)象中定義了一個(gè)數(shù)組屬性books挟伙,然后在<li>元素上使用v-for指令遍歷該數(shù)組,這將循環(huán)渲染<li>元素。在v-for塊中尖阔,可以訪問(wèn)所有父作用域的屬性贮缅,book是數(shù)組中元素的別名,每次循環(huán)介却,book的值都被重置為數(shù)組當(dāng)前索引的值谴供,在<li>元素內(nèi)部,可以通過(guò)Mustache語(yǔ)法來(lái)引用該變量值齿坷。

最終渲染結(jié)果如下圖:


image
  • v-for指令的表達(dá)式也可以使用of替代in作為分隔符桂肌,它更接近JavaScript迭代器的語(yǔ)法,如<div v-for="item of items"></div>

v-for指令的表達(dá)式還支持一個(gè)可選的參數(shù)作為當(dāng)前項(xiàng)的索引永淌。

修改代碼中的<li>元素

<li v-for="(book, index) in books">{{index}} - {{book.title}}</li>

多個(gè)參數(shù)需要放到圓括號(hào)中崎场,最后的渲染結(jié)果如下圖所示:


image
2. 數(shù)組更新檢測(cè)

Vue的核心是數(shù)據(jù)與視圖的雙向綁定,為了檢測(cè)數(shù)組中元素的變化遂蛀,以便能及時(shí)將變化反映到視圖中谭跨,Vue對(duì)數(shù)組的下列變異方法(mutation method)進(jìn)行了包裹。

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

我們可以直接使用Chrome瀏覽器的Console窗口輸入下列語(yǔ)句

vm.books.push({title: 'Book4'})

數(shù)組中還有一些非變異方法(non-mutating method)李滴,如filter()螃宙、concat()和slice(),它們不會(huì)改變?cè)紨?shù)組所坯,而總是返回一個(gè)新數(shù)組谆扎。對(duì)于這些方法,要想讓Vue幫我們自動(dòng)更新視圖芹助,可以使用新數(shù)組來(lái)替換原來(lái)的數(shù)組堂湖。

依然是上述代碼,在瀏覽器控制臺(tái)輸入下面的語(yǔ)句

vm.books = vm.books.concat([{title: 'Book5'}, {title: 'Book6'}])

Vue在檢測(cè)到數(shù)組變化時(shí)状土,并不是直接重新渲染整個(gè)列表苗缩,而是最大化地復(fù)用DOM元素,替換的數(shù)組中声诸,含有相同元素的項(xiàng)不會(huì)被重新渲染酱讶,因此可以大膽地使用新數(shù)組來(lái)替換舊數(shù)組,不用擔(dān)心性能問(wèn)題彼乌。

  • 要注意的是泻肯,通過(guò)下述方法引起的數(shù)組變動(dòng),Vue不能檢測(cè)到
// 通過(guò)索引直接設(shè)置數(shù)組值
vm.books[0] = {title: 'Book'}
// 修改數(shù)組的長(zhǎng)度
vm.books.length = 1

要解決上述第一類(lèi)問(wèn)題慰照,可以采用下面兩種方式灶挟,這兩種方式都可以實(shí)現(xiàn)vm.books[0] = {...}相同的效果

// 使用Vue的全局set()方法
Vue.set(vm.books, 0, {title: 'BookA'})
// 使用數(shù)組原型的splice()方法
vm.books.splice(0, 1, {title: 'BookB'})

作為替代,也可以使用Vue實(shí)例的$set方法毒租,該方法是全局方法Vue.set的一個(gè)別名

// 使用Vue實(shí)例的$set()方法
vm.$set(vm.books, 0, {title: 'BookC'})

前述第二類(lèi)問(wèn)題也是使用數(shù)組原型的splice()方法來(lái)解決的稚铣,代碼如下

vm.books.splice(1)

由于篇幅有限,本篇文章就先介紹到這里,v-for的更多用法以及其余指令將在下篇文章繼續(xù)介紹惕医。后續(xù)更多內(nèi)容請(qǐng)參考“Vue學(xué)習(xí)——指令(二)”

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耕漱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抬伺,更是在濱河造成了極大的恐慌螟够,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峡钓,死亡現(xiàn)場(chǎng)離奇詭異妓笙,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)能岩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)寞宫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人拉鹃,你說(shuō)我怎么就攤上這事淆九。” “怎么了毛俏?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)饲窿。 經(jīng)常有香客問(wèn)我煌寇,道長(zhǎng),這世上最難降的妖魔是什么逾雄? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任阀溶,我火速辦了婚禮,結(jié)果婚禮上鸦泳,老公的妹妹穿的比我還像新娘银锻。我一直安慰自己,他們只是感情好做鹰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布击纬。 她就那樣靜靜地躺著,像睡著了一般钾麸。 火紅的嫁衣襯著肌膚如雪更振。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天饭尝,我揣著相機(jī)與錄音肯腕,去河邊找鬼。 笑死钥平,一個(gè)胖子當(dāng)著我的面吹牛实撒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼知态,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼捷兰!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起肴甸,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤寂殉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后原在,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體友扰,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年庶柿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了村怪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡浮庐,死狀恐怖甚负,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情审残,我是刑警寧澤梭域,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站搅轿,受9級(jí)特大地震影響病涨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜璧坟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一既穆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雀鹃,春花似錦幻工、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至傅瞻,卻和暖如春迁酸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背俭正。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工奸鬓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掸读。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓串远,卻偏偏與公主長(zhǎng)得像宏多,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子澡罚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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

  • 本文承接上文伸但,繼續(xù)對(duì)Vue的指令進(jìn)行介紹,建議讀者先閱讀上篇文章留搔,以免有不解之處更胖。前文請(qǐng)參考“Vue學(xué)習(xí)——指令(...
    Tierney_John閱讀 299評(píng)論 0 0
  • 通過(guò)指令實(shí)現(xiàn)下拉菜單 下拉菜單在實(shí)際應(yīng)用中很常見(jiàn),當(dāng)鼠標(biāo)移動(dòng)到某個(gè)菜單上時(shí)會(huì)彈出一個(gè)子菜單列表隔显,每個(gè)子菜單都是可以...
    Tierney_John閱讀 414評(píng)論 0 1
  • 本文承接上文却妨,繼續(xù)對(duì)Vue的指令進(jìn)行介紹,同時(shí)也是指令系列的終章括眠。建議讀者先閱讀上篇文章彪标,以免有不解之處。前文請(qǐng)參...
    Tierney_John閱讀 613評(píng)論 0 1
  • 本文承接上文掷豺,繼續(xù)對(duì)Vue的指令進(jìn)行介紹捞烟,建議讀者先閱讀上篇文章,以免有不解之處当船。前文請(qǐng)參考“Vue學(xué)習(xí)——指令(...
    Tierney_John閱讀 424評(píng)論 0 0
  • 本文為轉(zhuǎn)載题画,原文:Vue學(xué)習(xí)筆記入門(mén)篇——安裝及常用指令介紹 介紹 Vue.js是當(dāng)下很火的一個(gè)JavaScrip...
    ChainZhang閱讀 396評(píng)論 0 1