Vue:使用数据控制DOM(但v-for,v-if,v-model和v-show不够用)

时间:2019-08-14 09:24:20

标签: javascript vue.js dom vuejs2

我以前使用过Vue,我知道如何使用v-for来渲染元素序列,v-ifv-show来有条件地显示元素,以及v-model来控制例如段落的内容。

但是现在我需要对DOM进行更好的控制:

  • 我在组件的ranges中有一个data对象,并且模板中有一个text div(text可能是id和/或ref属性)。 / li>
  • 对于每个范围,我想突出显示text div中文本的特定部分,而不是基于字符串或正则表达式匹配,而是基于文本索引(我之前是通过Rangy进行的)。 / li>
  • 我还想在每个[可选]范围内插入一些工具提示或弹出窗口,例如v-tooltip

例如,当我的范围对象包含<div ref='text'>The cat chases a dog.</div>时,我想在{ start: 0, end: 3 }内突出显示 the

在这种情况下,操作DOM对我不起作用,因为(i)将更新data,导致Vue再次更新DOM,删除先前的编辑内容,以及(ii)随后通过类似{ {1}}甚至不被Vue识别为组件。

利用Vue的数据驱动方法,有什么方法可以做我需要做的事情?

1 个答案:

答案 0 :(得分:1)

请确保,Vue无法与附加DOM一起使用, 尝试这个。效果很好:

通过拆分文本。我们得到了一个长度为2的数组

    数组l[0]
  1. 第一部分 是突出显示的文本之前的文本
  2. 数组l[1]
  3. 第二部分 是突出显示的文本之后的文本

然后我们合并:l[0] + <p style="/* some style */"> + hightlighted_text + </p> + l[1]

然后我们使用v-html

将HTML绑定到div
  

您需要进行一些验证,例如:如果突出显示的文本在整个文本中存在。否则,这将导致 向整个文本中添加新文本

var app = new Vue({
    el: '#app',
    data: {
        words: '',
        text: 'hello world im vue.js',
        hightlighted: ''
    },
    methods: {
        highlightMe() {
            var l = this.text.split(this.words);
            console.log(l);
            this.hightlighted = l[0] + '<p style="background-color: red; display: inline">' + this.words + '</p>' + l[1];
        }
    },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.js"></script>

<div id="app">
<label>text to be highlighted :</label><br />
<input type="text" class="form-control" v-model="words"><br/>
<button @click="highlightMe">hightLight ` {{ words }} `</button>
<div>
  {{text}}
</div>
<div v-html="hightlighted"></div>
</div>