Задать вопрос
Ответы пользователя по тегу Vue.js
  • Почему json выводится таким образом?

    0xD34F
    @0xD34F Куратор тега Vue.js
    выводит побуквенно

    Тот факт, что вы ожидали иного, ясно говорит следующее: вы не знаете, что такое json. Не понимаете, что это строка. Что сам json и объекты, получаемые при его парсинге - не одно и то же.

    Строки v-for так и перебирает - "побуквенно". То есть, значениями user являются строки единичной длины. Ну а свойств id, name, price и т.д. у строк нет, отсюда пустота там, где вы выводите свойства элементов users.
    Ответ написан
    Комментировать
  • Как через input загрузить картинку в cropper?

    0xD34F
    @0xD34F Куратор тега Vue.js
    mounted() {
      this.cropper = new Cropper(this.$refs.image, {
        zoomable: false,
        scalable: false,
        aspectRatio: 1,
      });
    },
    methods: {
      selectFile(e) {
        const file = (e.target.files || e.dataTransfer.files)[0];
        if (file) {
          const reader = new FileReader();
          reader.onload = e => this.cropper.replace(e.target.result);
          reader.readAsDataURL(file);
        }
      },
    },
    Ответ написан
    1 комментарий
  • Как в js вызвать событие change?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Во-первых, не change - v-model по умолчанию слушает событие input (если хотите, чтобы использовалось change, добавьте модификатор lazy).

    Во-вторых, dispatchEvent.
    Ответ написан
    Комментировать
  • Как добавить обработчик двойного клика на попап 2gis?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Что, не хочет добавляться обработчик? Видимо, такой возможности не предусмотрено в 2gis api. Давайте закостылим - добавим его нативными средствами. Ну, почти. Так как элемент popup'а создаётся при его первом открытии, понадобится однократно срабатывающий обработчик popupopen, в котором будет выполняться назначение обработчика dblclick.

    Добавляете компоненту методы:

    methods: {
      onPopupOpen(e) {
        e.target
          .getPopup()
          .getElement()
          .querySelector('.leaflet-popup-content-wrapper')
          .addEventListener('dblclick', this.onPopupDblClick);
      },
      onPopupDblClick(e) {
        const
          id = +e.currentTarget.querySelector('[data-id]').dataset.id,
          // теперь, зная id, можно найти соответствующий объект
        ...

    А создаваемым маркерам обработчик:

    .once('popupopen', this.onPopupOpen)

    https://jsfiddle.net/3jz059mb/
    Ответ написан
    Комментировать
  • Как вывести html в render функции?

    0xD34F
    @0xD34F Куратор тега Vue.js
    return createElement('div', {
      domProps: {
        innerHTML: '<b>hello, world!!</b>',
      },
    });
    Ответ написан
  • Как чекнуть во вложенном компоненте чекбокс через его пришедший $event.target?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Не надо напрямую устанавливать checked, так во vue дела не делаются.

    не давать снять последний чекбокс

    Добавьте своему компоненту параметр - disabled. В родителе делаете метод для вычисления его значения: если чекбокс выбран, и количество выбранных чекбоксов равно одному - true, в остальных случаях false. Например.
    Ответ написан
  • Данные переданные через provide не реактивны?

    0xD34F
    @0xD34F Куратор тега Vue.js
    В документации написано, что данные передаваемые через provide/inject от родителя ребенку реактивны.

    Это где такое написано? Я видел совсем другое:

    Note: the provide and inject bindings are NOT reactive.
    Ответ написан
    5 комментариев
  • Два router-view на одной странице?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Ответ написан
    Комментировать
  • Как модифицировать код в VUE, чтобы связанные списки через v-model отображали параметр сразу?

    0xD34F
    @0xD34F Куратор тега Vue.js
    created() {
      this.chooseChild = Object.values(this.parent)[0];
      this.chooseS = Object.values(this.chooseChild)[0];
      this.showinfo = Object.values(this.chooseS)[0];
    },

    UPD. А вообще, я бы всё переписал. Хочу, чтобы можно было строить цепочки select'ов произвольной длины.

    Вместо отдельных свойств, отвечающих за текущие значения select'ов cделаем массив:

    data: () => ({
      selectedValues: [],
      ...

    Сделаем вычисляемое свойство, представляющее массивы опций для select'ов и конечное значение. Идём вглубь объекта с данными, используя в качестве ключей выбранные значения:

    computed: {
      selectData() {
        const options = [];
        let { items } = this;
    
        while (items instanceof Object) {
          options.push(Object.keys(items));
          items = items[this.selectedValues[options.length - 1]];
        }
    
        return {
          options,
          result: items || null,
        };
      },
    },

    Создадим select'ы и отобразим конечное значение:

    <div>
      <select
        v-for="(options, i) in selectData.options"
        v-model="selectedValues[i]"
        @input="selectedValues.length = i"
      >
        <option v-for="n in options">{{ n }}</option>
      </select>
    </div>
    <div>SELECTED: <b>{{ selectData.result || '&lt; NONE &gt;' }}</b></div>

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

    created() {
      let { items } = this;
      while (items instanceof Object) {
        const key = Object.keys(items)[0];
        this.selectedValues.push(key);
        items = items[key];
      }
    },

    https://jsfiddle.net/64m37ng0/
    Ответ написан
  • Как при нажатии кнопки/(ячейки в таблице) менять её значение?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Храните вместо значения его индекс. При клике увеличивайте его на единицу.

    Соответственно, если надо значение показать:

    {{ массивВозможныхЗначений[индексЗначения] }}

    Ну или, если будете хранить сами значения - при клике ищите индекс значения в массиве, берёте следующее:

    следующееЗначение = массивВозможныхЗначений[массивВозможныхЗначений.indexOf(текущееЗначение) + 1]

    UPD. Как это может выглядеть: раз, два.
    Ответ написан
    Комментировать
  • Как разрешить ввод только 2х знаков после запятой?

    0xD34F
    @0xD34F Куратор тега Vue.js
    val => (val.split('.')[1] || '').length < 3 || 'Не более двух знаков после запятой'
    Ответ написан
    Комментировать
  • Почему vue-router не меняет данные в компоненте?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Потому что экземпляр компонента заново не создаётся при смене значений параметров. За ними надо следить:

    watch: {
      '$route.params.slug': {
        immediate: true,
        handler() {
          // сюда переносите код из created
        },
      },
    },
    Ответ написан
    1 комментарий
  • Как активировать кнопку при выборе элемента в таблице?

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

    computed: {
      disabled() {
        return !this.selected.length;
      },
    },

    <v-btn
      :disabled="disabled"
      ...
    Ответ написан
    4 комментария
  • Как скрыть элемент на определённом роуте?

    0xD34F
    @0xD34F Куратор тега Vue.js
    <div v-if="$route.name !== 'signup'">hello, world!!</div>

    или

    <div v-if="$route.path !== '/signup'">hello, world!!</div>
    Ответ написан
    1 комментарий
  • Как использовать keep-alive с vuikit tabs?

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

    computed: {
      isEmpty() {
        return !this.$store.state.wishlistIds.length;
      },
      ...
    Ответ написан
    Комментировать
  • Как оптимизировать несложное vue приложение?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Плохо:

    <div class="color-label red" @click="color = '#FB253E', textColor = '#ffffff' , strokeColor = '#ffffff';"></div>
    <div class="color-label green" @click="color = '#19AD6A' ,textColor = '#ffffff' , strokeColor = '#ffffff';"></div>
    <div class="color-label orange" @click="color = '#FC6621' ,textColor = '#ffffff' , strokeColor = '#ffffff';"></div>
    <div class="color-label blue" @click="color = '#1386a3' ,textColor = '#ffffff' , strokeColor = '#ffffff';"></div>
    <div class="color-label yellow" @click="color = '#FFED00' ,textColor = '#111111' , strokeColor = '#111111';"></div>
    <div class="color-label lightgreen" @click="color = '#00ff00' ,textColor = '#111111' , strokeColor = '#111111';"></div>
    <div class="color-label white" @click="color = '#ffffff' ,textColor = '#111111' , strokeColor = '#111111';"></div>

    Лучше:

    <div
      v-for="n in colors"
      :class="[ 'color-label', n.name ]"
      @click="onColorClick(n.values)"
    ></div>

    data: () => ({
      colors: [
        { values: [ '#FB253E', '#FFF', '#FFF' ], name: 'red' },
        { values: [ '#19AD6A', '#FFF', '#FFF' ], name: 'green' },
        { values: [ '#FC6621', '#FFF', '#FFF' ], name: 'orange' },
        { values: [ '#1386A3', '#FFF', '#FFF' ], name: 'blue' },
        { values: [ '#FFED00', '#111', '#111' ], name: 'yellow' },
        { values: [ '#00FF00', '#111', '#111' ], name: 'lightgreen' },
        { values: [ '#FFFFFF', '#111', '#111' ], name: 'white' },
      ],
      ...
    }),
    methods: {
      onColorClick([ color, textColor, strokeColor ]) {
        Object.assign(this, { color, textColor, strokeColor });
      },
      ...
    },


    Плохо:

    <tspan x="0" y="-10" text-anchor="middle" alignment-baseline="middle" font-family="'Swiss721BT-RomanCondensed'" :style="{ 'font-size': firstLineFontSize }">{{ firstLine }}</tspan>
    <tspan x="0" y="17" text-anchor="middle" alignment-baseline="middle" font-family="'Swiss721BT-RomanCondensed'" :style="{ 'font-size': secondLineFontSize }">{{ secondLine }}</tspan>
    <tspan x="-2" y="45" text-anchor="middle" alignment-baseline="middle" font-family="'Swiss721BT-RomanCondensed'" :style="{ 'font-size': thirdLineFontSize }">{{ thirdLine }}</tspan></text>
    ...
    <input type="text" placeholder="enter 1 text line" @input="changeFirstLine">
    <input type="number" value='25' @input="changeFirstLineFontSize"><span> px </span>
    <input type="text" placeholder="enter 2 text line" @input="changeSecondLine">
    <input type="number" value='18' @input="changeSecondLineFontSize"><span> px </span>
    <input type="text" placeholder="enter 2 text line" @input="changeThirdLine">
    <input type="number" value='18' @input="changeThirdLineFontSize"><span> px </span>

    data: {
      firstLine: 'Your',
      secondLine: 'custom',
      thirdLine: 'text',
      firstLineFontSize: '25',
      secondLineFontSize: '18',
      thirdLineFontSize: '18',
      ...
    },
    methods: {
      changeFirstLine: function(event) {
          this.firstLine = event.target.value;
      },
      changeSecondLine: function(event) {
          this.secondLine = event.target.value;
      },
      changeThirdLine: function(event) {
          this.thirdLine = event.target.value;
      },
      changeFirstLineFontSize: function(event) {
          this.firstLineFontSize = event.target.value;
      },
      changeSecondLineFontSize: function(event) {
          this.secondLineFontSize = event.target.value;
      },
      changeThirdLineFontSize: function(event) {
          this.thirdLineFontSize = event.target.value;
      },
      ...

    Лучше:

    <tspan
      v-for="n in lines"
      v-text="n.text || n.placeholder"
      :x="n.x"
      :y="n.y"
      :style="{ 'font-size': n.fontSize }"
      text-anchor="middle"
      alignment-baseline="middle"
      font-family="'Swiss721BT-RomanCondensed'"
    ></tspan>
    ...
    <template v-for="(n, i) in lines">
      <input type="text" v-model="n.text" :placeholder="`enter ${i + 1} text line`">
      <input type="number" v-model="n.fontSize"><span> px </span>
    </template>

    data: () => ({
      lines: [
        { x:  0, y: -10, fontSize: 25, placeholder: 'Your' },
        { x:  0, y:  17, fontSize: 18, placeholder: 'custom' },
        { x: -2, y:  45, fontSize: 18, placeholder: 'text' },
      ],
      ...
    }),
    Ответ написан
    Комментировать
  • Как выводить дочерние элементы из массива в treeview (vuetify)?

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

    const find = (arr, id) =>
      (Array.isArray(arr) ? arr : []).reduce((found, n) =>
        found || (n.id === id ? n : find(n.children, id))
      , null);

    И, используя её, перепишем вычисляемое свойство:

    selected() {
      return this.active.length
        ? find(this.users, this.active[0])
        : null;
    },

    UPD. Почитал документацию - оказывается, можно всё сделать гораздо проще. Указываем для treeview параметр return-object - тогда в active вместо ключей будут объекты. Соответственно, искать ничего не надо, вычисляемое свойство сократится до

    selected() {
      return this.active[0];
    },
    Ответ написан
    1 комментарий
  • Как правильно делать такие компоненты и как они называются?

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

    const Component = Vue.extend(...);

    Экземпляры создаёте не через шаблон/render-функцию других компонентов, а вручную вызываете конструктор и добавляете корневой элемент куда там вам надо:

    document.body.appendChild(new Component(...).$mount().$el);

    Удаление - так же вручную, вызываете метод $destroy и удаляете корневой элемент из DOM.
    Ответ написан