Задать вопрос
  • Как рендерить определенную разметку в зависимости от условия?

    0xD34F
    @0xD34F Куратор тега React
    switch(this.props.cardType) {

    Нет, так не надо. Лучше сделайте объект, где ключами будут вот эти cardType, а значениями - вынесенные в отдельные компоненты куски кода из case'ов. Тогда логика выбора что рендерить сократится до... В общем, совсем коротко и просто получится:

    const Component = components[this.props.cardType];
    return Component && <Component {...this.props} />;

    https://jsfiddle.net/ptm0zay7/1/
    Ответ написан
    Комментировать
  • Как получить атрибут в Vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Используйте ref. В шаблоне, например:

    <div data-bullshit-attribute="hello, world!!" ref="div"></div>

    В коде:

    const attrValue = this.$refs.div.getAttribute('data-bullshit-attribute');

    Одно непонятно - а какого чёрта сразу не положить нужное значение в data, зачем атрибут читать?
    Ответ написан
    3 комментария
  • Как правильно написать повторяющийся код?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const caesar = (str, offset) => Array
      .from(str, n => String.fromCharCode(n.charCodeAt(0) + offset))
      .join('');
    
    const caesarTemplate = (title, offset) => `
      <div class="caesar">
        <textarea class="caesar-input" data-offset="${offset}"></textarea>
        <hr>
        <p>${title}: <span class="caesar-output"></span></p>
      </div>
    `;
    
    document.addEventListener('input', ({ target: t }) => {
      if (t.matches('.caesar-input')) {
        const output = t.closest('.caesar').querySelector('.caesar-output');
        output.innerHTML = caesar(t.value, +t.dataset.offset);
      }
    });
    
    document.body.insertAdjacentHTML('beforeend', [
      [        'Шифр',  3 ],
      [ 'Расшифровка', -3 ],
    ].map(n => caesarTemplate(...n)).join(''));
    Ответ написан
    Комментировать
  • Почему геттер во Vuex при изменении не обновляет компонент?

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

    Расскажите, что вы ожидаете увидеть, и что реально видите. А то в показанном вами коде никаких проблем, связанных с обновлением, разглядеть не удаётся.
    Ответ написан
    3 комментария
  • Как вернуть все содержимое в тегах html без самих тегов c помощью JS?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const text = (el => (el.innerHTML = html, el.innerText))(document.createElement('div'));

    или

    const text = new DOMParser().parseFromString(html, 'text/html').body.textContent;

    или, получаем содержимое каждого текстового узла отдельно:

    const fragment = document.createRange().createContextualFragment(html);
    const iter = document.createNodeIterator(fragment, NodeFilter.SHOW_TEXT);
    const texts = [];
    for (let n; n = iter.nextNode(); texts.push(n.nodeValue)) ;
    Ответ написан
    Комментировать
  • Очистить от options Select в vue.js в новой строке?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Не надо ничего очищать. Пусть у каждого элемента будут собственные options. В шаблоне второго селекта меняете
    v-for="o in getOptions2(index)" на v-for="o in user.options"; в обработчик change первого селекта передаёте текущий объект: @change="changeUser(user)", и соответственно, полученные данные кладёте в этот объект вместо options2 (их просто вырезаете):

    changeUser(user) {
      fetch('https://jsonplaceholder.typicode.com/photos')
        .then(r => r.json())
        .then(d => this.$set(user, 'options', d));
    },
    Ответ написан
    1 комментарий
  • Как правильно сделать регулярку с переменной?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Уберите слэши, они тут не нужны - просто new RegExp(tags, 'gi').
    Ответ написан
    Комментировать
  • Как сделать чтобы JS "отрабатывался" в нескольких блоках сайта?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Сделать функцию, которая будет принимать в качестве параметров элемент/селектор и текст, который надо отобразить. Как-то так.
    Ответ написан
    1 комментарий
  • Регулярка проверки на число с первой известной цифрой?

    0xD34F
    @0xD34F Куратор тега Регулярные выражения
    И зачем тут регулярные выражения? Если у вас число - то и проверяйте его как число. Трёхзначное число, начинающееся с 3 - это >= 300 и < 400.

    Но вообще - 3\d{2}. Или ^3\d{2}$. Или \b3\d{2}\b. В зависимости от того, каковы входные данные, и что надо получить в результате.
    Ответ написан
    1 комментарий
  • Почему jQuery в template (vue) ничего не находит?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Потому что нечего находить - ваш шаблон не существует в DOM-дереве (при сборке компилируется в render-функцию); искать элементы вы пытаетесь в хуке created, это слишком рано, создание экземпляра vue и его монтирование происходит не единовременно - используйте хук mounted.
    Ответ написан
    3 комментария
  • Как ждать первоначального наполнения стора перед загрузкой страницы?

    0xD34F
    @0xD34F Куратор тега Vue.js
    В хуке App.vue выглядит не очень уместно, хочется вынести эту логику в другое место.

    Это какую такую логику? У вас там в created будет простой вызов экшена, это одна строка. Уместно, делайте.

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

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

    Можете в своём main.js завернуть создание экземпляра vue в коллбек экшена, который загружает данные:

    store.dispatch('получитьДанные').then(() => {
      new Vue({
        el: '#app',
        store,
        router,
        ...

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

    <div v-if="данные в хранилище есть">
      основной контент приложения
    </div>
    <div v-else>
      данные загружаются, надо подождать
    </div>
    Ответ написан
  • Как мне в модальном окне сделать прокрутку вниз?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Во-первых - никаких getElementById, ставьте ref на интересующий вас элемент.

    Во-вторых - если вам надо сделать прокрутку в самый низ, не надо указывать какое-то определённое число. У элемента есть свойство scrollHeight.

    Во-третьих - надо дождаться, пока будет показан дополнительный контент, и только потом выполнять прокрутку, т.е., используйте nextTick:

    this.$nextTick(() => {
      const el = this.$refs.container;
      el.scrollTop = el.scrollHeight;
    });

    И второй вопрос, если у меня в реальном проекте при таком коде не спускается никак, потому что идет погрузка через вкладки и используется keep-alive.

    Информации примерно 0. Что за вкладки, где используется keep-alive... Ничего непонятно.

    Если в keep-alive завёрнуто ваше окно, то выполняйте проверку this.show и прокрутку (можно вынести этот код в отдельный метод, чтобы не дублировать) и в хуке activated.

    UPD. https://codesandbox.io/s/vue-template-ow505
    Ответ написан
  • Как подключить Vuetify?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Вместо гамбургера отображается надпись "Меню"

    Нужно подключить иконочный шрифт. Как это сделать - можете прочитать в документации.
    Ответ написан
  • Можно ли во vuex писать mutation через Object.assign?

    0xD34F
    @0xD34F
    Можно.

    Только разберитесь, что это за штука такая, Object.assign, что делает. А то вы явно чего-то не до конца понимаете, судя по показанному коду. Ну и имейте в виду, что если какое-то из свойств payload отсутствует в стейте, то после добавления оно не будет реактивным.
    Ответ написан
    1 комментарий
  • Не показывать в списке select выбранные значения vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Вместо того, чтобы зашивать в шаблон варианты выбора, делаете массив и отдаёте его в v-for, предварительно прогнав через функцию-фильтр, где будут отброшены уже выбранные варианты (кроме текущего):

    <select v-model="user.name">
      <option value="">Выбрать</option>
      <option v-for="o in getOptions(index)" :value="o.value" v-text="o.label"></option>
    </select>

    getOptions(index) {
      return this.options.filter(o => this.users.every((u, i) => u.name !== o.value || i === index));
    },

    https://jsfiddle.net/gs0oenxq/
    Ответ написан
    4 комментария
  • Как по клику убрать класс у элемента и добавить предыдущему/следующему?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Добавляем кнопкам атрибут, который будет указывать относительную позицию нового активного элемента:

    <span class="prev" data-step="-1">Prev</span>
    <span class="next" data-step="+1">Next</span>

    Индекс нового активного элемента будет суммой индекса текущего и относительного положения нового. Чтобы произошёл переход из конца в начало - необходимо брать остаток от деления суммы на количество элементов, индекс несуществующего элемента, расположенного за последним, превратится в 0. Переход из начала в конец - в случае jquery ничего делать не надо, метод eq позволяет указывать отрицательные индексы, которые используются для отсчёта позиции элемента начиная с конца; в случае чистого js надо будет добавить к сумме количество элементов, чтобы потенциальное отрицательное значение стало положительным, и при этом не изменился остаток от деления.

    const itemSelector = 'li';
    const buttonSelector = '[data-step]';
    const activeClass = 'active';

    $(buttonSelector).click(function() {
      const { step } = this.dataset;
      const $items = $(itemSelector);
      const $active = $items.filter(`.${activeClass}`);
    
      $active.removeClass(activeClass);
      $items.eq(($active.index() + +step) % $items.length).addClass(activeClass);
    });
    
    // или
    
    const items = document.querySelectorAll(itemSelector);
    let index = 0;
    
    document.querySelectorAll(buttonSelector).forEach(n => {
      n.addEventListener('click', onClick);
    });
    
    function onClick({ currentTarget: { dataset: { step } } }) {
      items[index].classList.remove(activeClass);
      index = (index + items.length + +step) % items.length;
      items[index].classList.add(activeClass);
    }
    Ответ написан
    1 комментарий
  • Как сверстать такой элемент?

    0xD34F
    @0xD34F
    .xxx {
      background: silver;
      display: inline-flex;
      justify-content: center;
      align-items: center;
      font-size: 24px;
      padding: 0.3em 0.6em;
      position: relative;
    }
    
    .xxx::before {
      content: "";
      width: 1em;
      height: 1em;
      left: -0.2em;
      top: -0.2em;
      background: orange;
      position: absolute;
      z-index: -1;
    }

    https://jsfiddle.net/km85s9fv/
    Ответ написан
    Комментировать
  • Как сделать, чтобы обновлялся компонент при переходе по router-link?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Отслеживайте в компоненте изменения параметра роута:

    watch: {
      '$route.params.id': {
        immediate: true,
        handler() {
          /*
           * здесь идёт выполнение каких-то действий,
           * направленных на обновление компонента - запрос данных, например...
           * тут уж вам виднее, что это должно быть
           */
        },
      },
    },
    Ответ написан
    Комментировать
  • Почему метод Vue.js срабатывает дважды?

    0xD34F
    @0xD34F Куратор тега Vue.js
    запрос на сервер отправляется два раза, хотя есть переменная, которая это блокирует

    Нет такой переменной. Есть переменная, которая могла бы в подобном качестве использоваться - loading, если проверять в начале метода upload, что она не true - но она не используется никак (по крайней мере, в показанном вами огрызке кода).

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

    есть переменная end, статус которой проверяется постоянно

    А какой смысл в этой проверке, если вы сбрасываете значение end в false сразу после того, как выставили true? Можно дожидаться выполнения запроса - перенеся this.end = false в finally (однако, само по себе это не гарантирует, что вы не сможете отправлять следующий запрос до окончания предыдущего).
    Ответ написан