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

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Ответ очевиден - не использовать недокументированные* свойства типа __vueParentComponent.:)

    Раз ты используешь options api у тебя есть this.$parent для родительского компонента или ты можешь использовать ref для выбора конкретного.

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

    * Работа в режиме разработки и в режиме продакшена очень сильно отличается. Даже если ты видишь какие-то свойства в консоли, то, если они не документированы, значит полагаться на то, что ни будут там всегда - ни в коем случае нельзя. Особенно на явно помеченные как внутренние через нижнее подчёркивание.
    Ответ написан
    Комментировать
  • Можно ли передать нужный тип переменной в дженерик функции?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    getFormattedData тоже должен быть дженерик и собсно его(дженерик) прокидывать в нижестоящие.

    Типа того:
    type Type1 = 1;
    type Type2 = 2;
    type Type3 = 3;
     
    type ContainsType<T extends UniversalType = UniversalType> = {type: T};
    
    type UniversalType = Type1 | Type2 | Type3;
    
    
    class Cls {
      async getFormattedData<T extends UniversalType>(data: ContainsType<T>): Promise<T> {
            const anyDataObject = this.validateData(data);
            const result = this.formatDataByType(anyDataObject);
            return result;
      }
    
      validateData<T extends UniversalType = UniversalType>(data: ContainsType<T>): T {
        return data.type
      }
    
      formatDataByType<T extends UniversalType = UniversalType>(data: T): T {
        return data
      }
    
    }
    const foo = await new Cls().getFormattedData({type: 2}); // 2


    Если ты явно чему-то пропиваешь тип который никак не зависит от входного дженерика:
    const anyDataObject: Type1 | Type2 | Type3 = ...
    то какбэ всё - приехали, ты сам указал, что тут именно такой тип(во всём его многообразии) и пофиг на входные данные. Ты можешь дальше сузить тип внутри метода:
    if (anyDataObject === 2) {
      // тут anyDataObject для ts считается Type2
    }
    но это уже никак не повлияет на выходной тип.

    В общем выводить типы можно только если они зависят от входных данных(которые в свою очередь получаются через дженерик), иначе откуда TS узнает, что там от чего зависит.
    Если ты заранее даже приблизительно не знаешь, что придёт на вход, то и что пойдёт на выход ты ноже не знаешь, а не знаешь ты - не знает и, тем более, TS: там просто одни произвольные данные превратились в другие без использования логики. С тем же успехом можно попытаться вывести точный тип Math.random().
    Ответ написан
    Комментировать
  • Не видит значение input, как исправить?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Во-первых у input нет свойства length.
    var intxt=document.querySelector('input').length;
    intxt === undefined
    console.log вообще-то должен был тебе это показать.

    Далее: if(intxt.length<5){ тут ты пытаешься получить свойство length у unefined о чем тебе и пишет ошибка.

    Скорее всего ты хочешь что-то такое:
    var intxt=document.querySelector('input');
    ....
    if(intxt.value.length<5){
      ....
    } else {
    Ответ написан
    Комментировать
  • Почему пушатся коммиты которые я не делал в ветке?

    Aetae
    @Aetae
    Тлен
    Не бывает совсем "новых" веток - все ветки откуда-то растут.
    Если в запушеной ветке два коммита вместо одного, значит один из них уже был в той ветке, от которой вы отпочкованли "новую".
    Ответ написан
    Комментировать
  • Как убрать ободок от фона средствами CSS при использовании border-radius?

    Aetae
    @Aetae
    Тлен
    У тебя тут: .swiper-slide.category-banner__card::before чёрный background. Он и просвечивает.

    .swiper-slide.category-banner__card::before {
      background-color: transparent;
    }
    Ответ написан
  • При сборке к имени картинок добавляется хеш и картинки не отображаются. Как указывать путь к картинкам?

    Aetae
    @Aetae
    Тлен
    React - это тебе не Vue, он не умеет из коробки угадывать, что картинки надо импортировать.

    Для каждой картинки надо сделать руками:
    import img from './assets/img.jpeg'
    или использовать glob import.

    Ну либо положить картинки в public и брать их как есть по прямым путям относительно корня без всяких хэшей.

    Подробнее.
    Ответ написан
    Комментировать
  • Как расширить дженерик MutableRefObject добавив в него новое свойство?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ну какбэ очевидно, что:
    interface MutableRefObject<T> {
      prev: null | HTMLParagraphElement; 
    }


    Если интeрфейс в либе, то:
    declare module 'lib-name' {
      interface MutableRefObject<T> {
        prev: null | HTMLParagraphElement; 
      }
    }

    Или, хуже:
    declare module 'lib-name/full/path/to/declaration.ts' {
      interface MutableRefObject<T> {
        prev: null | HTMLParagraphElement; 
      }
    }


    Но вообще, если для себя то делай так:
    interface MySuperMutableRefObject extends MutableRefObject<T> {
      prev?: null | HTMLParagraphElement; 
    }

    и не трогай библиотечный тип.
    Ответ написан
    6 комментариев
  • Можно ли сделать так, чтобы картинка которая прижата к правому краю экрана(с помощью position: absolute) не обрезалась при адаптирование?

    Aetae
    @Aetae
    Тлен
    Не прижимать её к правому краю с поморью absolute, вестимо.
    Например: положи во флекс и прижми с помощью flex-end. Потом моешь поставить ей max-width: полный размер, min-width: минимальный - чтоб сжималась если не влезает...
    Тащем верстай.
    Ответ написан
    Комментировать
  • При решении каких задач используют генераторы?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    В практике генераторы не используются. Конец. :)

    На самом деле я лично видел ровно два практических кейса использования генераторов:
    1. Использование для асинхронных операций с возможностью прерывания, примеры: redux-saga, mobx actions.
    Суть: допустим ты делаешь какую-то ступенчатую операцию, и нужна возможность резко остановить исполнение извне. На async-ax тебе придётся городить что-то типа:
    async function multiStep() {
      await step1();
      if (stop) throw new Error(stop);
      await step2();
      if (stop) throw new Error(stop);
      await step3();
      if (stop) throw new Error(stop);
    }
    и никак красивее не сделать.
    На генераторе ты можешь просто писать:
    function* multiStep() {
      yield step1();
      yield step2();
      yield step3();
    }

    и просто не брать следующее значение, если исполнение прервалось.

    2. До появления воркеров с их помощью можно было работать с очень большими массивами не вызывая зависания страницы.

    На этом всё.:)
    Ответ написан
    2 комментария
  • Почему в готовых шаблонах bootsnrap не подключают через cdn?

    Aetae
    @Aetae
    Тлен
    Возможно ты имеешь ввиду CDN?

    В таком случае всё зависит от преимуществ и недостатков, рассмотрим основные:
    Серьёзный недостаток: cdn под контролем третьей стороны: он может быть скомпрометирован, он может прекратить работу, он может тормозить.
    Потенциальное преимущество: cdn от крупных компаний может быть быстрее, т.к. сервера могут втыкаться прямо в точки обмена трафика и дублироваться максимально близко к пользователю.
    Устаревшее главное преимущество: раньше библиотека с cdn кэшировалась раз и навсегда для всех сайтов оную использующих. Закэшировал на одном сайте - на другом она уже в кэше. Увы, все современные браузеры "ради безопасности" реализуют cache partitioning или что-то подобное, где для каждого сайта свой кэш, что полностью исключает данное преимущество.

    Итого, в современном вебе недостаток перевешивает.
    Ответ написан
    3 комментария
  • Как использовать один компонент с разными типами данных?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Наверное ты хочешь этого:
    type Props = { data?: ITemplate } | {}
    const CreateTemplateForm: FC<Props> = (props) => {
      if ('data' in props && props.data) {
        
        return ...;
      }
    
      return ...;
    }
    Ответ написан
    5 комментариев
  • Как оптимизировать сайт под большие экраны?

    Aetae
    @Aetae
    Тлен
    Все ребята с большими экранами давно научились нажимать Ctrl++. Если ты хочешь тупо такое же масштабирование, то не надо*.

    Смысл что-то делать есть только если настоящий дизайнер разумно что-то придумает специально под такой масштаб.

    * Если очень хочется, то немного математики + transform: scale + изменение ширины скроллбаров, но результат будет - херня.:)
    Ответ написан
    Комментировать
  • Как добавить готоую форму amoCrm в Vue3?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Я хз что такое AmoCrm, но если надо тупо добавить не-vue скрипы как vue-компонент, то как-то так:
    import { ref, h } from 'vue';
    
    function loadScript(options, root = document.head) {
      return root.appendChild(Object.assign(document.createElement('script'), options));
    }
    
    const Comp = defineComponent(() => {
      const root = ref(null);
    
      onMounted(() => {
        loadScript(
          {
            innerHTML: `
          !(function (a, m, o, c, r, m) {
        (a[o + c] = a[o + c] || {
            setMeta: function (p) {
                this.params = (this.params || []).concat([p]);
            },
        }),
            (a[o + r] =
                a[o + r] ||
                function (f) {
                    a[o + r].f = (a[o + r].f || []).concat([f]);
                }),
            a[o + r]({
                id: "....",
                hash: "....",
                locale: "ru",
            }),
            (a[o + m] =
                a[o + m] ||
                function (f, k) {
                    a[o + m].f = (a[o + m].f || []).concat([[f, k]]);
                });
    })(window, 0, "amo_forms_", "params", "load", "loaded");
          `
          },
          root.value
        );
        loadScript(
          {
            id: 'amoforms_script_...',
            async: 'async',
            charset: 'utf-8',
            src: 'https://forms.amocrm.ru/forms/assets/js/amoforms.js?...'
          },
          root.value
        );
      });
    
      return () => h('div', { ref: root });
    });
    Ответ написан
  • Как запустить реакт код без локального сервера или как его получить?

    Aetae
    @Aetae
    Тлен
    Забудь о фронте без локального сервера. Это время ушло.
    Сейчас для локальных файлов столько ограничений, что работать с этим даже на чистом html уже толком невозможно.
    Ответ написан
  • Для чего мемоизируют аутентификацию?

    Aetae
    @Aetae
    Тлен
    На самом деле useMemo нужен, чтобы при передаче значения как prop в низлежащий memo компонент не происходила перерисовка оного если не было изменений(+при передаче как зависимость в другой хук, тот не срабатывал заново).
    Стоит упустить хотя-бы одно место требующее useMemo и пойдёт водопадом перерисовка на каждый чих каждого компонента по всему дереву вниз. И именно это является основной причиной тормозов в React, а не какие-то там мифические сложные вычисления.

    Официальная позиция React: "говнокодь сейчас, оптимизируй потом", действительно предполагает использование useMemo "только в узких местах" и нигде больше. Прикол в том, что с таким подходом при разрастании проекта никакого "узкого места" просто нет, тормозить начинает просто потому, что складываются тысячи микротормозов от тысяч перерисовок тысяч компонентов: наступает то самое "потом" и тут придётся переписывать с useMemo чуть ли не весь проект, чтоб снизить эти тормоза.
    Именно по этому в реальной работе useMemo стараются таки использовать заранее в каждом месте, где оно потенциально нужно. Некоторые радикальные философии вообще предполагают использование useMemo просто всегда, без исключений.:)
    Ответ написан
    3 комментария
  • Видит ли работодатель мой трафик?

    Aetae
    @Aetae
    Тлен
    Выше ребята не упомянули ещё один момент: зачастую для работы с внутренней сетью в месте с VPN прилетает и свой DNS. Т.е. если даже весь трафик не идёт через vpn, а только рабочий - работодатель всё равно видит какие DNS запросы ты делал, т.е. имена посещаемых сайтов(без полной ссылки - только домены).
    Соответственно если в рабочее время от тебя запросы только на youtube да 9gag то можно сделать выводы.:)

    Занимается ли этим шпионажем работодатель на самом деле - это уже другой вопрос.
    Ответ написан
    2 комментария
  • Не получается подключить js файл через CDN, в чём может быть проблема?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Как надо: открываешь ссылку с библиотекой(например https://unpkg.com/tictic@0.1.0/) руками и находишь там версию UMD или без специальных пометок - это именно та что тебе нужна.
    ***
    ESM/ES/ES6 версия - это версия на модулях, её можно использовать только внутри script type="module" через import(никаких глобальных вызовов).
    CJS версия - это версия на Common JS, старого стандарта Node js, в браузере ты её использовать не сможешь без специального загрузчика.
    ***
    После этого копируешь себе ссылку убирая из неё /browse.

    В данной конкретной библиотеке НЕТ версии для обычного подключения через скрипт. Тебе остаётся либо использовать модуль, либо использовать систему сборки фронтэнда(vite, webpack, rollup, gulp...), либо отказаться от неё.

    P.S. С модулями оно будет выглядеть примерно так:
    <script type="importmap">
      {
        "imports": {
          "tictic": "https://unpkg.com/tictic@0.1.0/esm/index.js",
          "tslib": "https://unpkg.com/tslib@2.6.2/tslib.es6.js"
        }
      }
    </script>
    
    <script type="module">
      import { getDate } from 'tictic';
    
      console.log(getDate({}));
    </script>

    Как видишь тут пришлось добавить ещё и tslib, т.к. у tictic от неё зависимость, хорошо что только одна. Зачастую зависимостей целая куча и проще таки использовать системы сборки, чем все их прописывать руками.
    Так же стоит помнить что модули - это только для современных браузеров.
    Ответ написан
    Комментировать
  • Как компонент реакта понимает, что к нему привязали хук?

    Aetae
    @Aetae
    Тлен
    Простой ответ: глобальные переменные.:)
    React просто перед самим запуском устанавливает глобальную (условно) переменную указывающую на текущий исполняющийся компонент, на которую и смотрит в сою очередь хук. Именно потому хуки нельзя использовать вне компонента.
    Вот тут я упрощённо изобразил, что дальше происходит внутри useState.

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

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Для самого свежего хрома можно обойтись css:
    [role="row"]:has(.fraud) {
      background-color: #f1f7bc;
    }

    Для иных браузеров можно использовать такую извращенную классику(с оговорками):
    [role="row"] {
      position: relative;
      background-color: transparent;
    }
    [role="row"] .fraud::before {
      content: "";
      display: block;
      position: absolute;
      z-index: -1;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      background-color: #f1f7bc;
    }


    Ну либо использовать MutationObserver и следить за появлением новых [role="row"].
    Ответ написан
    Комментировать
  • Возможно ли на собрать такой блок на css, но что бы он тянулся в зависимости от содержимого?

    Aetae
    @Aetae
    Тлен
    Просто делаешь примитивную svg-картинку бэкграундом или встроеенно и растягиваешь на весь размер блока.

    Если хочется извращений - можно псевдоэлементом с трансформацией:
    Ответ написан
    3 комментария