• Не работает Vue.use(Vuex) в файле store.ts, как исправить?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    В Vue 3 нет никакого Vue.use(), теперь все плагины ставятся не глобально, а в конкретное приложение:
    import { createApp } from 'vue'
    import { createStore } from 'vuex'
    
    // Create a new store instance.
    const store = createStore({
      state () {
        return {
          count: 0
        }
      },
      mutations: {
        increment (state) {
          state.count++
        }
      }
    })
    
    const app = createApp({ /* your root component */ })
    
    // Install the store instance as a plugin
    app.use(store)
    (из официальной документации vuex)

    Ну и modelair верно сказал - теперь топят за pinia вместо vuex, что и к лучшему, так как по сути выкинули весь оверинжинирнутый мусор из vuex оставив только осмысленный функционал.
    Ответ написан
    Комментировать
  • Как хешируется пароль в админке роутера?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    С гарантией - надо копаться в исходниках, как предложил Сергей delphinpro.
    Однако перед этим я бы зашёл на первый попавшийся в гугле онлайн-хэшер(например) и захэшировал проверочное слово, результат чего сравнил бы с вариантом из админки. Почти наверняка используется какая-то стандартная хэш функция, и тебе достаточно на глаз её узнать.
    Ответ написан
    Комментировать
  • Как сделать следующий эффект для background?

    Aetae
    @Aetae
    Тлен
    Чуть более сложно чем нужно тебе:



    Упростишь сам, если надо.)
    Ответ написан
    Комментировать
  • Как сделать фабрику миксинов?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Без вариантов. Мешать классы в ts незя, потому что он как и js не поддерживает множественное наследование. Все методы сбоку через прототипы - не подразумевают работу с классами.
    Помимо того что сам js физически не даст тебе работать с нативными приватными свойствами(#), так уже ts не даст тебе работать нормально с приватными и защищёнными(private и protected), а микс абстрактных (abstract) вообще забагован и не работает(issue у них пару лет висит на гитхабе).

    В общем только крайне ограничено.
    Ответ написан
  • Как импортировать переменные в react?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ну в принципе можно как с любыми переменными - вынести за компонент, и даже будет работать, но так делать не надо.)

    Нормальное решение - использовать context всесто ref. Сверху где-то его Provider зафигачить, а где надо useContext.
    Ответ написан
    Комментировать
  • Почему тайпскрипт неправильно считывает тип?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Скорее всего поможет перегрузка, что-то типа:
    function getSkills(params: TGetSkills['requestParams']): TGetSkills['response'];
    function getSkills(params: TGetSkillsWithCriterions['requestParams']): TGetSkillsWithCriterions['response'];
    function getSkills(
        params: (TGetSkills | TGetSkillsWithCriterions)['requestParams'],
      ) {
        return instance.get<(TGetSkills | TGetSkillsWithCriterions)['response']>('url', {
          params: params,
        }),
    }
    
    getSkills: getSkills
    Ответ написан
    1 комментарий
  • Как правильно подгружать динамические изображения во Vue.js?

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

    Для решения подобных задач два варианта:
    1. require.context - который соберёт все файлы по предоставленному шаблону на этапе компиляции, и на этапе исполнения будет их подставлять. Этот вариант подходит если в папке img уже сейчас лежат все нужные изображения.
    2. Если изображения на этапе компиляции отсутствуют, а появляются каким-то сторонним образом в паке потом, то require тебе тут не нужен(и не поможет), просто динамически подставляй пути к ним как в твоём первом варианте.
    Путь от корня, если что, можно получить из __webpack_public_path__:
    root: __webpack_public_path__,
    <img :src="root + 'img/' + message.filename" :alt="message.filename"/>
    Ответ написан
    4 комментария
  • Как реализовать DI как в ангуляре?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Во первых DI в js\ts - полная бессмысленная хуита. Просто импортируй по-человечески что надо и используй.

    Но если очень хочется - это сложно. Механизм DI не предусмотрен в парадигме языка. Тебе придётся использовать свою особую надстройку над системой сборки, которая найдёт в файлах подобные DI и заменит их на обычные человеческие импорты. Сделать можно это тремя основными способами: как трансформермер для typescript, как трансформермер для babel и как кастомный loader для webpack. Во всех случаях это включает в себя работу с AST и кодогенерацию на этапе сборки.

    Впрочем, в залежах npm наверняка можно нарыть что-то готовое, чтоб не писать самому.
    Ответ написан
  • Как получить значение внутри функции при нажатии кнопки?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Если changeTab не может примать async функцию(функцию возвращающую Promise) то никак. Ожидание действия пользователя - асинхронная операция. Тебе надо изменить логику поведения.

    Иначе: система диалогов должна быть в любом случае вынесена в отдельный компонент, а в идеале вообще во внутренние вызовы, типа:
    const result = await modal({
      title: ...,
      type: 'confirm',
      acceptText: 'Подтвердить',
      ...
    })


    Но если что-то колхозить, то условно так:
    showPopup() {
      this.isDialogShown = true;
      this.pending = new Promise((resolve) => {
        this.discardChanges = () => resolve(false);
        this.saveChanges = () => resolve(true);
      });
    },
    async changeTab() {
      ...
      return await this.pending;
    }

    Ну или прямо так:
    changeTab() {
      return new Promise((resolve) => {
        this.discardChanges = () => resolve(false);
        this.saveChanges = () => resolve(true);
      });
    }


    Но я бы так делать не стал, а таки вынес нормально всё, ибо один компонент должен выполнять ровно одну функцию и его логика не должна просачиваться в иные.
    Ответ написан
    4 комментария
  • Как сравнить значение с ключом объекта?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Твой index - и есть в данном случае ключ. Т.е. проверять нужно просто index === 'dateTime'.

    Опережая возможный вопрос - если тебе нужен именно цифровой индекс, то в случае с объектом на входе он будет третьим параметром:v-for="(filter, key, index) in filters". Однако в твоём случае он не нужен, т.к. лучше привязывать key именно к ключу.

    В vue всё для людей.)
    Ответ написан
    1 комментарий
  • После отключения правила eslint ругается prettier, как предотвартить?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    prettier - это одно, eslint - это другое, если у тебя prettier подключается через eslint, то настройки для него указываются скопом, условно так:
    rules: {
        'prettier/prettier': ['warn', {
          semi: false,
          ...
          singleQuote: true,
          vueIndentScriptAndStyle: true,
          arrowParens: 'avoid',
          trailingComma: 'none',
          quoteProps: 'consistent',
        }],
    Ответ написан
    Комментировать
  • Как резольвить алиасы у скаченного через package.json репозитория?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Очевидно что пакет битый или ты подключаешь что-то не то.
    В готовой либе никаких алиасов быть не должно, на то она и готовая.

    Можно что-то нашаманить, но в каждом конкретном случае своё, потому что в любом случае через жопу.
    Ответ написан
    Комментировать
  • Как не дублировать компонент с похожими данными?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    const options = computed(() => {
      if (props.secondType) 
        return props.secondTypeItems.map(({ id, value}) => ({
          label: value,
          value: id 
        }));
    
      if (props.thirdType) 
        return props.thirdTypeEvents.map(({ desc, name }) => ({
          label: name,
          value: desc 
        }));
    
      // ...
    
      return [];
    });


    <el-select
          v-model="modelText"
          placeholder="Выберите предмет"
          @change="changeVal"
        >
          <el-option
            v-for="{ label, value} in options"
            :key="value"
            :label="label"
            :value="value"
          >
            {{ label }}
          </el-option>
        </el-select>
    Ответ написан
    Комментировать
  • Почему во Vue3 не срабатывает computed, когда меняется ref?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Во первых:
    import { computed, ref } from "vue";

    Во-вторых:
    <Input type="number" :value="count" @change="changeCount"/>


    Дальше при нормальных данных и компонентах должно работать, однако возможно энтот твой Input в change возвращает не значение, а event, тут хз сам смотри.
    Ответ написан
    3 комментария
  • Почему на разных версиях ноды по разному устанавливаются зависимости?

    Aetae
    @Aetae
    Тлен
    Скорее всего дело в либах которые требуют бинарников, а не только чистого js: такие либы сильно зависят как от версии ноды так и от окружения, и имеют готовые бинарники под какие-то популярные(или старые) версии. Если готовых бинарников под версию ноды\окружение нет - он будет пытаться оные собрать, но для этого нужно много всякого мусора и подготовки, потому оно скорее крашнется чем соберётся.)
    Ответ написан
    Комментировать
  • Какая лучшая практика организации css в проекте react?

    Aetae
    @Aetae
    Тлен
    Можно использовать css-modules.
    Можно оставить твой подход, просто пользоваться БЭМ и scss, называя корневой класс по имени компонента(тогда конфликтов никаких не будет).
    Решения css-in-js типа styled - популярны, но как по мне - ересь и грязь.
    Ответ написан
    Комментировать
  • Почему сервер получает пустые данные?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Откуда ты эту хрень взял?
    axios.post('http://localhost:5000/api/create-post', () => {
      body: data
    })
    Во-первых: axios принимает параметром объект, а не функцию возвращающую объект.
    Во-вторых: axios.post вообще сразу принимает body:
    axios.post('http://localhost:5000/api/create-post', data)

    В-третьих: даже если бы оно принимало функцию(что не так) - конструкция
    () => {
      body: data
    }
    на самом деле расшифровывается так:
    () => { // начало блока кода
      // метка body указывающий на висящую в воздухе переменную data
      body: data
      // никакого возврата из функции
    } // конец блока кода
    чтобы оно воспринималось как объект, можно, например, заключать в скобки:
    () => ({
      body: data
    })
    Ответ написан
    5 комментариев
  • Можно ли программно отрендерить vue компонент передав шаблон и параметры?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Vue работает с DOM, а не со строковым представлением.
    Тупо смонтируй компонент в скрытый div и забери из него innerHTML.

    Условно:
    // версия с рантайм компилятором шаблонов
    import { createApp } from 'vue/dist/vue.esm-bundler.js'; 
    
    function renderVueComponent(template, data) {
      const div = document.createElement('div');
      
      createApp({
        template,
        data: () => data
      }).mount(div);
    
      return div.innerHTML;
    }
    Ответ написан
    Комментировать
  • Как правильно объединить два типа HTMLElement?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ответ Александр хорошо работает если есть дискриминатор (в приведённом примере поле type).

    Если же такого уникального поля нет, то конкретно для React можно сделать на перегрузках, условно:
    type ExtraProps = {
      size?: 's' | 'm' | 'l';
    }
    
    type AnchorProps = ExtraProps & {href: string};
    type ButtonProps = ExtraProps & {type: string};
    
    function TappableComponent(props: AnchorProps ): ReactNode; 
    function TappableComponent(props: ButtonProps ): ReactNode;
    function TappableComponent(props: AnchorProps | ButtonProps ) {
         const Component = 'href' in props ? 'a' : 'button';
         return <Component>...</Component>
    }

    Там множество подводных камней, но иногда удобно.
    Ответ написан
    Комментировать
  • TypeScript ругается на getAttribute('href'). Как получить href ссылки?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ради ускорения сборки из коробки не предусмотрено сложной типизации событий. Одно время события имели сложную типизацию на дженериках, но оную вкинули из ts. (Что весьма меня расстраивает, могли бы и оставить как отдельную настройку, для тех кому плавная типизация важнее скорости.)

    Тебе остаётся только кастовать типы руками, увы. Причём рекомендую в данном случае использовать currentTarget а не target, потому что target может оказаться например span внутри этой ссылки, а не она сама.
    Ответ написан