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

    0xD34F
    @0xD34F Куратор тега Vue.js
    data: () => ({
      sortBy: '',
      ...
    }),

    <v-btn @click="sortBy = 'имя_свойства_по_которому_надо_выполнить_сортировку'">click me</v-btn>
    
    <v-data-table :sort-by.sync="sortBy">...</v-data-table>

    Если при повторном клике надо переключать порядок сортировки, тогда так:

    data: () => ({
      sortBy: [],
      sortDesc: [],
      ...
    }),
    methods: {
      sort(colName) {
        const sameCol = this.sortBy[0] === colName;
        const sortDesc = this.sortDesc[0];
    
        this.sortBy = sameCol && sortDesc ? [] : [ colName ];
        this.sortDesc = sameCol && sortDesc ? [] : [ sameCol ];
      },
      ...
    },

    <v-btn @click="sort('имя_свойства_по_которому_надо_выполнить_сортировку')">click me</v-btn>
    
    <v-data-table :sort-by.sync="sortBy" :sort-desc.sync="sortDesc">...</v-data-table>

    В случае же сортировки по нескольким свойствам, метод sort будет выглядеть следующим образом:

    sort(colName) {
      const index = this.sortBy.indexOf(colName);
      if (index === -1) {
        this.sortBy.push(colName);
        this.sortDesc.push(false);
      } else if (this.sortDesc[index]) {
        this.sortBy.splice(index, 1);
        this.sortDesc.splice(index, 1);
      } else {
        this.$set(this.sortDesc, index, true);
      }
    },

    А вообще, можно сделать совсем просто. Имитируется клик по заголовку указанного столбца, дальше компонент таблицы сам всё исполнит в лучшем виде:

    <v-btn @click="sort('имя_свойства_по_которому_надо_выполнить_сортировку')">click me</v-btn>
    
    <v-data-table ref="table">...</v-data-table>

    methods: {
      sort(colName) {
        const index = this.свойство_описывающее_столбцы_таблицы.findIndex(n => n.value === colName);
        this.$refs.table.$el.querySelector('thead tr').cells[index].click();
      },
      ...
    },
    Ответ написан
    Комментировать
  • Как во vuex передать инстанс яндекс.карты, чтобы в методах компонента Vue можно было по клику добавлять маркеры?

    0xD34F
    @0xD34F Куратор тега Яндекс.Карты
    Не нужно дёргать карту напрямую. Сделайте массив с данными маркеров, заполняйте его по клику, и на его основе создавайте экземпляры компонента маркера:

    import { yandexMap, ymapMarker, loadYmap } from 'vue-yandex-maps';

    components: {
      yandexMap,
      ymapMarker,
    },
    data: () => ({
      coords: null,
      markers: [],
      settings: { /* ... */ },
    }),
    methods: {
      onClick(e) {
        this.markers.push({
          id: 1 + Math.max(0, ...this.markers.map(n => n.id)),
          coords: e.get('coords'),
        });
      },
    },
    async mounted() {
      await loadYmap({ ...this.settings, debug: true });
    
      ymaps.geolocation.get().then(res => {
        this.coords = res.geoObjects.position;
      });
    },

    <yandex-map
      v-if="coords"
      :coords="coords"
      @click="onClick"
    >
      <ymap-marker
        v-for="n in markers"
        :key="n.id"
        :marker-id="n.id"
        :coords="n.coords"
      ></ymap-marker>
    </yandex-map>

    https://jsfiddle.net/f65hraxk/
    Ответ написан
    3 комментария
  • Как правильно добавить фотографии в слайдер Vue Carousel 3D?

    0xD34F
    @0xD34F Куратор тега Vue.js
    data: () => ({
      slides: [
        'путь к первой картинке',
        'путь ко второй картинке',
        ...
      ],
    }),

    <slide v-for="(n, i) in slides" :index="i">
      <figure>
        <img :src="n">
      </figure>
    </slide>
    Ответ написан
    Комментировать
  • Как показывать только один компонент, который используется несколько раз?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Родитель всегда общий? Если да, тогда добавьте в него свойство, которое будет указывать, в каком из экземпляров вашего компонента надо отображать дополнительные элементы. В качестве значения можно использовать индекс экземпляра, например (не обязательно, также подойдёт какое-нибудь свойство из объектов с данными, на основе которых создаются экземпляры компонента - главное, чтобы значения были уникальными, типа id):

    data: () => ({
      items: [ ... ],
      active: null,
    }),

    <v-xxx
      v-for="(n, i) in items"
      :показыватьДополнительныйКонтент="active === i"
      @переключитьОтображениеДополнительногоКонтента="active = active === i ? null : i"
      ...

    https://jsfiddle.net/kdg4qevp/

    В противном случае создайте наблюдаемый объект, и поместите свойство, указывающее кого отображать, в него:

    const xxx = Vue.observable({ active: null });

    В свой компонент добавьте вычисляемое свойство, значение которого а) определяет необходимость демонстрации дополнительных элементов; б) зависит от свойства наблюдаемого объекта:

    computed: {
      показыватьДополнительныйКонтент() {
        return xxx.active === this.какоеТоСвойствоСУникальнымЗначением;
      },
    },

    <div v-if="показыватьДополнительныйКонтент">
      ...
    </div>

    Также добавьте в свой компонент метод для переключения отображения дополнительного содержимого:

    methods: {
      переключитьОтображениеДополнительногоКонтента() {
        xxx.active = this.показыватьДополнительныйКонтент
          ? null
          : this.какоеТоСвойствоСУникальнымЗначением;
      },
    },

    <button @click="переключитьОтображениеДополнительногоКонтента">
      {{ показыватьДополнительныйКонтент ? 'hide' : 'show' }}
    </button>

    https://jsfiddle.net/kdg4qevp/1/
    Ответ написан
    1 комментарий
  • Что означают три точки впереди функции во vue шаблоне?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Это означает, что вы не знаете js.

    Да и в целом - плохо понимаете смысл используемых вами слов. Какой шаблон, вы чего? Шаблон vue - это html, который компилируется в render-функцию. А вы что показали?
    Ответ написан
    4 комментария
  • Vuetify - как обратиться к чекбоксам?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Добавляете в компонент свойство, которое будет указывать, случалось ли ваше событие. Если его значение false, тогда ничего не делаете, по умолчанию будет отрендерен чекбокс, если true - передаёте в соответствующий слот что там вам надо:

    data: () => ({
      событиеНаступило: false,
      ...
    }),

    @событие="событиеНаступило = true"

    <v-data-table>
      <template v-if="событиеНаступило" #item.data-table-select>
        здесь размещаете контент, который должен отображаться вместо чекбоксов
      </template>
      ...

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

    <v-data-table>
      <template #item.data-table-select="{ item, isSelected, select }">
        <div v-if="item.событиеНаступило">hello, world!!</div>
        <v-simple-checkbox
          v-else
          :value="isSelected"
          @input="select($event)"
        ></v-simple-checkbox>
      </template>
      ...
    Ответ написан
  • Почему в диалоговых окнах данные повторяются?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Не повторяются.

    Поскольку управление отображением всех диалогов завязано на одно и то же свойство (v-model="dialog_destroy"), то при открытии любого из них открываются все и вы всегда видите только последний - он скрывает собой остальные.

    Пусть видимостью диалогов управляют разные свойства:

    data: () => ({
      showDialog: {},
      ...
    }),

    <v-dialog v-model="showDialog[item.свойствоИмеющееУникальныеЗначенияДляКаждогоItem]">

    <v-btn @click="showDialog[item.свойствоИмеющееУникальныеЗначенияДляКаждогоItem] = false">Отменить

    Можно и без дополнительного объекта обойтись, хранить информацию о состоянии диалога среди прочих данных:

    <v-dialog v-model="item.showDialog">

    <v-btn @click="item.showDialog = false">Отменить

    Также можно вынести шаблон диалогового окна за пределы таблицы, чтобы оно было одно на всех:

    data: () => ({
      dialogData: null,
      ...
    }),

    <v-data-table>
      <template #item.action="{ item }">
        <v-btn @click="dialogData = item">Удалить контакт</v-btn>
      </template>
    </v-data-table>
    
    <v-dialog :value="!!dialogData" @input="dialogData = $event">
      <span>Удалить контакт: @{{ dialogData?.contact_name }}</span>
      <v-btn :href="dialogData?.destroy_link">Подтвердить</v-btn>
      <v-btn @click="dialogData = null">Отменить</v-btn>
    </v-dialog>
    Ответ написан
  • Передача css классов в компонент - вывести эти классы не на root элементе, на дочернем?

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

    functional: true,
    render(h, ctx) {
      return h('div', {
        class: 'col-12',
      }, [
        h('input', {
          class: [ ctx.data.class, ctx.data.staticClass ],
        }),
      ]);
    },
    Ответ написан
    Комментировать
  • Каким способом можно сделать автосоздание переменных для v-model?

    0xD34F
    @0xD34F Куратор тега Vue.js
    mounted() {
      this.$el.querySelectorAll('input').forEach(n => n.dispatchEvent(new Event('input')));
    },

    jsfiddle.net/whrgboxs
    Ответ написан
    Комментировать
  • Как сделать попеременное нажатие чекбоксов?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Внутри:

    inheritAttrs: false,
    model: {
      prop: 'checked',
    },
    props: [ 'value', 'checked' ],
    computed: {
      innerChecked: {
        get() {
          return this.checked;
        },
        set(val) {
          this.$emit('input', val);
        },
      },
    },

    <label>
      <input
        type="checkbox"
        v-model="innerChecked"
        v-bind="$attrs"
        :value="value"
      >
      <slot></slot>
    </label>

    Снаружи:

    data: () => ({
      items: [
        { label:  'hello, world!!', value:  69 },
        { label:  'fuck the world', value: 187 },
        { label: 'fuck everything', value: 666 },
      ],
      checked: [ 187 ],
    }),
    watch: {
      checked(val) {
        if (val.length > 1) {
          this.checked = val.slice(-1);
        }
      },
    },

    <v-checkbox
      v-for="n in items"
      v-model="checked"
      :value="n.value"
      name="items[]"
    >
      {{ n.label }}
    </v-checkbox>

    https://jsfiddle.net/769wdoq5/

    Один вопрос - на хрена? Можно заменить чекбоксы радиокнопками, и добавить ещё одну, которая будет обозначать отсутствие выбора.
    Ответ написан
    Комментировать
  • Комбинированная пагинация во Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    https://jsfiddle.net/vp4qawfg/

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

    0xD34F
    @0xD34F Куратор тега Vue.js
    computed: {
      range() {
        const prices = this.filterData.map(n => n.price);
        return {
          min: Math.min(...prices),
          max: Math.max(...prices),
        };
      },
    },

    <input type="range" v-bind="range">
    Ответ написан
    Комментировать
  • Как реализовать сортировку таблицы по нажатию на заголовок столбца?

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

    Сделайте вычисляемое свойство, которое будет представлять отсортированный массив. Текущий столбец - ключ, по которому из элементов массива извлекаются значения для сравнения; результат сравнения умножается на +/- 1, в зависимости от текущего направления сортировки.

    Функция, инициирующая сортировку, принимает столбец, по которому надо сортировать, и устанавливает значение соответствующего свойства. В случае, если новый и старый столбцы совпадают, переключайте значение свойства, отвечающего за направление сортировки.

    https://jsfiddle.net/qny6cvsr/1/
    Ответ написан
    Комментировать
  • Как не обрабатывать клик, если нажатие кнопки мыши произошло над другим элементом?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Добавить в компонент модального окна свойство, которое будет указывать, начат ли процесс закрытия окна. Выставляется в true только по mousedown на корневом элементе, в остальных случаях сбрасывается. При событии mouseup на корневом элементе проверяется значение, если true - можно закрывать.

    data: () => ({
      closing: false,
    }),

    <template>
      <div
        @mousedown="closing = $event.target === $el"
        @mouseup.self="closing && close()"
      >
        ...

    https://jsfiddle.net/3vkqm8sw/
    Ответ написан
    Комментировать
  • Как вынести в метод назначение классов?

    0xD34F
    @0xD34F Куратор тега Vue.js
    methods: {
      classes: obj => ({
        'current-active': obj.progress.current > 0,
      }),
      ...
    },

    :class="classes(cutLine)"
    Ответ написан
    3 комментария
  • Vuetify - как у календаря убрать выбор месяца?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Скрыть через стилизацию:

    .show-days-only .v-picker__title,
    .show-days-only .v-date-picker-header {
      display: none;
    }

    <v-date-picker class="show-days-only"
    Ответ написан
    Комментировать
  • Как поменять переменную в шаблоне из роутера?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Можно использовать метаданные маршрутов:

    routes: [
      {
        ...
        meta: { pageTitle: 'hello, world!!' },
      },
      {
        ...
        meta: { pageTitle: 'fuck the world' },
      },
      ...
    ],

    <div>{{ $route.meta.pageTitle }}</div>
    Ответ написан
    Комментировать
  • Как слушать изменения vuex хранилища и менять определённые данные в компоненте?

    0xD34F
    @0xD34F Куратор тега Vue.js
    В компоненте - переносите authCheck из data в computed, используете mapGetters.
    Ответ написан
  • Как сделать круглый colorpicker?

    Комментировать
  • Как выделить текст в html?

    0xD34F
    @0xD34F Куратор тега Vue.js
    methods: {
      marked: (text, search) => search
        ? text.replace(RegExp(search.replace(/[\\^$|.*?+{}()[\]]/g, '\\$&'), 'gi'), '<mark>$&</mark>')
        : text,
    },

    <div v-html="marked(text, search)"></div>

    Если выделение должно пересекать границы тэгов, то стоит взять какую-нибудь готовую библиотеку под это дело, такую как, скажем, mark.js (пример использования совместно с vue).
    Ответ написан
    1 комментарий