видел раньше5 библиотек Vue.js Я не могу жить безКоторый является первымClick Off to Close
, основная функция — инициировать событие, когда пользователь щелкает за пределами элемента.
Цель этой статьи, рукописные пользовательские инструкции для достижения этой функции.
Функция состоит в том, чтобы самостоятельно инкапсулировать раскрывающийся список или инкапсулировать календарь и надеяться, что раскрывающийся список можно будет закрыть, когда вы щелкнете по части не раскрывающегося списка.
обычный выпадающий список
Сначала реализовать нормальную раскрывающуюся коробку. То есть коробка + панель. Нажмите на коробку, отобразите или скройте панель.
<div id="app">
<div class="select-box">
<div class="trigger-head" @click="clickSelect">点击下拉</div>
<div v-if="isShow" class="trigger-body">我是下拉框</div>
</div>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
isShow: false
},
methods: {
clickSelect() {
this.isShow = !this.isShow;
}
}
});
</script>
<!-- style这里先放后面,毕竟不是说的重点 -->
<style>
.select-box {
width: 200px;
margin-left: 200px;
}
.trigger-head {
border: 1px solid #ccc;
padding: 10px;
}
.trigger-body {
width: 200px;
height: 300px;
background-color: #ccc;
position: absolute;
}
</style>
Важно: нажать на улице, закрою панель
Я сначала вставлю код, после прочтения кода я в принципе понимаю
mounted() {
document.addEventListener("click", (e)=> {
// 记得在.select-box那边加上ref="selectBox"
const selectBox = this.$refs.selectBox;
// 重点来了:selectBox里是否包含点击的元素,不包含点击的元素就隐藏面板
if (!selectBox.contains(e.target)) {
this.isShow = false;
}
});
},
На самом деле с первого взгляда на код аудитория, вероятно, все поймет.
Событие клика привязывается глобально, а затем передаетсяcontains
Этот ключевой метод определяет, является ли выбранный элементselectBox
Потомки , если нет, то должно бытьselectBox
Как инкапсулировать пользовательские инструкции в официальные документы
Упакуйте один здесь,clickOutside
Инструкция, которая связывает элемент инструкции, указывает, что щелчок за пределами элемента выполнит соответствующую функцию.
// html那边 <div v-click-outside="hidePanel" ref="selectBox" class="select-box" >
Vue.directive("click-outside", (el, bindings, vnode) => {
// el就是绑定指令的元素,bindings.expression就是动态参数这里是hide,vnode是绑定指令的元素的虚拟节点,vnode.context就是节点所在的vm实例
document.addEventListener("click", e => {
// 点击的是 绑定指令元素么 不是就执行函数
if (!el.contains(e.target)) {
let method = bindings.expression;
vnode.context[method]();
}
});
});
// 顺便记得在methods里面添加 hidePanel(){ this.isShow = false }
Хуки для пользовательских директив
Выше, в основном почти, но есть оптимизированная точка, потому что событие связывания являетсяdocument
, мы должны развязать в нужное время.
Прочитав документацию на официальном сайте, можно подумать оunbind
Этот хук, как только инструкция будет отвязана, документ автоматически отменит привязку события.
Обратите внимание, что для облегчения отвязки вам необходимо назначить событие клика наel.handle
.
Оптимизированный код инструкции выглядит следующим образом:
Vue.directive("click-outside", {
// el就是绑定指令的元素,bindings.expression就是动态参数这里是hide,vnode是绑定指令的元素的虚拟节点,vnode.context就是节点所在的vm实例
bind(el, bindings, vnode) {
el.handle = e => {
// 点击的是 绑定指令元素么 不是就触发 参数传进来的函数
if (!el.contains(e.target)) {
let method = bindings.expression;
vnode.context[method]();
}
};
document.addEventListener("click", el.handle);
},
unbind(el) {
// 相关事件移除
document.removeEventListener("click", el.handle);
}
});
Дополнительно: Инструкция по автофокусу
Я не знаю, нашли ли мы его, даже если бы мыinput
добавить тудаautofocus
свойство, но фокус пропадает на долю секунды, а потом курсора нет.
потому что#app
Код внутри входит в фрагмент, компилирует его, а затем заливает в него. Поэтому в начале есть мгновенный фокус, а после того, как он будет влит, эффект фокуса будет недействителен.
Таким образом, если вы хотите выполнить автофокусировку, пакет может быть простой командой, вот прямо официальный сайт.
// <input type="text" v-focus>
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时
inserted: function (el) {
// 聚焦元素
el.focus()
}
})