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

    0xD34F
    @0xD34F Куратор тега Vue.js
    Что там у вас отвечает за видимость картинки, preloaderVisibility? Ну вот и выставьте его в false по получении данных. Это после data.forEach(link => this.links.push(link)), если я правильно понял.
    Ответ написан
    Комментировать
  • Как во Vue.js добавить данные в существующий массив?

    0xD34F
    @0xD34F Куратор тега Vue.js
    А откуда вы взяли, что у вас там массив? Вы сообщение об ошибке вообще читали? Если "this.articles.push is not a function", значит this.articles - это не массив, у массивов метод push есть. Изначально да - массив, но когда вы в created вызываете getArticles, производится перезапись свойства. Неплохо было бы разобраться, что на самом деле возвращает запрос на получение статей - уж не объект ли?

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

    Да, не массив, а объект. Я просто и так и так пробовал. Смог добавить таким способом.
    this.articles = Object.assign(this.articles, response.data.payload);

    Но значение добавилось не так как нужно.

    Присваивание бессмысленное - Object.assign модифицирует первый аргумент, а не создаёт новый объект.

    Кроме того, vue не отслеживает установку значений по индексу.

    Сам способ добавления данных в массив сомнительный - что если имена свойств пришедшего объекта не образуют корректного набора индексов? Типа, начинаются не с нуля, есть пропуски... А если какие-то из имён свойств вообще не могут быть использованы в качестве индекса массива? - само свойство создано будет, но v-for (как и методы - forEach, map, ...) не будет его обрабатывать. Доставайте из объекта массив значений и уже его элементы добавляйте в articles:

    this.articles.push(...Object.values(response.data.payload));

    Это если именно "добавить в существующий". Но, поскольку изначально он пустой, в getArticles можно просто заменить один массив другим:

    this.articles = Object.values(response.data.payload);

    А вообще - какого чёрта? Ждёте массив, а приходит объект... Или исправьте бекенд, чтобы приходил массив, или не ждите массива - замените дефолтное значение articles на пустой объект, а в getArticles по получении данных просто выполняйте присваивание: this.articles = response.data.payload. А там, где пытаетесь concat выполнить, создавайте новый объект, в который будут копироваться свойства существующего и результат запроса:

    this.articles = { ...this.articles, ...response.data.payload };
    // или
    this.articles = Object.assign({}, this.articles, response.data.payload);
    Ответ написан
    3 комментария
  • Почему изменение маршрута вручную нарушает автоматический routing в приложении Vue?

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

    Сохраняйте таймаут при установке и сбрасывайте его при уходе с роута:

    this.timeout = setTimeout(...

    beforeRouteLeave(to, from, next) {
      clearTimeout(this.timeout);
      next();
    },

    UPD. Небольшое демо.
    Ответ написан
    Комментировать
  • Как передать компоненту параметры через v-model?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Дефолтное имя параметра значения для v-model - "value", а никакой не "modal". Замените имя параметра, или настройте model в соответствии со своими потребностями.
    Ответ написан
    1 комментарий
  • Vue hotel datepicker, как получить данные?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Документация прочитана, наверно не настолько внимательно, чтобы понять

    Не получается понять документацию - можно глянуть исходный код. И если я правильно понял то, что там увидел, то надо ловить события check-in-changed и check-out-changed.

    UPD. Ну да, так и есть.
    Ответ написан
    Комментировать
  • Как сделать фильтрацию по нескольким значениям в VueJS?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сложно это всё. Четыре селекта - очень похожие, четыре вычисляемых свойства - очень похожие. Многовато копипасты. Надо упростить.

    Первым делом внимательно посмотрим на все эти похожие куски кода, найдём, где они отличаются, и на основе этих отличий сделаем описание фильтров:

    filters: [
      { name: 'calculator.brand_filter', getter: obj => obj.brand.name, value: '' },
      { name: 'calculator.company_filter', getter: obj => obj.company.name, value: '' },
      { name: 'calculator.country_filter', getter: obj => obj.brand.country, value: '' },
      { name: 'calculator.side_filter', getter: obj => obj.sides, value: '' },
    ],

    Затем сделаем собственно фильтрацию, пропустим данные через массив фильтров (если значение фильтра выставлено - производится фильтрация, нет - оставляем данные как есть):

    computed: {
      filteredProfiles() {
        return this.filters.reduce((profiles, { value, getter }) => {
          return value
            ? profiles.filter(n => getter(n) === value)
            : profiles;
        }, this.profiles);
      },

    Далее, надо дать пользователю возможность задавать значения фильтров. Сделаем компонент фильтра:

    Vue.component('filter-select', {
      props: [ 'name', 'options', 'value' ],
      template: `
    <div>
      <p>{{ name }}<p>
      <select :value="value" @change="$emit('input', $event.target.value)">
        <option value="">-</option>
        <option v-for="n in options">{{ n }}</option>
      </select>
    </div>`
    });

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

    computed: {
      filterOptions() {
        return this.filters.map(n => [...new Set(this.profiles.map(n.getter))]);
      },

    Наконец, создадим сами фильтры:

    <filter-select
      v-for="(n, i) in filters"
      v-model="n.value"
      :options="filterOptions[i]"
      :name="trans(n.name)"
    ></filter-select>

    Также не будем забывать про обнуление значений фильтров. Так что вот метод сброса фильтров и кнопка, по клику на которую он будет вызываться:

    methods: {
      resetFilters() {
        this.filters.forEach(n => n.value = '');
      },

    <button @click="resetFilters">{{ trans('calculator.reset_filter') }}</button>

    Демо можно посмотреть здесь (да, тут меньше фильтров, чем у вас - ну так вы свои данные не показали, а у меня воображения на большее не хватило).
    Ответ написан
    1 комментарий
  • Как отфильтровать результаты v-for на полученное через select options значение в VueJS?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Добавляете в компонент свойство brand. И используете его в качестве значения для своего select'а, а метод handleBrand вырезаете:

    <select v-model="brand" class="custom-select">

    Делаете ещё одно вычисляемое свойство - отфильтрованные элементы из profiles, чей brand.name равен brand:

    filteredProfiles() {
      return this.profiles.filter(n => n.brand.name === this.brand);
    },

    Ну и выводите эти отфильтрованные элементы:

    <div v-for="profile in filteredProfiles" class="row feed">
    Ответ написан
  • Как избежать [vue/no-parsing-error] Parsing error: duplicate-attribute?

    0xD34F
    @0xD34F Куратор тега Vue.js
    :license="{
      old_price: 20,
      price: 200,
      title: 2,
    }"

    Ну и остальные аналогично.
    Ответ написан
    1 комментарий
  • Как удалить повторяющиеся объекты в VueJS?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделайте вычисляемое свойство:

    computed: {
      brands() {
        return [...new Set(this.profiles.map(n => n.brand.name))];
      },
    },

    <option v-for="brand in brands" :value="brand">{{ brand }}</option>
    Ответ написан
    1 комментарий
  • Как по таймеру изменить route во Vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    const router = new VueRouter({
      routes: [
        { path: '/',    component: { template: '<div>Home</div>' } },
        { path: '/foo', component: { template: '<div>Foo</div>'  } },
        { path: '/boo', component: { template: '<div>Boo</div>'  } },
      ],
    });
    
    new Vue({
      router,
      el: '#app',
      data: () => ({
        routeIndex: 0,
      }),
      created() {
        setInterval(() => {
          const { routes } = this.$router.options;
          this.routeIndex = (this.routeIndex + 1) % routes.length;
          this.$router.push(routes[this.routeIndex]);
        }, 1000);
      },
    });

    <div id="app">
      <router-view></router-view>
    </div>
    Ответ написан
    Комментировать
  • Как обновлять карту 2gis?

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

    if (!this.map) {
      this.map = DG.map(...);
      this.marker = DG.marker(...);
    } else {
      this.map.panTo(...)
      this.marker.setLatLng(...);
    }

    https://jsfiddle.net/o04vc57k/
    Ответ написан
    Комментировать
  • Как будет правильно добавить стили к компоненту?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Через обертку <div class="container-avatar"><Avatar/></div> - в этом варианте лишний html елемент

    Что мешает добавлять класс непосредственно экземпляру компонента? Вполне себе рабочий вариант.
    Ответ написан
    2 комментария
  • Как организовать ajax фильтрацию vue.js по критериям указанным в массиве?

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

    Выводите его содержимое в шаблоне, например:

    <div v-for="item in flightsData">
      <div>Price: {{ item.price }}</div>
      <div v-for="f in item.flights">
        <div>Departure: {{ f.cities.departureCity }}, {{ f.departureTime }}</div>
        <div>Arrival: {{ f.cities.arrivalCity }}, {{ f.arrivalTime }}</div>
      </div>
    </div>

    Как может выглядеть фильтрация результатов запроса (наверное, было бы логичнее выполнять фильтрацию на сервере и отдавать только необходимые данные, подумайте об этом):

    this.flightsData = response.data.filter(n => val.includes(n.flights[0].airline.code));
    Ответ написан
    1 комментарий
  • Как отследить, что данные во vuex добавились?

    0xD34F
    @0xD34F Куратор тега Vue.js
    пишет ошибку что свойства id нету

    А так ли это на самом деле? Вместо пересказа следует текст ошибки показывать. Почему-то уверен, что у вас там не id отсутствует, а не получается достать id из отсутствующего объекта, типа "Cannot read property 'id' of undefined". В случае отсутствия объектов подсовывайте пустые:

    isShow() {
      return ((this.getProject() || {}).creator || {}).id === this.user.id;
    },


    как в другом компоненте дождаться пока метод fetch() положит данные с store?

    Условный рендеринг - добавьте v-if="данные" тому элементу/компоненту, что эти данные использует.
    Ответ написан
    1 комментарий
  • Как в Vue.js сделать чтобы по на нажатию на элемент списка он попадал в массив (без html элемента input) и отправлял ajax запрос?

    0xD34F
    @0xD34F Куратор тега Vue.js
    При удалении в splice надо указывать индекс, а не сам элемент:

    methods: {
      select(airline) {
        const index = this.selected.indexOf(airline);
        if (index !== -1) {
          this.selected.splice(index, 1);
        } else {
          this.selected.push(airline);
        }
      },
    },

    Свойство checkedAll должно быть вычисляемым, с сеттером:

    computed: {
      checkedAll: {
        get() {
          return this.airlines.every(n => this.selected.includes(n.name));
        },
        set(val) {
          this.selected = val ? this.airlines.map(n => n.name) : [];
        },
      },
    },


    AJAX запрос <...> нужен watch?

    Можно так, да.

    что лучше использовать

    axios
    Ответ написан
    1 комментарий
  • Как в vue сделать независимые переключатели классов?

    0xD34F
    @0xD34F Куратор тега Vue.js
    data: () => ({
      items: [
        { active: false, text: '...' },
        { active: false, text: '...' },
        ...
      ],
    }),

    <div
      v-for="n in items"
      v-text="n.text"
      :class="[ { active: n.active }, 'toggle' ]"
      @click="n.active = !n.active"
    ></div>


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

    а как сделать чтобы не городить кучу даныx в data?

    Типа, лучше городить ещё большую кучу html кода? Нет, так дела не делаются. По крайней мере, при использовании vue, тут данные первичны.

    Хотя, можно и без данных - если вы разметку генерите автоматически, без копипасты:

    data: () => ({
      itemsCount: 5,
      active: [],
    }),
    methods: {
      toggle(item) {
        const i = this.active.indexOf(item);
        if (i === -1) {
          this.active.push(item);
        } else {
          this.active.splice(i, 1);
        }
      },
    },

    <div
      v-for="i in itemsCount"
      v-text="`Item ${i}`"
      :class="[ { active: active.includes(i) }, 'toggle' ]"
      @click="toggle(i)"
    ></div>
    Ответ написан
    3 комментария
  • Как повесить директиву в рендер функции?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Чето я вообще ничего найти не могу.

    Плохо искали. Нужная информация есть прямо в разделе документации, посвящённом render-функции.
    Ответ написан
  • Как сделать пагинацию?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Добавим два свойства - количество элементов на странице (т.е., сколько элементов следует показывать единовременно) и номер текущей страницы:

    perPage: 10, // или 20, или 50, это вам виднее... да и настраиваемым можно его сделать
    page: 1,

    Затем добавим пару вычисляемых свойств - количество страниц и элементы текущей страницы:

    pages() {
      return Math.ceil(this.items.length / this.perPage);
    },
    pageData() {
      const end = this.page * this.perPage;
      return this.items.slice(end - this.perPage, end);
    },

    И отобразим элементы:

    <div v-for="item in pageData">
      ...

    Также сделаем методы для переключения страниц - по номеру и относительно текущей страницы...

    goTo(page) {
      this.page = Math.max(1, Math.min(this.pages, page));
    },
    next(change) {
      this.goTo(this.page + change);
    },

    ...чтобы дать пользователю возможность просмотреть все данные:

    <button @click="goTo(1)">в начало</button>
    <button @click="next(-1)">предыдущая страница</button>
    <button @click="next(+1)">следующая страница</button>
    <button @click="goTo(pages)">в конец</button>

    https://jsfiddle.net/dkb5wej1/
    Ответ написан
    Комментировать