WedX - журнал о программировании и компьютерных науках

Не удается получить доступ к этому объекту из-за сложной функции js - Vuejs

Я работаю с популярным компонентом vue-select для проекта VueJs. Я хочу настроить keyDownEvent и просмотрел документы, чтобы узнать, как этого добиться. Меня встретил загадочный пример с использованием комбинации современных методов JS.

<template>
  <v-select
          taggable
          multiple
          no-drop
          :map-keydown="handlers"
          placeholder="enter an email"
  />
</template>

<script>
export default {
  name: 'CustomHandlers',
  data: {
      variableIwantAccessTo: []
  },
  methods: {
    handlers: (map, vm) => ({
      ...map, 50: e => {
        e.preventDefault();
        if( e.key === '@' && vm.search.length > 0 ) {
          vm.search = `${vm.search}@gmail.com`;
        }
      },
    }),
  },
};
</script>

Я понимаю простую логику блока if, но не понимаю комбинацию используемых методов, которая приводит к этому. Основная проблема, с которой я столкнулся в своей пользовательской реализации, — это потеря контекста для объекта this. Я хочу что-то вроде этого:

    handlers: (map, vm) => ({
  ...map, 50: e => {
    e.preventDefault();
    if( e.key === '@' && vm.search.length > 0 ) {
      console.log(this.variableIwantAccessTo);
    }
  },

Я не могу понять, как передать это с этой реализацией. Вот ссылка на документы: https://vue-select.org/guide/keydown.html#mapkeydown


  • О, vm — это не экземпляр Vue, как я думал. Вам нужно будет изменить handler: (map, vm) => ({/*...*/}) на handler(map, vm) { return {/*...*/} }, где вы сможете использовать this в качестве экземпляра Vue. 04.12.2020
  • Я попробовал это с ответами Eason Yus, и он регистрируется как неопределенный даже сразу в начале первой функции стрелки. 04.12.2020
  • Я не могу помочь, не видя код, который вы пробовали. Вот рабочая демонстрация, как я описал: codepen.io/tony19/pen/ExgPEKV 04.12.2020
  • Ах да, я бы тоже так написал. На самом деле я сам решил это прямо перед вашим сообщением, используя функцию() {}, а не обозначение стрелки. 04.12.2020

Ответы:


1

как вы видите, на самом деле в этом случае есть два уровня функций, исходный стиль функции обработчика опускает {}, поэтому у вас нет места для определения себя (ссылки на это) во внешней функции.

в компоненте vue это во внешнем будет указывать на компонент, поэтому мы объявляем себя здесь, затем мы используем self как дисперсию закрытия во внутреннем.

Я думаю, это поможет вам, попробуйте, пожалуйста.

export default {
  name: 'CustomHandlers',
  methods: {
    // handlers: (map, vm) => {
    // if it is arrow function,it can't do the trick 
    // thanks to  Yair Cohen
       handlers(map, vm) {
        const self = this;
        return {
          ...map, 50: e => {
            e.preventDefault();
            if( e.key === '@' && vm.search.length > 0 ) {
              vm.search = `${vm.search}@gmail.com`;
              // self will be this here
              const self2 = self;
            }
          },
        };
    },
  },
};

обновление: изменен код, внешняя функция со стрелки на нормальную функцию,

04.12.2020
  • журналы undefined в консоли :/ 04.12.2020
  • Это по-прежнему не будет работать, поскольку функция обработчиков является функцией стрелки, а не обычной, поэтому она все еще не определена. Если вы измените его на обычную функцию, она будет работать 04.12.2020
  • да, вы правы, я только что сделал демо, чтобы проверить свой код, я отредактирую его на случай, если кто-то ошибется. 04.12.2020
  • Спасибо @YairCohen за разбор функции и tony19 за рабочий пример с использованием this. В конце концов я сам пришел к результату после использования этого ответа и недавно столкнулся с этой проблемой в другом проекте. Для тех, кто еще не знает, проверьте этот раздел в документах vuejs. org/v2/guide/instance.html#Instance-Lifecycle-Hooks 04.12.2020

  • 2

    Разберем эту функцию:

    1. Вы объявляете стрелочную функцию с именем handlers, которая принимает два аргумента с именами map и vm.

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

    С учетом сказанного кажется, что это специально разработано таким образом, и, глядя на код, я могу предположить, что вы должны передавать контекст в качестве второго аргумента - vm.

    1. Вы возвращаете объект: в первой части объекта вы используете оператор распространения для распространения аргумента map, из этого мы можем предположить, что map также является объектом, и вы хотите вернуть объект, содержащий саму карту объектов. (используя оператор распространения, вы, по сути, объединяете map с возвращаемым объектом.

    Вторая часть объекта, который вы возвращаете, представляет собой свойство с именем 50, это свойство представляет собой метод, который получает событие, вызывает preventDefault() для этого события, затем имеет оператор if, если этот оператор if проходит, он присваивает vm.search объекту определенное значение.

    Поскольку мы предположили, что vm означает контекст, это то же самое, что и присвоение this.search, поэтому, по сути, это присваивание переменной в контексте определенного значения.

    Надеюсь, теперь стало понятнее :)

    04.12.2020
  • Технически вам не нужно this в обработчике событий. Элемент this обычно указывает на доступный из переданного объекта события. 04.12.2020
  • Только если это обычная функция, со стрелочной функцией это будет равно значению this из объемлющей области видимости, которая в данном случае все еще не определена. 04.12.2020
  • Ну, да, this, которое вы получаете в стрелочной функции, — это то, что унаследовано от контекста, если оно существует. Я хочу сказать: не используйте this в обработчике событий; использовать объект события. Нет необходимости переключаться на обычную функцию. 04.12.2020
  • @YairCohen Правильно ли я думаю, что после первой функции со стрелкой есть функция самовызова? Почему он обернут ()? И обычно я согласен с намерениями Уроборуса, но объект vm не тот объект, который мне нужен. Я пытаюсь сослаться на переменную в родительской области самого экземпляра Vue, записанную как «this.vairableName». 04.12.2020
  • Нет, после первой функции со стрелкой нет самовызывающейся функции, круглые скобки есть, потому что именно так вы возвращаете выражение с несколькими строками. Ознакомьтесь с дополнительными примерами того, как это работает: stackoverflow.com/questions/20824558/ 04.12.2020
  • @YairCohen Не совсем так. Скорее, это неявный возврат стрелочной функции для литерала объекта. Объект необходимо заключить в круглые скобки, чтобы синтаксический анализатор мог отличить его от оператора блока. 04.12.2020
  • @tony19 Верно, так точнее. 04.12.2020
  • Новые материалы

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

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

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


    Для любых предложений по сайту: [email protected]