vue中點選空白處隱藏div的實現(用指令優雅的實現)

jaxQin發表於2019-03-02

簡單想應該怎麼實現? 1、肯定是給document增加一個click事件監聽 2、當發生click事件的時候判斷是否點選的當前物件 結合著本思路和指令我們們來實現。


簡單介紹vue指令

一個指令定義物件可以提供如下幾個鉤子函式 (均為可選):

  • bind:只呼叫一次,指令第一次繫結到元素時呼叫。在這裡可以進行一次性的初始化設定。
  • inserted:被繫結元素插入父節點時呼叫 (僅保證父節點存在,但不一定已被插入文件中)。
  • update:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以通過比較更新前後的值來忽略不必要的模板更新 (詳細的鉤子函式引數見下)。
  • componentUpdated:指令所在元件的 VNode 及其子 VNode 全部更新後呼叫。
  • unbind:只呼叫一次,指令與元素解綁時呼叫。

接下來我們來看一下鉤子函式的引數 (即 el、binding、vnode 和 oldVnode)。

這裡寫圖片描述

程式碼實現

建立指令物件,分析放在程式碼中

<template>
	<div>
		<div class="show" v-show="show" v-clickoutside="handleClose">
			顯示
		</div>
	</div>
</template>

<script>
const clickoutside = {
	// 初始化指令
    bind(el, binding, vnode) {
        function documentHandler(e) {
			// 這裡判斷點選的元素是否是本身,是本身,則返回
            if (el.contains(e.target)) {
                return false;
			}
			// 判斷指令中是否繫結了函式
            if (binding.expression) {
				// 如果繫結了函式 則呼叫那個函式,此處binding.value就是handleClose方法
                binding.value(e);
            }
		}
		// 給當前元素繫結個私有變數,方便在unbind中可以解除事件監聽
        el.__vueClickOutside__ = documentHandler;
        document.addEventListener('click', documentHandler);
    },
    update() {},
    unbind(el, binding) {
		// 解除事件監聽
        document.removeEventListener('click', el.__vueClickOutside__);
        delete el.__vueClickOutside__;
    },
};
export default {
    name: 'HelloWorld',
    data() {
        return {
            show: true,
        };
    },
    directives: {clickoutside},
    methods: {
        handleClose(e) {
            this.show = false;
        },
    },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.show {
    width: 100px;
    height: 100px;
    background-color: red;
}
</style>

複製程式碼

注:指令程式碼參考自iview 原創文章,轉載請註明出處

相關文章