Прикрепите v-модель к динамическому элементу c, добавленному с помощью .appendChild в Vue. js - PullRequest
1 голос
/ 21 января 2020

Я работаю с библиотекой, в которой нет оболочки Vue. js. Библиотека добавляет элементы в DOM динамически c.

Я хочу иметь возможность связать атрибут v-model с этими элементами с помощью Vue и добавить их в свою модель в свою модель.

Я делал это в прошлом с другие реактивные структуры, такие как Knockout. js, но я не могу найти способ сделать это с помощью vue. js.

Любая плата за это? Должно быть что-то среди этих строк, я предполагаю:

var div = document.createElement('div');
div.setAttribute('v-model', '{{demo}}');
[VUE CALL] //tell vue.js I want to use this element in my model.

document.body.appendChild(div);

1 Ответ

0 голосов
/ 22 января 2020

Вы можете создать компонент-оболочку для своей библиотеки, а затем настроить пользовательский v-model, чтобы получить результат в соответствии с тем, что вы ищете. Поскольку ваша библиотека отвечает за управление DOM, вам нужно подключиться к событиям, предоставляемым вашей библиотекой, чтобы обеспечить актуальность вашей модели. Вы можете иметь поддержку v-model для своего компонента, обеспечив две вещи:

  • Принимает value реквизит
  • Выдает input событие

Вот пример выполнения чего-то похожего: https://codesandbox.io/s/listjs-jquery-wrapper-sdli1 и фрагмент реализованного мной компонента оболочки:

<template>
  <div>
    <div ref="listEl">
      <ul ref="listUlEl" class="list"></ul>
    </div>
    <div class="form">
      <div v-for="variable in variables" :key="variable">
        {{ variable }}
        <input v-model="form[variable]" placeholder="Enter a value">
      </div>
      <button @click="add()">Add</button>
    </div>
  </div>
</template>

<script>
export default {
  props: ["value", "variables", "template"],

  data() {
    return {
      form: {}
    };
  },

  mounted() {
    this.list = new List(
      this.$refs.listEl,
      {
        valueNames: this.variables,
        item: this.template
      },
      this.value
    );

    this.createFormModels();
  },

  methods: {
    createFormModels() {
      for (const variable of this.variables) {
        this.$set(this.form, variable, "");
      }
    },

    add() {
      this.$emit("input", [
        ...this.value,
        {
          id: this.value.slice(-1)[0].id + 1,
          ...this.form
        }
      ]);
    }
  },

  watch: {
    value: {
      deep: true,
      handler() {
        this.$refs.listUlEl.innerHTML = "";

        this.list = new List(
          this.$refs.listEl,
          {
            valueNames: this.variables,
            item: this.template
          },
          this.value
        );
      }
    }
  },

  beforeDestroy() {
    // Do cleanup, eg:
    // this.list.destroy();
  }
};
</script>

Ключевые моменты:

  • Выполните инициализацию пользовательской библиотеки на mounted(), чтобы создать DOM. Если ему нужен элемент для работы, укажите его через <template> и поместите ref. Это также место для настройки прослушивателей событий в вашей библиотеке, чтобы вы могли запускать обновления модели через $emit('value', newListOfStuff).
  • watch для изменений в value prop, чтобы вы могли повторно инициализировать библиотеку или, если это предоставляет способ обновить свою коллекцию, используйте это вместо этого. Обязательно очистите предыдущий экземпляр, если библиотека поддерживает его, а также открепите обработчики событий.
  • Вызовите все операции очистки, удаление обработчиков событий внутри beforeDestroy.

Для дополнительная ссылка:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...