• Как загрузить картинку в VUE3?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Подстановка путей к динамическим ассетам осуществляется на этапе сборки. Со строками из js сборка напрямую не работает.

    1. Ты можешь сделать так:
    import Wordpress from '../assets/wordpress-logotype-wmark.png';
    import Bitrix from '@/assets/logotip/1c_bitrix_logo.svg.png';
    const brandImgs = {
      '1C Bitrix': Bitrix,
      Wordpress,
    };

    По сути сделать руками то, что делает сборщик vue с src под капотом.

    2. Ты можешь просто сразу положить иконки в папку /public и указывать не относительные пути в рамках проекта, а абсолютные от корня:
    const brandImgs = {
      '1C Bitrix': '/logotip/1c_bitrix_logo.svg.png',
      'Wordpress': '/logotip/wordpress-logotype-wmark.png',
     };


    3. Ты можешь использовать динамический import().

    4. Ты можешь использовать import.meta.glob в vite или require.context в webpack.
    (Тут стоит помнить, что все ограничения упомянутые для п.3 применимы и здесь.)
    Ответ написан
  • Как внутри state использовать связанные элементы?

    Aetae
    @Aetae
    Тлен
    Используй getters, оно именно для этого и предназначено. Точно также как computed в самом vue.
    export default createStore({
      state: {
        list1: [],
      },
      getters: {
        list2(state) {
          return state.list1.filter(...) 
        }
      }
    })


    P.S. И да, нахрен vuex, используй pinia.
    Ответ написан
    Комментировать
  • Flex-grow 1 не работает, что делать?

    Aetae
    @Aetae
    Тлен
    Ну так а с чего бы ему что-то прижимать? Они вообще в разных блоках и никак не связаны.
    Ну и flex-grow это не про "прижимание", это про "заполнение имеющегося места".

    Чтобы что-то "прижимало" .twitter_swipe тебе надо .twitter__row слать flex column, не забыть задать высоту и задать уже для .twitter__body flex-grow.
    Ответ написан
    1 комментарий
  • Не могу понять, что не так с innerHTML?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Судя по ошибкам "JSX expressions must have one parent element," и "Uncaught SyntaxError: Unexpected token '<'" у вас где-то кусок html кода вне строки.
    Т.е. прям <какоц-то тег> ... вместо '<какоц-то тег> ...'.
    Код из вопроса должен работать без проблем.
    Ответ написан
    Комментировать
  • Как удалить теги style?

    Aetae
    @Aetae
    Тлен
    Почему ты не можешь повлиять на бэкэнд? Парсишь небось?
    Причём тут реакт? Реакт рисует элементы и стили на лету, а не получает их с бэкэннда.

    Если таки с бэка приходит html строка, которая потом вставляется через dangerouslySetInnerHTML то предварительно её почистить можно так:
    function removeStyles(html) {
      const container = document.createElement('div');
      container.innerHTML = html;
      container.querySelectorAll('style').forEach(
        style => style.remove()
      );
      return container.innerHTML;
    }


    Если ты пуляешь напрямую чужой реакт код, то тут два варианта:
    1. Делать как указал Даниил , только при этом ещё и динамически, дожидаясь пока реакт их нарисует, для чего придётся использовать MutationObserver или банальный setTimeout. Однако в таком случае стили могут успеть отрисоваться до удаления, из-за чего может происходить мерцание.
    2. Лезть глубже в исходники и патчить: подменять react функции работы со стилями, или даже тупо document.createElement, отфильтровая ненужный style. Но всё это уже требует понимания.:)
    Ответ написан
    Комментировать
  • Как правильно реализовать передачу данных между не связанными друг с другом компонентами в vue3?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Если ты не используешь SSR, то тебе достаточно просто reactive/ref объекта, чтоб получить эрзац-стор, тупо:
    // где-нибудь 
    export const basket = reactive([]); // или ref([]) по вкусу. 
    // везде где надо
    import { basket } from './...'

    Реактивность будет прекрасно работать.

    Почему кто-то использует специальные store если можно делать так? Потому что сторы учитывают работу в режиме SSR, а также позволяют удобную отладку в случае множества запутанных связей.
    Вам я бы тоже рекомендовал использовать таки store - только pinia, а не vuex. Не вижу причин его не использовать.

    По поводу EventBus: с одной стороны новичку её использовать категорически не рекомендуется, т.к. работа со store куда удобнее, очевиднее и надёжнее. Однако и совсем отрицать её использование тоже не следует, шина отлично подходит для случаев когда мы имеем дело именно с событиями, а не изменением состояния. Т.е. послать какой-нить notification или лог - самое оно, использовать для изменения basket, как в вашем случае - нет.
    Ответ написан
    1 комментарий
  • Как получить токен из заголовков ответа в js?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    1. no-cors на клиенте это не "отключение cors", иначе не было никакого смысла в cors, это метка "мне похрен на ответ, я просто отправляю". Соответственно с такой меткой ты не можешь читать ответ никак.
    2. Если при обычном запросе возникакет ошибка cors - значет сервер не посылает allow-* заголовков и cors не разрешён.
    3. Заголовок Set-Cookie ставит, очевидно, cookie. Напрямую его читать в любом случае нельзя.
    3.1. Но можно читать поставленную cookie
    3.1.1. Но читать её можно только на том домене доя которого она поставлена.
    3.1.2. Читать её можно только если она не (как в данном случае) HTTP-only.
    5. Возможно вам и не нужно ничего ни откуда доставать: HTTP-only куки передаются браузером в запросе самостоятельно, из скрипта к ним доступа нет. Однако он и не нужен. Отправляйте все запросы с credentials: "include" и значение автоматически будет присутствовать в заголовке Cookie..
    Ответ написан
    Комментировать
  • Решил сделать часы со стрелкой и поворот стрелки запилил с помощью transform: rotate (deg). Это нормально?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Оно не должно накручиваться на самом то деле - положение стрелки должно чётко зависеть от текущего времени и больше ничего. Полагаться на таймауты и интервалы - нельзя, браузер не гарантирует их чёткое временное выполнение.

    Чтоб стрелка двигалась плавно - использовать надо requestAnimationFrame.
    Ответ написан
    Комментировать
  • Как исправить ошибку Module not found с версией react-scripts 5?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    compilerOptions.path влияет только собсно на "красные подчёркивания", tsconfig никак не управляет настоящими путями.
    Тебе надо руками прописывать alias в конфиге webpack.
    Ответ написан
    6 комментариев
  • Почему не работает таймер когда наступает новый час?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Открываешь консоль и видишь там красный текст "hours is undefined" или типа того. Понимаешь, что у тебя в коде задано не hours, а h, исправляешь и не отвлекаешь людей тупыми вопросами.

    P.S. Для таймера правильно использовать Date, время исполнения setInterval может быть изменено со стороны браузера или из-за нагрузки.
    Ответ написан
  • Как использовать директивы внутри кастомных директив в nuxt 3?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Встроенного механизма наследования нет. Директивы - это уже продвинутый механизм, подразумевается, что раз уж вы взялись за директивы - вы глубоко понимаете механизмы Vue. Если вам сильно хочется таки использовать чужую директиву внутри своей, надо будет самостоятельно экспериментировать, навскидку вижу два варианта:
    1. "тупой", но точно работающий - пробрасывать все возможные хуки директивы напрямую:
    const myDirective = {
      created(el, binding, vnode, prevVnode) {
         otherDirective?.created(el, binding, vnode, prevVnode);
         ...
      },
      beforeMount(el, binding, vnode, prevVnode) {
         otherDirective?.beforeMount(el, binding, vnode, prevVnode);
         ...
      },
      ....
    }

    2. "умный", но требующий знаний и экспериментов - манипуляции напрямую с vNode.

    Однако, возможно, лучше будет сделать просто-компонент-обёртку, который просто навесит все нужные директивы на обёрнутый компонент, примерно так:
    import { useSlots, withDirectives, resolveDirective } from 'vue'
    
    export default {
      setup() {
        const htmlDirective = {
          mounted(el, html) {
            el.innerHTML = html.value
          }
        }
    
        const colorDirective = {
          mounted(el, color) {
            el.style.color = color.value
          }
        }
        
        // const someDirective = resolveDirective('some-directive');
    
        const slots = useSlots();
    
        return () => withDirectives(slots.default()[0], [
          [htmlDirective, 'some html'],
          [colorDirective, 'red'],
        ])
      }
    }

    <wrapper><some-compnent /></wrapper>
    Ответ написан
    1 комментарий
  • Как нарисовать картинку в canvas?

    Aetae
    @Aetae
    Тлен
    let img = new Image()
    // создали Image, пока ничего не происходит
    
    img.src = "path/to/img.jpg"
    // установили src - пошла загрузка картинки
    
    ctx.drawImage(img, x, y);
    // нарисовали на канвасе сраное ничто
    
    // идёт загрузка картинки
    // идёт загрузка картинки
    // идёт загрузка картинки
    // идёт загрузка картинки
    // идёт загрузка картинки
    // идёт загрузка картинки
    // идёт загрузка картинки
    
    // картинка загрузилась, вызвано событие img.onload
    Ответ написан
    1 комментарий
  • Как правильно задать относительный путь до файла?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Зависит от того какую систему сборки используете.
    Например для webpack можно использовать ContextReplacementPlugin\NormalModuleReplacementPlugin, чтоб пофиксить пути импорта как вам надо, в т.ч. относительные.
    Однако, если обойтись без относительности, то плагин не нужен: можно просто прописать alias вида
    '@locale': path.resolve(__dirname, `src/${LOCALE}/js/register.js`)
    Ответ написан
    Комментировать
  • Почему условие в setInterval не всегда срабатывает?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Очевидно потому, что значение '00:01' проскакивает между вызовами setInterval.

    Почему?
    Во-первых: потому что 1000 в параметрах ничего не гарантирует, перерыв может быть больше - в двух случаях:
    1. если выполнение вызываемой функции происходит дольше интервала(не наш случай);
    2. если вкладка не активна, все современные браузеры сильно замедляют таймеры(самая вероятная причина).
    Во-вторых: числа меняются какой-то другой функцией и совершенно неизвестно как там работает таймер.
    Ответ написан
  • Как вызвать функцию при посещение страницы?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Оба варианта должны работать - первый при полной загрузке, второй при загрузке DOM(и наличии jquery на странице).
    Есть ещё более прямой и очевидный вариант, запуск "прям тут где скрипт": <script>функция();</script>, но раз не помогли предыдущие, то и этот не поможет.

    Вопрос: что значит "не помогло", конкретно?

    Пока могу только нагадать: возможно у тебя в этой функции открывается новое окно, тогда ответ простой - никак, окна можно открывать только по действию пользователя.
    Ответ написан
    Комментировать
  • Как через код использовать ctrl+wheel?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Никак. Со своим зумом пользователь работает сам и не тебе его менять.
    Если нужно изменить какие-то размеры - меняй эти размеры.

    Если для каких-то особых целей надо имитировать поведение при других расширениях, этого можно добиться масштабируя фрейм через transform scale и его размеры, как это делает codepen.
    Ответ написан
    Комментировать
  • Верный ли алгоритм для фильтра товаров?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Нормально. Источником состояния должно быть только одно место: в данном случае этим источником выступает url.
    Ответ написан
    Комментировать
  • Как удалить элемент массива при клике на кнопку?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    @click="deleteTodo(todo)"
    
    deleteTodo(todo) {
      this.todos.splice(this.todos.indexOf(todo), 1);
    }

    Или
    v-for="(todo, index) in todos"
    @click="deleteTodo(index)"
    
    deleteTodo(index) {
      this.todos.splice(index, 1);
    }
    Ответ написан
    Комментировать
  • Как посчитать количество объектов с определённым значением ключа?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Не прибегая к циклам - ручкой на листочке, лол.
    Любой вариант, какой бы вы не выбрали сводится к циклам под капотом.
    arr.filter(obj => !obj.status).length;
    arr.reduce((length, {status}) => status ? length : length + 1, 0);
    ...и т.п.
    Ответ написан
    1 комментарий
  • Можно ли передавать CSS классы через props?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Передавать класс в props можно, многие библиотек так делают, но осторожно и только когда без этого не обойтись.

    Особенно стоит обратить внимание на это при использовании scoped стилей: переданный внутрь класс не будет работать сам по себе, т.к. привязан к scope родительского компонента, придётся использовать псвевдоселектор :deep(), а это уже чревато коллизиями.

    Лучше же разбить всё на максимально небольшие компоненты с простыми api конфигурации и повсеместно использовать слоты, чтобы такие вещи не требовались слишком часто.
    Ответ написан
    2 комментария