Vue: как динамически привязать свойство к новому элементу DOM

#javascript #jquery #vue.js #vuejs2

#javascript #jquery #vue.js #vuejs2

Вопрос:

Допустим, у меня есть компонент со следующим шаблоном:

 <div id="root"></div>
  

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

 $('#root').append('<div id="a1" v-bind:styles="styles.a1"></div>')
  

где «styles.a1» — это просто объект из данных компонента:

 data() {
   return {
      styles: { a1: {color: 'red'} }
   };
}
  

Я полагаю, что привязка новорожденного элемента не будет работать, потому что Vue ничего не знает об этом новом элементе и его привязке.

Но, может быть, есть какой-то способ реализовать желаемую логику?

PS Я знаю, что природа Vue заключается в манипулировании данными, а не DOM, но вот ситуация, с которой мне приходится иметь дело.

Ответ №1:

Если вы используете компоненты Vue, вам не следует манипулировать DOM.

  • Для этого вам следует либо использовать шаблонную логику.

        <template v-if="someCondition">
           <div id="a1" v-bind:styles="styles.a1"></div>
       </template>
      
  • Оберните код, отличный от Vue, внутри его собственного компонента Vue.

     Vue.component('date-picker', {
      template: '<input/>',
      mounted: function() {
        $(this.$el).datepicker();
      },
      beforeDestroy: function() {
        $(this.$el).datepicker('hide').datepicker('destroy');
      }
    });
      

    https://vuejsdevelopers.com/2017/05/20/vue-js-safely-jquery-plugin/

  • Используйте пользовательскую директиву.

     Vue.directive('demo', {
        bind: function () {
            $(this.el).css({color:'#fff', backgroundColor:this.arg});
        },
        update: function (value) {
            $(this.el).html(
                'argument - '   this.arg   '!<br>'  
                'key - '   this.key   '<br>'  
                'value - '   value);
        }
    });
    
      

Комментарии:

1. Я бы хотел НЕ использовать манипуляции с DOM, но проблема в том, что шаблон загружается динамически (и это может быть что угодно), во-вторых, я должен добавлять новые элементы. Пожалуйста, подскажите мне, как избежать манипулирования DOM в этом случае.

2. В этом случае вам следует использовать строковые шаблоны, скомпилированные шаблоны работать не будут.

3. Или, если вам необходимо, вы можете добавить больше html с помощью v-html , но вы не можете добавлять к нему директивы

4. Можете ли вы добавить больше информации об использовании шаблонов строк, как это могло бы помочь?

5. Я не могу использовать какую-либо шаблонную логику, потому что в моем случае шаблоном может быть что угодно. Другое дело, что я должен добавлять новые элементы только после того, как шаблон смонтирован и отрисован. И я не понимаю, как пользовательская директива поможет, если я заранее не знаю, каким будет новый элемент.

Ответ №2:

Вы можете сначала привязать стиль без значения,

 data() {
   return {
      styles: { a1: '' }
   };
}
  

затем вы можете добавить в него данные из события с помощью обычного JS. (jQuery здесь даже не нужен).

 methods: {
   quack() {
        this.styles.a1 = { color: red }
    }
}
  

Редактировать: я неправильно понял. Кажется, Vue не обнаруживает вновь добавленные элементы после монтирования. Итак, что вы можете сделать, это смонтировать экземпляр Vue после добавления добавленных элементов или повторно отобразить весь экземпляр с помощью forceUpdate . (Последний будет повторно отображать весь экземпляр, поэтому я рекомендую разбить на несколько экземпляров Vue для повышения производительности)

Принудительное обновление

Комментарии:

1. Спасибо, но, к сожалению, ваш ответ — это не то, о чем я спрашиваю. Мой вопрос заключается в том, как создать новый элемент, добавить его в DOM (или как-то связать еще) и привязать к нему некоторые данные — все программно. Объект style приведен только для примера.

2. Ах, я ошибся. Извините. Да, вы можете! Вам просто нужно повторно смонтировать экземпляр после его добавления, поскольку Vue их не обнаруживает. ^^ Вот больше информации! Подождите, я получил неправильную ссылку. Минуту

3. Обновлено. Надеюсь, это тот ответ, который вы хотите

4. Спасибо, это не совсем то, что я хочу, но я рассмотрю эту функцию (для обновления всего экземпляра).

5. или вы можете создать несколько экземпляров Vue и просто обновить добавленный экземпляр, чтобы он не перерисовывал всю страницу ^^