🔥"Нестандартный" трюк Vue, 🤖99% людей видят его впервые

JavaScript Vue.js
🔥"Нестандартный" трюк Vue, 🤖99% людей видят его впервые

Пусть "Родной Ивент" и "в-он" хорошо играют

Понимание «события» в одном предложении: Аналогично vue$emit, использоватьnew Eventбраузер можно создатьродное событие,используяaddEventListenerСлушайте события.

Простой в использовании:

// 监听
el.addEventListener('abc', onAbc);
// 创建事件
const event = new Event(type);
// 派发事件对象
el.dispatchEvent(event);

Какое это имеет отношение к Vue?

Видите ли, обычно события привязываются к компонентам следующим образом:

<my-scroll @scroll-reach-bottom="onScrollReachBottom"/>

Но если не компонент являетсяHTML-элементШерстяная ткань?

<div @scroll-reach-bottom="onScrollReachBottom"/>

Чтобы реализовать приведенный выше пример, вам нужно использоватьПользовательское событие (Событие).

Почему бы не использовать «компоненты»?

Взяв в качестве примера «перетаскиваемый компонент», хорошо известно, что компонент имеет хотя бы один элемент (корень), тогда, если мы используем «перетаскиваемый компонент»:

<my-drag>
    <span>待拖拽</span>
</my-drag>

<!--实际dom结构-->
<div>
    <span>待拖拽</span>
</div>

Видно, что компонент разрушает структуру dom и может напрямую влиять на стиль при использовании, поэтому многие плагины vue используют «инструкции vue» для решения этой проблемы.

Улучшенные «директивы vue»

Это команда InfiniteScroll пользовательского интерфейса Ele.me:

<ul 
    v-infinite-scroll="load" 
    infinite-scroll-distance="10" 
    infinite-scroll-delay="10">
    <li v-for="i in count">{{ i }}</li>
</ul>
export default{
    directives:{
        infiniteScroll
    }
}

Напротив, если вы используете Event для реализации:

<ul @infinite-scroll="load">
    <li v-for="i in count">{{ i }}</li>
</ul>
export default{
    mounted(){
        const is = new InfiniteScroll(this.$el,{
            distance:10,
            delay:10
        });
        this.$on('hook:destroy', is.destroy);
    }
}

Честно говоря, особой разницы для пользователя нет, просто семантика "@" выглядит немного лучше, но уничтожение нужно запускать вручную.

Но если вы написали «инструкции vue», вы должны помнить, что vue не особенно дружелюбен к дизайну «хуков-функций» инструкций, и вам нужно самостоятельно реализовать управление данными между хуками, что не элегантно.

но используетсяEventТаким образом, вы можете превратить свои собственные компоненты в конструкторы, вышеупомянутая проблема «управления состоянием» может быть решена,И код, который вы пишете таким образом, не ограничивается vue-плагином, это обычный js-плагин, который можно использовать в любом фреймворке.

КонечноТакие понятия, как «модификаторы» для директив, по-прежнему привлекательны, и при желании их можно комбинировать.EventПри использовании вместе с «директивой vue» она еще более мощная.

Как использовать событие?

Определите событие 'abc' и присвойте значение объекту события:

// 注册监听
el.addEventListener('abc', event=>{
    'abc' === event.type // true
    1 === event.a // true
});
// 创建事件
const event = new Event(type, {
     // 事件是否可以冒泡, 默认false
    bubbles: false,
     // 事件是否可以取消(使用preventDefault时), 默认false
    cancelable: false,
    // 事件是否会在影子DOM根节点之外触发侦听器, 默认false, 
    // 此属性涉及原生web component, 欲深入了解web component请查阅mdn
    composed: false 
});

// 修改事件对象的值
Object.assign(event, {a:1,b:2});
// 派发事件对象
el.dispatchEvent(event);

отменяемый экземпляр

el.addEventListener('abc', event=>{
    // 受到cancelable控制
    // cancelable === false时,
    // preventDefault()无效
    event.preventDefault();
});

Примеры пузырей

parent.appendChild(el);

el.addEventListener('abc', event=>{
    // event.stopPropagation();
});

parent.addEventListener('abc', event=>{
    // 受到bubble控制
    // bubble === false时,
    // 子元素绑定的事件回调中, 
    // 有没有event.stopPropagation()都不触发
});

совместимый

EventНесовместимо с более ранними версиями, но явно написано на mdn, будущие браузеры будут использоватьEventКак стандарт, поэтому мы должны сделать совместимость со старым синтаксисом.

createEvent

const event = document.createEvent('HTMLEvents');
// 参数意义和new Event一样
event.initEvent(type, bubbles, cancelable);

«Серый» означает «неизвестный», но вы можете использовать его с уверенностью, потому что часть «v-model» исходного кода vue2.6 используется во многих местах.createEventОписание должно быть совместимо с ie9.

Совместимый код

function dispatchDOMEvent(el, payload, eventInit){
    let event;
    if (void 0 !== Event) {
        event = new Event(type, eventInit);
    } else {
        event = document.createEvent('HTMLEvents');
        event.initEvent(type, eventInit?.bubbles, eventInit?.cancelable);
    }
    return el.dispatchEvent(event);
}

Исходный код:GitHub.com/any86/anyi-he…

Мои приложения

На самом деле такой способ работы с Vue тоже случайное открытие, он не сложный, но вообще я об этом не думаю.

я сделал✋ Библиотека жестовТаким образом, это работает с "v-on" под vue:

✋ Библиотека жестов:GitHub.com/any86/anyi-he…

🔥Серия курсов Typescript

Если вы заинтересованы в ts, добро пожаловать в мой базовый учебник по ts.

Первый урок, опыт машинописи

Урок 2, Основные типы и вводные расширенные типы

Урок 3, Общие сведения

Урок 4. Интерпретация расширенных типов

Урок 5. Что такое пространство имен

Специальная статья, изучайте машинопись в исходном коде vue3🔥🦕 - "есть"

Урок 6, что такое файл декларации? 🦕 - Глобальная декларация

Обучение интерфейсу для начинающих 🔥 машинописный текст - настоящий бой, полноэкранный браузер (59 строк)

Группа WeChat

Спасибо за чтение, если у вас есть какие-либо вопросы, вы можете добавить меня в WeChat, я приглашу васГруппа WeChat(Из-за ограничения Tencent на 100 участников в группах WeChat после того, как более 100 участников должны быть привлечены участниками группы)