Сводка динамических компонентов и глобальной привязки событий, вызванных случаем Vue

внешний интерфейс контейнер Vue.js

Недавно я изучил некоторые основные способы использования Vue для самостоятельного изучения, а также сделал несколько заметок. Заинтересованные друзья могут ознакомиться с другими моими статьями. На самом деле технология — это не просто чтение. Только в реальных проектах мы можем обнаружить проблемы. , обнаружить точки знаний, которые мы не освоили, а затем обнаружить и решить проблемы, и тогда наши способности могут быть улучшены.

Основываясь на этой идее, я начал сам создавать туристический сайт.Туристические сайты не могут обойтись без выбора города, поэтому я буду записывать некоторые проблемы и решения при реализации списка выбора городов, чтобы сегодня подвести итоги.

компонент выбора списка городов

Во-первых, давайте поговорим о том, какой компонент выбора города мы хотим реализовать:

  1. Когда поле ввода получит фокус, отобразите компонент
  2. Нажмите на список городов, чтобы обновить отображение города в поле ввода.
  3. Щелкните другие пустые части, чтобы скрыть компоненты
  4. Выбранный город сохраняется, а не сбрасывается при переключении на другие компоненты

Давайте разберем это шаг за шагом

первый шаг

Отобразить компонент после того, как поле ввода получает фокус, очень просто. Мы привязываем событие фокуса к полю ввода, а затем передаем состояние отображения компоненту. Мы передаем isShowCityList компоненту выбора города, чтобы управлять поведением.

<el-input 
    @focus="isShowCityList=true"
    placeholder="请输入目的地">
</el-input>

второй шаг

Мы не делаем слишком много выражений.В этой статье мы хотим представить привязку динамических компонентов и глобальных событий, использование дочерних компонентов для родительских компонентов и использование пользовательских событий $emit для передачи родительским компонентам.

третий шаг

Нам нужно нажать на другие места, где компонент города скрыт.Первое впечатление некоторых студентов может состоять в том, чтобы использовать событие размытия ввода (то есть событие потери фокуса), пока наш ввод теряет фокус, мы его скрываем .

На самом деле, мое первое впечатление такое же, но после того, как мы привязываем событие потери фокуса ввода, когда мы выбираем список городов, это также происходит, когда ввод теряет фокус, поэтому мы не можем выбрать город. Очевидно, что такой образ мышления неприемлем.

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

Мы делаем следующее в функции монтируемого хука.

mounted() {
    document.addEventListener("click", e => {
        console.log('全局事件被触发');
        if (!this.$refs.searchCity.contains(e.target)) {
            this.isLoadCityList = false;
        }
    });
}

ОК, после этого шага наша проблема решена, пока мы щелкаем за пределами этого контейнера, компонент списка городов будет скрыт, я думал, что это закончилось, но это невозможно, или я слишком молод, чтобы сделать это. следствием этого является то, что независимо от того, где мы нажмем, это вызовет это событие, даже когда мы переключимся на другие компоненты, событие все равно будет запущено, очевидно, это не то, что мы хотим, потому что текущее событие будет запускаться бесконечно, что, несомненно, дайте нам принести непредвиденные проблемы.

Наилучший эффект, который нам нужен, определенно заключается в том, что текущее глобальное событие работает под текущим компонентом.Когда мы переключаемся на другие компоненты, событие автоматически удаляется, поэтому я мог бы подумать об использовании функции-ловушки beforeDestroy для удаления этого глобального события. То есть, когда мы переключаемся на другие компоненты, чтобы удалить это глобальное событие.

beforeDestroy() {
    document.removeEventListener("click", () => {
      //...
    });
}

Как вы думаете, я смогу решить проблему таким образом? Очевидно, все еще не можем или слишком молоды, просто мы не можем отменить привязку события, так что же нам делать? На самом деле там яма, большая яма, потому что я не знаю эту большую яму, и я проверил много информации и не могу ее найти, потому что способ проверки неправильный, и, наконец, я спросил большой парень в группе, чтобы получить ответ, я должен сказать, что общение со старшими очень важно, это может помочь вам избежать многих ловушек.

Если вы хотите освободить событие здесь, две функции обратного вызова освобождения и привязки должны быть одинаковыми.Что это значит? Посмотри на код и все поймешь. Если вы этого не сделаете, вы не сможете удалить событие.Что касается более глубоких причин, то я не очень в этом разбираюсь.Информацию проверю позже.

methods: {
  isSearchCityNode(e) {
    if (!this.$refs.searchCity.contains(e.target)) {
      console.log("全局事件被触发");
      this.isLoadCityList = false;
    }
  }  
},
mounted() {
    document.addEventListener("click", this.isSearchCityNode);
},
beforeDestroy() {
    document.removeEventListener("click", this.isSearchCityNode);
}

четвертый шаг

Нам нужно сохранить город, который мы выбираем при переключении компонентов. Если мы не будем сохранять город, который мы выбираем каждый раз, когда мы переключаемся на другие компоненты, выбранный нами город будет сброшен до значения по умолчанию. Этот опыт определенно плохой, и это не то, что мы хотим.

Причина сброса заключается в том, что каждый раз, когда мы переключаемся между разными компонентами, компоненты будут заново создаваться и уничтожаться, что также приведет к повторяющимся проблемам с рендерингом, не благоприятствующим производительности.

Итак, как нам справиться с этой проблемой? Я использовал поддержку активности здесь, чтобы решить эту проблему, так как же следует использовать поддержку активности и какова ее функция?

<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

При обертывании динамического компонента неактивные экземпляры компонента кэшируются, а не уничтожаются, он не отображает элемент DOM сам по себе и не появляется в цепочке родительских компонентов.

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

активировано: вызывается при активации компонента поддержки активности.

deactivated: вызывается, когда компонент поддержки активности деактивирован.

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

activated() {
    document.addEventListener("click", this.isSearchCityNode);
},
deactivated() {
    document.removeEventListener("click", this.isSearchCityNode);
}

Суммировать

В случае компонента списка городов он представляет, как мы связываем глобальные события и оптимизируем их в Vue, Мы должны помнить, что в привязке и выпуске событий есть большая дыра.

Мы можем создать кешируемый компонент с помощью , и мы добавим две функции ловушки для использования.

Если в тексте есть какие-то неточности, милости просим великого бога сделать кирпич!