Задать вопрос
Ответы пользователя по тегу Vue.js
  • Как обернуть выбранный элемент в другой, или построить вокруг него конструкцию из элементов DOM методами Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    <div class="wrapper" v-if="надо рендерить обёртку">
      ...
      <элемент />
      ...
    </div>
    <элемент v-else />

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

    0xD34F
    @0xD34F Куратор тега CSS
    Время, которое я задаю, применяется к fadeOut, а вот к runProgress нет

    Окей, посмотрим на эти fadeOut и runProgress:

    this.fadeOut = `fadeOut ${this.time}s linear forwards`,
    this.runProgress = `runProgress ${this.time}s liner forwards`,

    Вам вопрос: чем отличаются эти две строки (конечно, помимо имён анимаций)?

    UPD. А это вообще нормально - всем назначать одно и то же значение? В смысле, в шаблоне эти fadeOut и runProgress используются для задания анимации элементам, у которых есть предок с v-for. Если изменить значение свойства time и добавить в messages новый элемент, то у тех, что были добавлены раньше, изменится длительность анимации. Наверное, стоит вырезать свойства fadeOut и runProgress, элементам messages при создании добавлять актуальное значение свойства time, типа time: this.time, и использовать его при задании стилей:

    methods: {
      getStyle: (name, { time }) => ({
        animation: `${name} ${time}s linear forwards`,
      }),
      ...

    :style="getStyle('fadeOut', message)"

    :style="getStyle('runProgress', message)"
    Ответ написан
    1 комментарий
  • Как выводить варианты ответов в случайном порядке?

    0xD34F
    @0xD34F Куратор тега Vue.js
    function shuffle(arr) {
      for (let i = arr.length; i > 1;) {
        const j = Math.random() * (i--) | 0;
        [ arr[i], arr[j] ] = [ arr[j], arr[i] ];
      }
    
      return arr;
    }

    computed: {
      shuffledAnswers() {
        return shuffle(Object.entries(this.questions[this.idx].answers));
      },
      ...

    <div v-for="[ key, answer ] in shuffledAnswers">
      ...

    UPD. Конечно, вопрос был не об этом, но есть ряд замечаний по поводу показанного кода.

    "answers": {

    Пусть это будет массив. Соответственно, правильный ответ будет обозначаться через индекс.

    import usersData from "../questions.json";

    Не надо импортировать вопросы в компоненте теста, пусть они передаются в него через props.

    selectedAnswer: "",

    Всего один? Этого мало, надо запоминать все полученные ответы.

    count: 5,

    <div v-if="idx < count">

    Если завтра добавятся новые вопросы или удалятся какие-то из существующих, побежите изменять значение этого свойства? Оно не нужно, надо смотреть на длину массива с вопросами. Или, можно сделать вычисляемое свойство, представляющее текущий вопрос (просто извлекаем элемент из массива с вопросами по индексу текущего вопроса), и проверять, существует ли он.

    computed:{
      randomQuestions () {
        usersData.sort(() => Math.random() - 0.5)

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

    :disabled="selectedAnswer != ''"

    Блокировать выбор ответа не надо - вдруг пользователь случайно не туда нажал. Пусть будет возможность изменить сделанный выбор. Это касается не только ответов на текущий вопрос, а всех, т.е., в дополнение к

    <button
      @click="nextQuestion"

    надо сделать такую же кнопку для перехода к предыдущему вопросу.

    document.querySelectorAll("input").forEach((el) => (el.checked = false));

    Не надо лезть в DOM руками. Чтобы при переходе к следующему вопросу сбрасывать выбор, достаточно пересоздавать элементы, назначив их общему предку ключ, зависящий от индекса (:key="индекс_вопроса"). Но это, конечно, костыльное решение. Правильно будет управлять радиокнопками основываясь на данных, через v-model.

    @change="answered($event)"

    answered(e) {
      this.selectedAnswer = e.target.value;
      if (this.selectedAnswer == this.questions[this.idx].correctAnswer) {
        this.correctAnswers++;

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

    https://jsfiddle.net/0L9ayx1u/1/
    Ответ написан
    1 комментарий
  • Почему не могу перейти к странице по прямому адресу?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Потому что документацию не читаете:

    поскольку наше приложение — одностраничное, не сконфигурировав соответствующим образом сервер мы заставим пользователей получать ошибку 404, если они перейдут по http://oursite.com/user/id напрямую

    <...>

    всё, что нужно — единственная "резервная" запись в конфигурации сервера. Если URL не совпадает ни с одним статическим файлом, сервер должен просто отдать index.html, в котором и живёт наше приложение
    Ответ написан
    Комментировать
  • Как сократить запись в v-bind?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Не надо indexOf, индексы доступны в v-for без каких-либо дополнительных телодвижений:

    <div v-for="(row, iRow) in rows" class="board__rows">
      <div
        v-for="(col, iCol) in columns"
        v-text="col + row"
        :class="[ [ 'white', 'black' ][(iRow ^ iCol) & 1], 'board__square' ]"
      ></div>
    </div>
    Ответ написан
    Комментировать
  • Как добавить сотрудника в список (таблицу)?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Cannot read properties of undefined (reading 'lastname')

    Понятно, смотрим, где есть попытка чтения свойства lastname.

    async addNewEmployee({ commit }, employee) {
        await axios
            .post(`http://127.0.0.1:8000/api/v1/employees/`, {
                lastname: employee.lastname,

    Тоже понятно, смотрим, где вызывается addNewEmployee и что туда передаётся.

    @submit.prevent="addNewEmployee(employee)"

    А вот здесь непонятно - что такое employee? Такого свойства в компоненте нет. Надо добавить. Его содержимым будет то, что сейчас находится в хранилище - firstname, lastname, number - там, в хранилище, этим данным делать нечего.
    Ответ написан
    1 комментарий
  • Как правильно реализовывать прелоадеры?

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

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

    Или это считается нормальной практикой?

    Да, считается. У говнокодеров.
    Ответ написан
    3 комментария
  • Почему не меняется класс при скролле?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Встречный вопрос - почему вы решили, что класс должен меняться? Может, всё-таки стоит почаще заглядывать в документацию, а?

    app.ifScroll =

    Меняйте эту чушь на ifScroll.value =.
    Ответ написан
    Комментировать
  • Как применять в Quasar Select методы hidePopup и showPopup?

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

    И не должно быть - всё более чем очевидно.

    Конечно, для тех, кто о vue хоть что-то знает - например, что у vue есть документация. Тогда можно её открыть и прочитать там про ref:

    <q-select
      ref="select"
      ...

    <q-btn
      @click="$refs.select.showPopup()"
      ...
    Ответ написан
    Комментировать
  • Как закрепить центральный блок?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Вместо заворачивания ul в transition следует завернуть li в transition-group:

    <transition-group tag="ul" name="fade" class="buttons">
      <li
        v-if="какое здесь будет условие, предлагаю подумать самостоятельно"
        ...
    Ответ написан
    9 комментариев
  • Как получить нужную кнопку из такого обьекта?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Нет необходимости "получать", можно сразу передавать в функцию нужный объект вместо его отдельных свойств.

    Почему у элементов радиогрупп отдельные свойства checked? - активным же может быть только один. Пусть checked будет у самих радиогрупп и хранит не логическое значение, а индекс/id/value активного элемента.

    Как исполнены сами радиокнопки (кстати, а почему не показали шаблон?)? Если input'ми, используйте v-model вместо того, чтобы вручную обновлять свои данные.
    Ответ написан
    Комментировать
  • Как переиспользовать функцию?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Комментировать
  • Как сделать, если пустой инпут - то не выводить итем?

    0xD34F
    @0xD34F Куратор тега Vue.js
    computed: {
      trimmedNewTodoText() {
        return this.newTodoText.trim();
      },
      ...

    addNewTodo() {
      const title = this.trimmedNewTodoText;
      if (title) {
        this.todos.push({
          title,
          ...

    <button :disabled="!trimmedNewTodoText">Add</button>
    Ответ написан
    Комментировать
  • Каким способом лучше вызвать метод в дочернем компоненте из родителя?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Чем является первый способ? - реагированием на изменения параметра.
    Чем является второй способ? - вызовом метода дочернего компонента.

    А чего вам надо? Чего надо, то и делайте. По-моему, всё очевидно.
    Ответ написан
    Комментировать
  • Почему v-model на компоненте при изменении поля input не обновляет данные?

    0xD34F
    @0xD34F Куратор тега Vue.js
    props: {
      user: String
    },
    emits: ["update:someUser"]

    Это неверно. Имя события надо привести в соответствие с именем параметра, исправляем:

    - emits: ["update:someUser"]
    + emits: ["update:user"]

    - @input="$emit('update:someUser', $event.target.value)"
    + @input="$emit('update:user', $event.target.value)"
    Ответ написан
    Комментировать
  • Как добавить подсказки?

    0xD34F
    @0xD34F Куратор тега Vue.js
    data: () => ({
      items: [
        { text:  '69', tooltip:  'hello, world!!' },
        { text: '187', tooltip:  'fuck the world' },
        { text: '666', tooltip: 'fuck everything' },
      ],
    }),

    <div
      v-for="n in items"
      v-text="n.text"
      :data-tooltip="n.tooltip"
      class="item"
    ></div>

    .item {
      display: inline-flex;
      justify-content: center;
      align-items: center;
      color: white;
      background: red;
      width: 150px;
      height: 50px;
      margin: 10px;
      position: relative;
    }
    .item:hover::before {
      content: attr(data-tooltip);
      display: inline-block;
      background: blue;
      color: white;
      position: absolute;
    }
    Ответ написан
  • Как написать сортировку галереи работы на vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделайте вычисляемое свойство, которое будет представлять данные, соответствующие выбранной категории:

    computed: {
      filteredWorks() {
        const category = this.tabs.find(n => n.id === this.activeTabId)?.category;
        return category равна той, что у 'Все работы'
          ? this.works
          : this.works.filter(n => n.category === category);
      },

    <div class="articles__items articles__items--works">
      <img v-for="n in filteredWorks" :key="n.id" :src="n.image">
    </div>

    tabs: [
      { id: '1', name: 'Все работы', category: 'doors' },
      { id: '2', name: 'Окна', category: 'windows' },
      { id: '3', name: 'Двери', category: 'doors' },

    Почему у category одинаковые значения (doors)? Надо исправить.
    Ответ написан
    Комментировать
  • Почему не появляется третье окно, и не присваиваются классы к тексту?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Что, открыть консоль не догадались? Или открыли и тут же закрыли, придя в ужас от количества красного?

    В props и в data одно и то же свойство.
    props: {
      spawns: Boolean

    data() {
     return {
       play: false,
       active: false,
       prepare: false,
       spawns: {

    Куча незакрытых div'ов.

    <div class="hr">

    <div class="logo">

    <div class="icon">

    Ответ написан
  • Как в select положить все значения включая вложенные из массива объектов?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Понадобится функция, которая вложенный массив развернёт в плоский:

    const flat = (arr, childrenKey = 'children') =>
      (arr instanceof Array ? arr : []).reduce((acc, n) => (
        acc.push(n, ...flat(n[childrenKey], childrenKey)),
        acc
      ), []);
    
    // или, если нужны копии объектов без ссылок на массивы вложенных объектов:
    const flat = (arr, childrenKey = 'children') =>
      Array.isArray(arr)
        ? arr.flatMap(({ [childrenKey]: c, ...n }) => [
            n,
            ...flat(c, childrenKey),
          ])
        : [];

    Дальше всё просто - вычисляемое свойство, v-for по его значению:

    computed: {
      users() {
        return flat(this.elements);
      },
    },

    <option v-for="n in users" :key="n.id">{{ n.name }}</option>
    Ответ написан
    1 комментарий