Как можно манипулировать DOM, например, обтеканием текста в элементе абзаца, используя только Vue. js? - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть компонент Vue, который имеет contenteditable div, который позволяет пользователям вводить сообщения. Когда пользователь впервые пытается создать сообщение, я использую jQuery, чтобы обернуть текст в тег <p>. Я не могу понять, как этого достичь, используя только Vue. js ...

Vue. js компонент

<template>
   <div id="Message" contenteditable="true" @focus="formatMessage" @keydown="formatMessage" @keyup="formatMessage" @keypress="formatMessage">

   </div>
</template>

<script>
  import $ from 'jquery'

  formatMessage: function(event) {
    if ($("#Message > p").length === 0) {            // if no <p> element when user interacts with div
      $("#Message").contents().eq(0).wrap("<p />");  // then wrap a <p> tag around the first child content
  }

}

Можно ли сделать это, используя всего лишь Vue. js, поэтому мне не нужно загружать библиотеку jQuery для простых манипуляций с DOM (что может вызвать проблему) с Vue в виртуальном DOM c с изменениями jQuery)?

до formatMessage():

<div id="Message" contenteditable="true">
I started typing here  
</div>

после formatMessage() :

<div id="Message" contenteditable="true">
 <p>I started typing here</p>
</div>

Можно / лучше попробовать сделать это с помощью виртуального DOM Vue? Могу ли я каким-то образом использовать createElement для создания нового тега p, а затем обновить его содержимое тем, что печатает пользователь? Может быть, это не так, как работает Virtual DOM, я не уверен.

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Не используйте JQuery -подобную манипуляцию DOM в VUE, VUE - это управляемая данными структура , вам нужно сохранить некоторые данные в компоненте для запуска макета, например

<template>
   <div contenteditable="true" @focus="formatMessage" @keydown="formatMessage" @keyup="formatMessage" @keypress="formatMessage">
     <!-- wrap 'p' tag, if 'shouldWrap'-->
     <p v-if="shouldWrap">{{content}}</p>
     <!-- without wrap-->
     <template v-else>{{content}}</template>
   </div>

</template>
<script>
export default {
 data () {
   return {
    shouldWrap: false,
    content:'' // text, you want to display inside div
   }
 },
 methods: {
   formatMessage() {
    this.shouldWrap = true
   }
 }
}
</script>
0 голосов
/ 27 апреля 2020

Вы можете использовать v-if и немного продублировать код, если хотите добиться чего-то похожего

<template>
   <div v-if="shouldWrap === false" contenteditable="true" @focus="formatMessage" @keydown="formatMessage" @keyup="formatMessage" @keypress="formatMessage">

   </div>
   <p v-else>
      <div contenteditable="true" @focus="formatMessage" @keydown="formatMessage" @keyup="formatMessage" @keypress="formatMessage">
     </div>
   </p>
</template>
<script>
export default {
 data () {
   return {
    shouldWrap: false
   }
 },
 methods: {
   formatMessage() {
    this.shouldWrap = true
   }
 }
}
</script>

Но, вероятно, попытка соответствовать стилю p также должна сработать.

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