Vue 自定義指令

關於自定義指令的寫法(全局和局部),有哪些鉤子函數,鉤子函數的參數這裏就不做講解,Vue文檔很清楚,可以直接看文檔的;https://cn.vuejs.org/v2/guide/custom-directive.html

一、 自定義雙向數據綁定

這個指令的實現還是比較簡單的;

  1. 首先在指令綁定到元素的時候,把數據和 data 中的數據保持一致; bind()
  2. data 中的數據更新的時候,把更新過的數據更新到指令綁定的元素中; uodate()
  3. 在指令綁定的元素更新數據的時候,監聽 input 事件,通過 event.target.value 拿到新的數據,更新到 data 中去;inserted()

難點說明:(3.)
vnode.context[binding.expression]
vnode:Vue 編譯生成的虛擬節點,其實就是組件的虛擬 DOM 對象
vnode.context指令綁定的元素所在的組件的對象
binding.expression:字符串形式的指令表達式( v-gx="gong" 中的 gong

鉤子函數的參數 – vnode
vnode:使用了指令之後,它會把當前這個元素,創建成一個虛擬的 DOM元素;
裏邊包含(常用):

  1. context:這個指令綁定的元素所在的組件對象;
  2. data:綁定指令的數據;
  3. elm:指令所綁定的真實 DOM元素;

主要代碼

<div id="app">
    <input type="text" v-sync='name'>
    <input type="text" v-model="name" style="background-color: #ccc;">
</div>

<script>
    Vue.directive('sync',{
        bind(el, binding, vnode){
            el.value = binding.value;
        },
        inserted(el, binding, vnode){
            el.addEventListener('input', (ev)=>{
                vnode.context[binding.expression] = ev.target.value;
            });
        },
        update(el, binding, vnode){
            el.value = binding.value;
        }
    });

    new Vue({
        el: '#app',
        data: {
            name: '宮鑫'
        }
    })
</script>

二、自定義事件指令

要實現這個事件的自定義指令,其實主要是靈活運用鉤子函數的參數 binding,主要是如下幾個參數
binding.arg:傳給指令的參數,可選。例如 v-my-directive:foo 中,參數爲 “foo”。
binding.value:指令的綁定值,例如:v-my-directive="1 + 1" 中,綁定值爲 2
binding.modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象爲{ foo: true, bar: true }
再加上一些判斷,自定義事件指令就完成了;

主要代碼

<div id="app">
    <button v-gx:click.stop="run">按鈕</button>
</div>

<script>
    Vue.directive('gx', {
        bind(el, binding, vnode) {
            // 【1】判斷值是不是一個函數
            if (typeof binding.value == 'function') {
                // 【2】判斷事件類型是否符合
                if (/(click|mouseover|mouseout|mousemove|keydown|keyup)/.test(binding.arg)) {
                    // 【3】給指令綁定的元素綁定事件
                    el.addEventListener(binding.arg, (ev) => {
                        // 【4】修飾符 比如:stop
                        if (binding.modifiers.stop) {
                            ev.stopPropagation();
                        }
                        // 【5】執行函數
                        binding.value(ev)
                    });
                } else {
                    console.error('您的事件類型有誤,請檢查:' + binding.arg);
                }
            } else {
                console.error('您傳入的值並不是一個函數:' + binding.value);
            }

        }
    });

    new Vue({
        el: '#app',
        methods: {
            run(val) {
                alert(val);
            }
        },
    })
</script>




衣帶漸寬終不悔,爲伊消得人憔悴
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章