Задать вопрос
  • Почему шина событий не слышит событие?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Возможная причина номер раз - в тот момент, когда вы делаете emit события, отсутствует экземпляр компонента, где вы пытаетесь его слушать.

    Возможная причина номер два:

    bus.$off('selectedCompanies')

    Толково придумано. Давайте представим, что создаётся два... нет, лучше пять экземпляров компонента. Затем один удаляется. Вопрос - сколько после этого останется обработчиков события selectedCompanies? Думаете, что четыре? А вот и нет - ни одного. Надо всё-таки указывать, какой именно обработчик вы удаляете.

    Наконец, возможная причина номер три:

    Есть 2 независимы страницы.

    Очень надеюсь, вы подразумеваете не разные вкладки/окна браузера.
    Если всё-таки да...

    ...ну, поздравляю - чего-то вы в этой жизни не понимаете, от слова совсем. Нет реакции на событие потому, что шин у вас две - и ничего они друг о друге не знают. В этом случае вам нужна не шина, а надо как-то пересылать информацию между вкладками. Для этого можно использовать localStorage (есть плагины для vuex под это дело, можете погуглить), или BroadcastChannel.
    Ответ написан
  • Почему при поиске вылезает TypeError: Cannot read property 'toString' of null?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Какое-то из свойств объекта оказалось null'ом. Почему бы не добавить проверку перед toString'ом - что именно вы собираетесь преобразовывать? Может и не надо перегонять null'ы в строки, может, в этом случае результат поиска сразу отрицательный должен быть. Ну или преобразовывайте в строку как-нибудь иначе, варианты разные есть: ('' + m) или `${m}` или String(m).

    А вообще, вы конечно поторопились вот так в лоб использовать первый попавшийся код. Вон, у вас там ещё и вложенные объекты есть, по их свойствам поиск корректно работать не будет (т.к. дефолтное строковое представление объекта - это '[object Object]') - об этом вы подумали? Нет, точно надо проверять, что за значение:

    return this.sortedTokens_VMP.filter(n => Object.values(n).some(m => {
      if (m instanceof Object) {
        // проверяем объект, возможно, стоит сделать какую-нибудь рекурсивную функцию под это дело
      } else if (typeof m === 'number') {
        // а вдруг числа надо обрабатывать иначе, чем строки
      } else {
        // какая-то дефолтная проверка значения
      }
    }));

    UPD. А сортировка, сортировка-то - тоже ведь ерунда получится при работе с null'ами и вложенными свойствами.

    Вот как всё будет:

    Рекурсивная функция, которая проверяет, есть ли где во вложенных объектах указанная строка:

    const includes = (obj, str) => Object
      .values(obj)
      .some(n => n instanceof Object
        ? includes(n, str)
        : `${n}`.toLowerCase().includes(str)
      );

    Используем её внутри вычисляемого свойства, представляющего отфильтрованные данные:

    filteredTokens_VMP() {
      const s = this.search.toLowerCase();
      return this.sortedTokens_VMP.filter(n => includes(n, s));
    },

    Функция, извлекающая вложенное значение по строке, где ключи разделены точками:

    const getNested = (root, path) => path
      .split('.')
      .reduce((p, c) => p != null ? p[c] : p, root);

    Используем её в вычисляемом свойстве, представляющем отсортированные данные, если попадается nullish значение, будем загонять соответствующий элемент в конец:

    sortedTokens_VMP() {
      const reverse = this.sort.reverse ? -1 : 1;
      return this.tokens_VMP
        .map(n => [ getNested(n, this.sort.key), n ])
        .sort(([a], [b]) => reverse * (
          a == null ?  Infinity :
          b == null ? -Infinity :
          a < b     ?        -1 :
          a > b     ?         1 :
                              0
        ))
        .map(n => n[1]);
    },
    Ответ написан
  • Как организовать поиск во Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    вот пример - https://codepen.io/pespantelis/pen/ojwgPB?editors=1010,
    но здесь используется версия vue/0.12.16/vue.min.js

    Нет проблем переписать с использованием актуальной версии vue.
    Ответ написан
    1 комментарий
  • Почему некорректно работает условие проверки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Что если пользователь введёт значение, которое нельзя привести к числу? Получите NaN, этот случай у вас никак не обрабатывается.

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

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

    let count = null;
    while (1) {
      count = prompt('Введите количество колонок для таблицы умножения') | 0;
      if (count > 0) {
        break;
      }
      alert('Введите корректное число');
    }
    Ответ написан
    Комментировать
  • Почему вылезает ошибка "Uncaught TypeError: Cannot read property '0' of undefined"?

    0xD34F
    @0xD34F Куратор тега JavaScript
    lat + x != 11

    lon + y != 11

    А 10, стало быть, является допустимым значением, да? И это значение вы используете в качестве индекса массива, чей размер - тоже 10. Толково придумано, ничего не скажешь.
    Ответ написан
    1 комментарий
  • Почему возникает ошибка "unknown action type"?

    0xD34F
    @0xD34F
    Потому что нет экшена. Что непонятного-то? Раз нет, а вызывать надо - добавьте его.

    UPD. Вынесено из комментариев:

    я понял, что нет экшена. Вопрос в том, что он есть )

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

    Какие могут быть варианты:
    • Вместо actions засунули его в mutations
    • Допустили опечатку - вместо actions написали anctions или action или actons или...
    • Забыли подключить модуль, в котором экшен находится
    • Неправильно вызываете - экшен находится в namespaced модуле
    • ...

    Проверяйте код своего хранилища, думайте.
    Ответ написан
  • Как можно упростить декодирование кода морзе?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const decodeMorse = code => code
      .trim()
      .split('   ')
      .map(n => n.split(' ').map(m => MORSE_CODE[m]).join(''))
      .join(' ');

    или

    const decodeMorse = code => code
      .trim()
      .replace(/\S+ ?/g, m => MORSE_CODE[m.trim()])
      .replace(/  /g, ' ');
    Ответ написан
    Комментировать
  • Как сделать микшер цветов на vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Создадим объект, который будет содержать компоненты цвета:

    colorComponents: {
      r: 0,
      g: 0,
      b: 0,
    },

    На основе этого объекта создадим элементы управления значениями компонентов цвета:

    <div v-for="(v, k) in colorComponents">
      {{ k }}
      <input v-model="colorComponents[k]" type="range" min="0" max="255">
      {{ v }}
    </div>

    И стилизуем какой-нибудь элемент, вычисляя итоговый цвет:

    <div :style="style">

    computed: {
      style() {
        return {
          'background-color': `rgb(${Object.values(this.colorComponents).join(',')})`,
        };
      },
    },

    jsfiddle.net/o1xe8gmk/1
    Ответ написан
    Комментировать
  • Как лучше реализовать выбор не более скольких-то элементов из списка по клику?

    0xD34F
    @0xD34F Куратор тега JavaScript
    При клике проверяем, у скольких элементов класс уже есть, если максимум достигнут - класс не добавляем:

    const itemSelector = '.item';
    const activeClass = 'active';
    const maxActive = 3;
    const onMaxActiveClick = () => alert(`больше ${maxActive} нельзя`);
    
    
    // делегирование, назначаем обработчик клика один раз для всех элементов
    document.addEventListener('click', function(e) {
      const item = e.target.closest(itemSelector);
      if (item) {
        const active = document.querySelectorAll(`${itemSelector}.${activeClass}`);
        if (active.length < maxActive || item.classList.contains(activeClass)) {
          item.classList.toggle(activeClass);
        } else {
          onMaxActiveClick();
        }
      }
    });
    
    // или, назначаем обработчик клика каждому элементу индивидуально
    let activeCount = 0;
    
    for (const n of document.querySelectorAll(itemSelector)) {
      n.addEventListener('click', onClick);
      activeCount += n.classList.contains(activeClass);
    }
    
    function onClick({ currentTarget: item }) {
      if (activeCount < maxActive || item.classList.contains(activeClass)) {
        activeCount += item.classList.toggle(activeClass) ? 1 : -1;
      } else {
        onMaxActiveClick();
      }
    }
    Ответ написан
    Комментировать
  • Почему иногда выходит ошибка " Uncaught TypeError: Cannot read property '3' of undefined "?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кажется, кто-то не в курсе, что индексация массивов начинается с нуля.

    Ну нет у вас ни в одном из массивов элемента с индексом 10, нет. Соответственно, когда lon принимает значение 10, map[lon] оказывается undefined, отсюда и ошибка.
    Ответ написан
    1 комментарий
  • Почему не работает ngModel?

    0xD34F
    @0xD34F
    А не многовато ли у вашего ngModel скобок?
    Ответ написан
    Комментировать
  • Можли ли продолжить всплытие собственных событий в vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    А можно ли как то прокинуть это событие далее(всплытие), что бы можно было его прослушать на любом компоненте-предке, в том числе и на корневом?

    Вручную в каждом компоненте делайте emit, или гуглите, как сделать шину событий (event bus) - можно будет подписываться на нужное событие где угодно.
    Ответ написан
    1 комментарий
  • Не работает radio checked?

    0xD34F
    @0xD34F Куратор тега CSS
    В чем ошибка?

    В том, что вы почему-то решили не разбираться, как именно работает используемый вами инструмент.

    Поменяйте input и span местами - будет работать как вам нужно.
    Ответ написан
    Комментировать
  • Как обновлять ссылку на элемент после использования drag&drop?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Делегируйте обработку событий, и тогда не придётся беспокоиться о пропавших обработчиках. Как-то так.
    Ответ написан
    7 комментариев
  • Как создать калькулятор из таблицы?

    0xD34F
    @0xD34F
    Есть таблица
    <...>
    Может быть, можно упростить

    Можно. Вернее, не надо было ничего усложнять - перенесли бы вашу таблицу в код как она была. Двумерный массив. Первый индекс соответствует месяцу (надо только будет вычесть единицу из того, что введёт пользователь), второй возрасту (а здесь, соответственно, вычесть 18). Вся логика со switch'ами ужмётся до одной строчки.
    Ответ написан
    5 комментариев
  • Как сделать подстановку из массива с ключом из регулярного выражения?

    0xD34F
    @0xD34F Куратор тега Регулярные выражения
    $text = preg_replace_callback("/\{a (\d+)\}/", function($matches) use($routes) {
      return "<a href=\"".$routes[$matches[1]]."\">";
    }, $text);
    Ответ написан
    Комментировать
  • Как отфильтровать активные чекбоксы?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const getCheckedValues = elements =>
      [...elements].reduce((acc, n) => (
        n.checked && (acc[n.name] = acc[n.name] || []).push(n.value),
        acc
      ), {});

    Если пустые группы тоже должны присутствовать, то

    const getCheckedValues = elements =>
      Array.prototype.reduce.call(
        elements,
        (acc, { name, value, checked }) => (
          acc[name] = acc[name] || [],
          checked && acc[name].push(value),
          acc
        ),
        {}
      );
    Ответ написан
    Комментировать
  • Как вытащить числа из строки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const numbers = (string.match(/-?\d+(\.\d+)?/g) || []).map(Number);
    
    // или
    
    const numbers = string.split(' ').map(parseFloat).filter(Number.isFinite);
    Ответ написан
    3 комментария
  • Почему mouseout не так работает?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Всё работает так, как и должно. Чтобы получить требуемое поведение, надо обрабатывать другие события:

    @mouseenter="showDrop = true"
    @mouseleave="showDrop = false"

    UPD. А зачем два свойства для управления отображением форм? Они что, могут показываться одновременно? Может, лучше сделать одно свойство, которое будет содержать имя показываемой формы? Как-то так:

    data: () => ({
      showForm: 'auth',
      // ...
    }),

    Форма авторизации: v-show="showForm === 'auth'", @click="showForm = 'reg'".
    Форма регистрации: v-show="showForm === 'reg'", @click="showForm = 'auth'".
    Ответ написан
    1 комментарий