Как правильно связать данные с динамически созданным элементом в Vue?

Здравствуйте! Я недавно начал изучать Vue и столкнулся с проблемой. Не могу понять, как изменить содержимое динамически созданного HTML-элемента, а также как связать данные с этим элементом. 

<br/>

```javascript
<script>
export default {
  data() {
    return {
      fghg: '',
      hk: '',
    }
  },
  methods: {
    _jjj() {
      this.fghg = '<b v-bind:data="hk">jjj!!!!</b>'; // этот элемент создается динамически. Как можно изменить значения его атрибута "data" и содержимое при нажатии на кнопку "12", как показано в коде ниже?
      this.hk = '!21121!';
    },
    _kkk() {
      // ... ??? ...
    }
  }
}
</script>

<template>
  <div v-html="fghg"></div>
  <button @click="_jjj">11</button>
  <button @click="_kkk">12</button>
</template>
```

<br/>

В коде выше я добавил комментарий, поясняющий суть проблемы. Ранее, используя jQuery, это было проще. Пример на jQuery:

<br/>

```javascript
function _jjj() {
  $('.fghg').html('<b class="aaakjhij" data="hk">jjj!!!!</b>');
}
function _kkk() {
  var elem = $('.aaakjhij');
  elem.html('ha-ha-haaaa!!!');
  elem.attr('data', 'ooooooooooo');
}
```

<br/>

```html
<div class="fghg"></div>
<button onclick="_jjj()">11</button>
<button onclick="_kkk()">12</button>
```

<br/>

Как мне поступить в данной ситуации?
  • 24 октября 2024 г. 22:12
Ответы на вопрос 2
Привет! Понимаю, что переход с jQuery на Vue может вызвать некоторые трудности, особенно когда речь идет о динамическом создании и изменении содержимого элементов. 

В Vue мы обычно избегаем напрямую манипулировать DOM через `v-html`, поскольку это нарушает реактивность и может привести к проблемам с производительностью, а также с безопасностью (возможные XSS-уязвимости).

Вот как можно переосмыслить твою задачу в контексте Vue, не полагаясь на `v-html` и манипуляции с jQuery:

1. Используй условный рендеринг для динамически создаваемого элемента вместо `v-html`.
2. Привязывай значения атрибутов и содержимого к данным в модели.

Вот пример, как это можно сделать:

```vue
<template>
  <div>
    <b v-if="showElement" :data="hk">{{ elementContent }}</b>
    <button @click="_jjj">11</button>
    <button @click="_kkk">12</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showElement: false,
      hk: '',
      elementContent: ''
    }
  },
  methods: {
    _jjj() {
      this.hk = '!21121!';
      this.elementContent = 'jjj!!!!'; // изменяем содержимое
      this.showElement = true; // показываем элемент
    },
    _kkk() {
      this.elementContent = 'ha-ha-haaaa!!!'; // изменяем содержимое
      this.hk = 'ooooooooooo'; // изменяем значение атрибута
    }
  }
}
</script>
```

### Объяснение кода:

- Используется переменная `showElement` для контроля отображения элемента `<b>`. Сначала он не будет показан (по умолчанию `false`), а после нажатия кнопки “11” он появится.
- Внутри элемента `<b>` связываются содержимое и атрибут `data` с данными из модели Vue:
  - `:data="hk"` привязывает атрибут `data` к значению свойства `hk`.
  - `{{ elementContent }}` используется для отображения текстового содержимого элемента, которое также управляется из модели.

Теперь, когда ты нажимаешь кнопку “11”, создается элемент `<b>` с заданными атрибутами и содержимым. Нажатие на кнопку "12" изменяет содержимое и атрибут динамически. Таким образом, мы остаёмся в рамках реактивности Vue и избегаем проблем, связанных с управлением DOM напрямую.
Если работаешь с vue - тебе не нужно трогать dom руками и наоборот. 
v-html только для статических каких-то данных.

Вот это вот <b class="aaakjhij" data="hk">jjj!!!!</b> должно быть уже в шаблоне. Если надо по условию - то использовать v-if или v-for если несколько.
Примерно так:
<script>
export default {
  data() {
    return {
      data: 'hk',
      text: 'jjj!!!!',
      show: false
    }
  },
  methods: {
    _jjj(){
      this.show = true
      this.data = 'hk';
      this.text = 'jjj!!!!';
    },
   _kkk(){
      this.data = 'ooooooooooo';
      this.text = 'ha-ha-haaaa!!!'
    }
  }
}
</script>

<template>
  <div>
    <b v-if="show" :data="data">{{text}}</b>
  </div>
  <button @click="_jjj">11</button>
  <button @click="_kkk">12</button>
</template>

Тебе надо перестать мыслить в jquery и начать мыслить в vue.

Если всё ещё остаются проблемы - опиши конкретную конечную цель, которой ты хочешь добиться, не в виде кода, а в виде результата и условий.
Похожие вопросы