*Vue.js 實(shí)戰(zhàn)* 基礎(chǔ)篇 學(xué)習(xí)筆記



書本信息:

?<< Vue.js 實(shí)戰(zhàn) >>?作者: 梁灝

學(xué)習(xí)筆記 部分內(nèi)容摘自書 非原創(chuàng) 侵刪

第二章 數(shù)據(jù)綁定


2.1.4 過(guò)濾器

推薦用 computed 來(lái)實(shí)現(xiàn)
在 {{}} 插值尾部添加一個(gè)管道運(yùn)行算符 | 對(duì)數(shù)據(jù)進(jìn)行過(guò)濾

<div id="app">
    {{ data | formatDate }
</div>
<script>
    var padDate = function(value) {
        return value < 10 ? '0' + value : value;
    };

    var app = new Vue({
        el: '#app',
        data: {
            date: new Date()
        },
        filters: {
            formatDate: function(value) {
                var hours = padDate(date.getHours());
                return hours;
            }
        },
        mounted () {
            var _this = this;
            this.timer = setInterval(function() {
                _this.date = new Date();
            }, 1000);
        },
        beforeDestroy () {
            if (this.timer) {
                clearInterval(this.timer);
            }
        }
    })
</script>
  • 串聯(lián)

{{ message | filterA | filterB }}

  • 接收參數(shù)

{{ message | filterA('arg1', 'arg2') }}


第三章 計(jì)算屬性


3.2 計(jì)算屬性用法

每一個(gè)計(jì)算屬性都包含一個(gè) gettter 和一個(gè) setter, 在我們需要時(shí), 可以提供一個(gè) setter 函數(shù), 當(dāng)手動(dòng)修改計(jì)算屬性的值就行修改一個(gè)普通數(shù)據(jù)那樣時(shí), 就會(huì)觸發(fā) setter 函數(shù), 執(zhí)行一些自定義的函數(shù)

<div id="app">
    姓名: {{ fullName }}
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            firstName: 'Jack',
            lastName: 'Green'
        },
        computed: {
            fullName: {
                // getter
                get () {
                    return this.firstName + ' ' + this.lastName;
                },
                // setter
                set (newValue) {
                    var names = newValue.split(' ');
                    this.firstName = names[0];
                    this.lastName = names[names.length - 1];
                }
            }
        }
    })
</script>

當(dāng)執(zhí)行 app.fullName = 'John Doe'; 時(shí), setter 就會(huì)被調(diào)用, 數(shù)據(jù) firstName 和 'lastName' 都會(huì)相對(duì)更新, 視圖也會(huì)更新.


第五章 內(nèi)置指令


5.1.2 v-once

v-once 不需要表達(dá)式, 定義它的組件或組件只渲染一次, 包括元素或組件的所有子節(jié)點(diǎn)
首次渲染后, 不再歲數(shù)據(jù)的變化重新渲染, 將被視為靜態(tài)內(nèi)容
<span v-once>{{ message }}</span>


5.2.1 key 屬性 元素復(fù)用

Vue 在渲染元素時(shí)出于效率考慮, 會(huì)盡可能的復(fù)用已有元素而非重新渲染
如果你不希望這樣, 可以使用 key 屬性, 可以讓你自己決定是否要復(fù)用元素, key 的值必須唯一

<div id="app">
    <template v-if="type === 'name">
        <label>用戶名: </label>
        <input placeholder="輸入用戶名" key="name-input">
    </template>
    <template v-else>
        <label>郵箱: </label>
        <input placeholder="輸入郵箱" key="mail-input">
    </template>
    <button @click="handleToggleClick">切換輸入類型</button>
</div>

5.3 列表渲染 v-for

  • 數(shù)組

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

  • 對(duì)象

<li v-for="(value, key, index) in user">{{ index }} - {{ key }}: {{ value }}</li>

  • 整數(shù)

<span v-for="n in 10">{{ n }} </span>
結(jié)果是 1 2 ...... 10


5.3.2 數(shù)組更新

Vue 的核心是數(shù)據(jù)與視圖的雙向綁定, 當(dāng)我們修改數(shù)組時(shí), Vue 會(huì)檢測(cè)到數(shù)據(jù)變化, 所以用 v-for 渲染的也會(huì)立即更新. Vue 包含了一組觀察數(shù)組變異的方法, 使用它們改變數(shù)組也會(huì)觸發(fā)視圖更新.

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

使用以上方法會(huì)改變這些方法調(diào)用的原始數(shù)組, 有些方法不會(huì)改變?cè)紨?shù)組

  • filter()
  • concat()
  • slice()

它們返回的是一個(gè)新數(shù)組, 在使用這些非變異方法時(shí), 可以用新數(shù)組來(lái)替換原始數(shù)組

app.books = app.books.filter(function (item) {
    return item.name.match(/JavaScript/);
    // 對(duì) books 數(shù)組做 filter 返回帶有 JavaScript 的項(xiàng)
})

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

需要注意的是, 以下變動(dòng)的數(shù)組中, Vue 是不能檢測(cè)到的, 也不會(huì)觸發(fā)視圖更新

  • 通過(guò)索引直接設(shè)置項(xiàng), 比如 `app.books[3] = {...}
  • 修改數(shù)組長(zhǎng)度, 比如 `app.books.length = 1

解決第一個(gè)問(wèn)題可以用兩種方法

  • set 方法
Vue.set(app.books, 3, {
    name: 'changedName'
});

// webpack app.&set
this.&set(app.books, 3, {
    name: 'changedName'
})
  • 用 splice
app.books.splice(3, 1, {
    name: 'changedName'
})

第二個(gè)問(wèn)題也可以直接用 splice 來(lái)解決
app.books.splice(1);


5.4.2 修飾符

在@綁定的事件后加小圓點(diǎn) ".", 再更一個(gè)后綴來(lái)使用修飾符

  • .stop
  • .prevent
  • .capture
  • .self
  • .once

具體用法

// 阻止單擊事件冒泡
<a @click.stop="handle"></a>
// 提交事件不再重載頁(yè)面
<form @submit.prevent="handle"></form>
// 修飾符可以串聯(lián)
<a @click.stop.prevent="handle"></a>
// 只有修飾符
<form @submit.prevent></form>
// 添加事件偵聽(tīng)器時(shí)使用事件捕獲模式
<div @click.capture="handle"></div>
// 只當(dāng)事件在該元素本身(而不是子元素)觸發(fā)時(shí)觸發(fā)回調(diào)
<div @click.self="handle"></div>
// 只觸發(fā)一次, 組件同樣適用
<div @click.once="handle"></div>

在表單元素上監(jiān)聽(tīng)鍵盤事件時(shí), 還可以使用按鍵修飾符, 比如按下某個(gè)鍵時(shí)猜調(diào)用方法

// 只有在 keyCode 是13時(shí)代用 submit()
<input @keyup.13="submit">

也可以自己配置具體按鍵

Vue.config.keyCodes.f1 = 112;
// 全局定義后, 就可以使用 @keyup.f1

除了具體的某個(gè) keyCode, 還提供了一些快捷名稱

  • .enter
  • .tab
  • .delete (刪除和退格)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

這些按鍵修飾符也可以組合使用, 或者和鼠標(biāo)一起配合使用

  • .ctrl
  • .alt
  • .shift
  • .meta ( Mac 下是 Command, Windows 下是窗口鍵)

第六章 表單與 v-model


6.3 修飾符

.lazy: 懶加載

在輸入框中, v-model 默認(rèn)實(shí)在 input 事件中同步輸入框的數(shù)據(jù) (除了中文輸入法輸入的時(shí)候), 使用修飾符 .lazy 會(huì)轉(zhuǎn)變?yōu)樵?change 事件中同步
<input v-model.lazy="message">

.number: 將輸入的 String 轉(zhuǎn)換為 Number

使用 .number 可以將輸入轉(zhuǎn)換為 Number 類型, 否則雖然你輸入的是數(shù)字, 但是它的類型其實(shí)是 String, 在輸入輸入框中比較有用
<input type="number" v-model.number="message">

.trim: 自動(dòng)過(guò)濾輸入的首尾空格

<input type="text" v-model.trim="message">


第七章 組件詳解


7.1.2 is 屬性掛載組件

Vue 組件的模板在某些情況下會(huì)受到 HTML 的限制, 比如 <table> 內(nèi)規(guī)定只允許是 <tr>, <td>, <th> 等這些表格元素, 所以直接在 <table> 內(nèi)使用組件是無(wú)效的, 這種情況下, 可以使用特殊的 is 屬性來(lái)掛載組件
常見(jiàn)的限制元素還有 <ul>, <ol>, <select>

<div id="app">
    <table>
        <tbody is="my-component"></tbody>
    </table>
</div>

7.2.3 數(shù)據(jù)驗(yàn)證 props

在組件中, 使用選項(xiàng) props 來(lái)聲明需要從父級(jí)接收的數(shù)據(jù), props 的值可以是兩種, 一種是字符串?dāng)?shù)組, 一種是對(duì)象
當(dāng) prop 需要驗(yàn)證時(shí), 就需要對(duì)象寫法
一般當(dāng)你的組件需要提供給別人使用時(shí), 推薦都進(jìn)行數(shù)據(jù)驗(yàn)證, 比如某個(gè)數(shù)據(jù)必須是數(shù)字類, 如果是 string 就會(huì)在控制臺(tái)彈出警告

props: {
    // 必須是數(shù)字類型
    propA: Number,
    // 必須是字符串或者數(shù)字
    propB: [String, Number],
    // 布爾值, 如果沒(méi)有定義, 默認(rèn)為 true
    propC: {
        type: Boolean,
        default: true
    },
    // 數(shù)字, 而且是必傳
    propD: {
        type: Number,
        required: true
    },
    // 如果是數(shù)組或者對(duì)象, 默認(rèn)值必須是一個(gè)函數(shù)來(lái)返回
    propE: {
        type: Array,
        default: function () {
            return [];
        }
    },
    // 自定義驗(yàn)證函數(shù)
    propF: {
        validator: function (value) {
            return value > 10;
        } 
    }
}

驗(yàn)證的 type 類型可以是:

  • String
  • Number
  • Boolean
  • Object
  • Array
  • Function

type 也可以是一個(gè)自定義構(gòu)造器, 使用 instanceof 檢測(cè)
當(dāng) prop 驗(yàn)證失敗時(shí), 在開(kāi)發(fā)版本下會(huì)在控制臺(tái)拋出一條警告


7.3.1 自定義事件 v-on .native 監(jiān)聽(tīng)原生事件, 監(jiān)聽(tīng)的是該組件的根元素

當(dāng)給一個(gè) Vue 組件綁定事件的時(shí)候需要加上 .native
否則 Vue 會(huì)認(rèn)為這個(gè)是一個(gè)自定義事件 v-on 來(lái)監(jiān)聽(tīng)子組件的 $emit()

<my-component v-on:click,native="handleClick"></my-component>


7..3.2 自定義組件使用 v-model

<my-component v-model="total"></my-component>
...
methods: {
    handleClick () {
        this.counter++;
        this.$emit('input', this.counter);
    }
}

組件 $emit() 的事件名是特殊的 input, 在使用組件的父級(jí), 并沒(méi)有在 <my-component> 上使用 @input="handler", 而是直接使用了 v-model 綁定的一個(gè)數(shù)據(jù) total, 也可以用自定義事件實(shí)現(xiàn)

<my-component @input="handleGetTotal"></my-component>
...
methods: {
    handleGetTotal (total) {
        this.total = total;
    }
}

v-model 還可以用來(lái)創(chuàng)建自定義的表單輸入組件, 進(jìn)行數(shù)據(jù)雙向綁定

<my-component v-model="total"></my-component>
<button @click="handleReduce">-1</button>
...
<template>
    <input :value="value" @input="updateValue">
</template>
...
methods: {
    updateValue (event) {
        this.$emit('input', event.target.value);
    }
}

實(shí)現(xiàn)這樣一個(gè)具有雙向綁定的 v-model 組件需要滿足下面兩個(gè)要求

  • 接收一個(gè) value 屬性
  • 在有新的 vaue 時(shí)觸發(fā) input 事件

7.3.3 非父子組件通信

組件通信幾種方式

  • $emit() $on() 只能父子組件通信, 子組件 props 接收父組件數(shù)據(jù)
  • bus 空 Vue 實(shí)例
  • vuex
  • 父鏈和子組件索引

父鏈

在子組件中, 使用 this.$parent 可以直接訪問(wèn)該組件的父實(shí)例或組件, 父組件也可以通過(guò) this.$children 訪問(wèn)他所有的子組件, 而且可以遞歸向上或者向下無(wú)限訪問(wèn), 一直到根實(shí)例或最內(nèi)層的組件

子組件索引

當(dāng)子組件較多時(shí), 通過(guò) this.$children 來(lái)一一遍歷出我們需要的一個(gè)組件實(shí)例是比較困難的, 尤其是當(dāng)組件動(dòng)態(tài)渲染時(shí), 他們的序列不是固定的. Vue 可以使用特殊的屬性 ref 來(lái)為子組件指定一個(gè)索引名稱

<div id="app">
    <button @click="handleRef">通過(guò)ref獲取子組件實(shí)例</button>
    <compoent-a ref="comA"></compoent-a>
</div>
...
methods: {
    handleRef () {
        var msg = this.$refs.comA.message;
        console.log(msg);
    }
}

在父組件模板中, 子組件標(biāo)簽上使用 ref 指定一個(gè)名稱, 并在父組件內(nèi)通過(guò) this.$refs 來(lái)訪問(wèn)指定名稱的子組件

注意: $refs 只在組件渲染完成后才填充, 并且他是非響應(yīng)式的, 它僅僅作為一個(gè)直接訪問(wèn)子組件的應(yīng)急方案, 應(yīng)當(dāng)避免在模板或計(jì)算屬性中使用


7.4.4 作用域插槽

作用域插槽是一種特殊的 slot, 使用一個(gè)可以復(fù)用的模板替換已渲染元素

// 列表組件, 允許組件自定義應(yīng)該如何渲染列表每一項(xiàng)
<div id="app">
    <my-list :books="books">
        // 作用域插槽也可以是具名的 slot
        <template slot="book" scope="props">
            <li>{{ props.bookName }}</li>
        </template>
    </my-list>
</div>
<script>
    Vue.component('my-list', {
        props: {
            books: {
                type: Array,
                default () {
                    reutrn [];
                }
            }
        },
        template: '\
        <ul>\
            <slot name="book"\
                  v-for="book in books"\
                  :book-name="book.name"\
                  //這里也可以寫默認(rèn) slot 內(nèi)容 \
            </slot>\
        </ul>'
    });

    var app = new Vue({
        el: '#app',
        data: {
            books: [
                { name: 'abc1'},
                { name: 'abc2'},
                { name: 'abc3'}
            ]
        }
    })
</script>

父組件當(dāng)中 scope="props", 這里的 props 只是一個(gè)臨時(shí)變量, 就像 v-for="item in items" 里面的 item 一樣. template 可以通過(guò)臨時(shí)變量 props 訪問(wèn)來(lái)自子組件插槽的數(shù)據(jù)

在這個(gè)例子當(dāng)中, 子組件 my-list 接收父級(jí)的 prop 數(shù)組 books, 并且將它在 name 為 book 的 slot 上使用 v-for, 同時(shí)暴露一個(gè)變量 bookName

這個(gè)作用域插槽的使用場(chǎng)景就是即可以復(fù)用子組件的slot, 又可以使 slot 內(nèi)容不一致. 如果上例還在其他組件內(nèi)使用, <li> 的內(nèi)容渲染權(quán)是由使用者掌握的, 而數(shù)據(jù)卻可以通過(guò)臨時(shí)變量 (比如 props) 從子組件內(nèi)獲取


7.4.5 訪問(wèn) slot

this.$slots.name

this.$slots.default ????//包括了所有沒(méi)有被包含在具名 slot 中的節(jié)點(diǎn)


7.5.3 動(dòng)態(tài)組件

Vue 提供了一個(gè)特殊元素 <component> 來(lái)動(dòng)態(tài)地掛載不同的組件, 使用 is 特性來(lái)選擇要掛載的組件

<div id="aap">
    <component :is="currentView"></component>
    <button @click="handleChangeView('B')">點(diǎn)擊切換到組件B</button>
</div>
<script>
    ...
    components: {
        comA: {...},
        comB: {...}
    },
    date: {
        currentView: 'comA'
    },
    methods: {
        handleChangeView (component) {
            this.currentView = 'com' + component;
        }
    }
</script>

7.6.1 $nextTick

Vue 中異步更新隊(duì)列

Vue在觀察到數(shù)據(jù)變化時(shí)并不是直接更新 DOM, 而是開(kāi)啟一個(gè)隊(duì)列, 并緩沖在同一事件循環(huán)中發(fā)生的所有數(shù)據(jù)改變. 在緩沖時(shí)會(huì)去除重復(fù)數(shù)據(jù), 從而避免不必要的計(jì)算和 DOM 操作.

然后, 在下一個(gè)事件循環(huán) tick 中, Vue 刷新隊(duì)列并執(zhí)行實(shí)際 (已去重) 工作. 所以如果你用一個(gè) for 循環(huán)來(lái)動(dòng)態(tài)改變數(shù)據(jù)100次, 其實(shí)它只會(huì)應(yīng)用最后一次改變, 如果沒(méi)有這種機(jī)制, DOM 就要重繪100次, 這顯然是一個(gè)很大的開(kāi)銷.
Vue 會(huì)根據(jù)當(dāng)前瀏覽器環(huán)境優(yōu)先使用原生的 Promise.then 和 MutationObserver, 如果都不支持, 就會(huì)采用 setTimeout 代替.
知道了 Vue 異步更新 DOM 的原理, 上面示例的報(bào)錯(cuò)也就不難理解了. 事實(shí)上, 在執(zhí)行 this.showDiv=true; 時(shí), div 仍然還是沒(méi)有被創(chuàng)建出來(lái), 直到下一個(gè) Vue 事件循環(huán)時(shí), 才開(kāi)始創(chuàng)建. $nextTick 就是用來(lái)知道什么時(shí)候 DOM 更新完成的

<div id="app">
    <div id="div" v-if="showDiv">這是一段文本</div>
    <button @click="getText">獲取 div 內(nèi)容</button>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            showDiv: false
        },
        methods: {
            getText () {
                this.showDiv = true;
                this.$nextTick(function () {
                    var text = document.getElementById('div').innerHTML;
                    console.log(text);
                });
            }
        }
    })
</script>

這時(shí)候點(diǎn)擊按鈕, 控制臺(tái)會(huì)打印出 div 的內(nèi)容 "這是一段文本"

理論上, 我們應(yīng)該不用主動(dòng)操作DOM, 因?yàn)?Vue 的核心思想就是數(shù)據(jù)驅(qū)動(dòng) DOM, 但在很多業(yè)務(wù)里, 我們避免不了會(huì)使用一些第三方庫(kù), 比如 popper.js, swiper 等, 這些基于原生 js 的庫(kù)都有創(chuàng)建和更新及銷毀的哇證生命周期, 與 Vue 配合使用時(shí), 就要利用好 $nextTick

vue nextTick深入理解-vue性能優(yōu)化、DOM更新時(shí)機(jī)、事件循環(huán)機(jī)制


7.6.3 手動(dòng)掛載實(shí)例

動(dòng)態(tài)地創(chuàng)建 Vue 實(shí)例, Vue 提供了 Vue.extend 和 $mount 兩個(gè)方法來(lái)手動(dòng)掛載一個(gè)實(shí)例.

Vue.extend 是基礎(chǔ) Vue 構(gòu)造器, 創(chuàng)建一個(gè) 子類 , 參數(shù)是一個(gè)包含組件選項(xiàng)的對(duì)象.

如果 Vue 實(shí)例在實(shí)例化時(shí)沒(méi)有收到 el 選項(xiàng), 它就處在 '未掛載' 狀態(tài), 沒(méi)有關(guān)聯(lián)的 DOM 元素. 可以使用 $mount() 手動(dòng)地掛載一個(gè)未掛載的實(shí)例. 這個(gè)方法返回實(shí)例自身, 因而可以鏈?zhǔn)秸{(diào)用其他實(shí)例方法.

<div id="mount-div">
    
</div>
<script>
    var MyComponent = Vue.extend({
        template: '<div>Hello: {{ name }}</div>',
        data () {
            return {
                name: 'abc'
            }
        }
    });

    new MyComponent().$mount('#mount-div');
</script>

除了這種寫法外, 以下兩種寫法也是可以的

new MyComponent().$mount('#mount-div');
// 同上
new MyComponent({
    el: '#mount-div'
});
// 或者, 在文檔之外渲染并且隨后掛載
var component = new MyComponent().$mount();
document.getElementById('mount-div').appendChild(component.$el);

手動(dòng)掛載實(shí)例 (組件) 是一種比較極端的高級(jí)用法, 在業(yè)務(wù)中幾乎用不到, 只在開(kāi)發(fā)一些復(fù)雜的獨(dú)立組件時(shí)可能會(huì)使用, 這邊只做了解.

Vue2 幾種常見(jiàn)開(kāi)局方式


第八章 自定義指令


8.1 基本用法

exp. 注冊(cè)一個(gè) v-focus 的指令, 用于在 <input>, <textarea> 元素初始化時(shí)自動(dòng)獲得焦點(diǎn)

  • 全局注冊(cè)
Vue.directive('focus', {
        //指令選項(xiàng)
});
  • 局部注冊(cè)
var app = new Vue({
    el: '#app',
    directives: {
        focus: {
            //指令選項(xiàng)
        }
    }
})

下面具體介紹自定義指令的各個(gè)選項(xiàng)

自定義指令的選項(xiàng)是由幾個(gè)鉤子函數(shù)組成的, 每個(gè)都是可選的

  • bind:
    只調(diào)用一次, 指令第一次綁定到元素時(shí)調(diào)用, 用這個(gè)鉤子函數(shù)可以定義一個(gè)在綁定時(shí)執(zhí)行一次的初始化動(dòng)作
  • inserted:
    被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用 (父節(jié)點(diǎn)存在即可調(diào)用, 不必存在于 document 中)
  • update:
    被綁定元素所在的模板更新時(shí)調(diào)用, 而不論綁定值是否變化. 通過(guò)比較更新前后的綁定值, 可以忽略不必要的模板更新
  • componentUpdated:
    被綁定元素所在模板完成一次更新周期時(shí)調(diào)用
  • unbind:
    只調(diào)用一次, 指令與元素解綁時(shí)調(diào)用

可以根據(jù)需求在不同的鉤子函數(shù)內(nèi)完成邏輯代碼, 例如上面的 v-focus, 我們希望在元素插入父節(jié)點(diǎn)時(shí)就調(diào)用, 可以用 inserted

<div id="app">
    <input type="text" v-focus>
</div>
<script>
    Vue.directive('focus', {
        inserted (el) {
            // 聚焦元素
            el.focus();
        }
    });

    var app = new Vue({
        el: '#app'
    })
</script>

瀏覽器中打開(kāi)這個(gè)頁(yè)面, input 輸入框就自動(dòng)獲得了焦點(diǎn), 成為可輸入狀態(tài)

每個(gè)鉤子函數(shù)都有幾個(gè)參數(shù)可用, 比如上面我們用到了 el

  • el 指令所綁定的元素, 可以用來(lái)直接操作 DOM
  • binding 一個(gè)對(duì)象, 包含以下屬性
    • name?指令名, 不包括 v- 前綴
    • value?指令的綁定值, 例如 v-my-directive="1+1", value 的值是2
    • oldValue?指令綁定的前一個(gè)值, 僅在 update 和 componentUpdated 鉤子中可用, 無(wú)論值是否改變都可用
    • expression?綁定值的字符串形式. 例如 v-my-directive="1+1", expression 的值是 "1+1"
    • arg 傳給指令的參數(shù), 例如 v-my-directive:foo, arg 的值是 foo
    • modifiers 一個(gè)包含修飾符的對(duì)象, 例如 v-my-directive.foo.bar, 修飾符對(duì)象 modifiers 的值是 { foo: true, bar: true }
  • vnode Vue 編譯生成的虛擬節(jié)點(diǎn)
  • oldVnode 上一個(gè)虛擬節(jié)點(diǎn)僅在 update 和 componentUpdated 鉤子中可用

下面是結(jié)合了以上參數(shù)的一個(gè)具體實(shí)例

<div id="app">
    <div v-test:msg.a.b="message"></div>
</div>
<script>
    Vue.directive('test', {
        bind (el, binding, vnode) {
            var keys = [];
            for (var i in vnode) {
                keys.push(i);
            }
            el.innerHTML =
                'name: ' + binding.name + '<br>' +
                'value: ' + binding.value + '<br>' +
                'expression: ' + binding.expression + '<br>' +
                'argument: ' + binding.arg + '<br>' +
                'modifiers: ' + JSON.stringify(binding.modifiers) + '<br>' +
                'vnode keys: ' + keys.join(', ')
        }
    });

    var app = new Vue({
        el: '#app',
        data: {
            message: 'some text'
        }
    })
</script>

執(zhí)行后, <div> 的內(nèi)容會(huì)使用 innerHTML 重置

vnode keys:
tag, data, children, text, elm, ns, context, functionalContext, key, componentOptions,
componentInstance, parent, raw, isStatic, isRootInsert, isComment,isCloned, isOnce

在大多數(shù)場(chǎng)景下, 我們會(huì)在 bind 鉤子里綁定一些事件, 比如在 document 上用 addEventListener 綁定, 在 unbind 上用 removeEventListener 解綁, 比較典型的示例就是讓這個(gè)元素隨著鼠標(biāo)拖拽

如果需要多個(gè)值, 自定義指令也可以傳入一個(gè) js 對(duì)象字面量, 只要是合法類型的 js 表達(dá)式都是可以的

<div id="app">
    <div v-test="{msg: 'hello', name: 'abc'}"></div>
</div>
<script>
    Vue.directive('test', {
        bind (el, binding, vnode) {
            console.log(binding.value.msg);
            console.log(binding.value.name);
        }
    });

    var app = new Vue({
        el: '#app'
    })
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容