Vue js 用 html 内容渲染文本

Posted

技术标签:

【中文标题】Vue js 用 html 内容渲染文本【英文标题】:Vue js render text with html content 【发布时间】:2021-07-23 07:18:33 【问题描述】:

我想要做的是有一个根元素,其中包含一个包含内部 html 的道具,例如:hello<b>hey</b> 但我不能使用 v-html,因为这个元素也有子元素,例如:

<template>
  <component :is="element.tag" contenteditable="true">
    <div contenteditable="false">
      <span class="delete-obj" :id="'delete'+element.id" >delete</span>
    </div>
    <RenderString :string="element.content" />
  </component>
</template>
<script>
    import Vue from "vue";
  
    Vue.component("RenderString", 
        props: 
            string: 
                required: true,
                type: String
            
        ,
        render(h) 
            const render = 
                template:  this.string ,
                methods: 
                    markComplete() 
                        console.log('the method called')
                    
                
            
            return h(render)
        
    )
    export default 
        name: "VElement",
        props: 
            element: 
                required: false,
                default: null
            ,
        ,
    
 </script>

我已经尝试过上述方法,并且尝试过使用插槽。我可以使用像 element.innerText 这样的普通 javascript 来解决它,但我不想这样做。主要目标是当他们键入元素时元素是可编辑的,他们正在编辑将呈现的 element.content,其中的 div 是我也需要的普通 HTML。 主要问题是我想要的内部 HTML 没有根元素。 元素类似于:

id:1,tag:"div",content:"hello<b>hey</b>"

我希望最终结果是:

<div contenteditable="true">
    <div contenteditable="false">
        <span class="delete-obj" :id="'delete'+element.id" >delete</span>
    </div>
    hello<b>hey</b>
<div>

当我点击内部时我想编辑hello&lt;b&gt;hey&lt;/b&gt;,我不希望它包裹在其他任何东西中,如果我将 v-html 放在外部 div 上,内部 div 就消失了。

【问题讨论】:

你的脚本块在哪里?您正在使用 element,但您没有显示它的定义位置 @Jonathan 脚本没有什么重要的,但我编辑给你看,元素就这么简单 v-html 指令应该使用类似“hellohey”的字符串 &lt;div contenteditable="false"&gt;的问题内容是否被用户编辑? @Seblor 是的,我知道这行得通,但把它放在外部 div 上,&lt;div contenteditable="false"&gt; 消失了,取而代之的是字符串 【参考方案1】:

如果您确实无法将内容包装在父元素中,也许一个好方法是编写一个呈现文本的VUE directive。

JS FIDDLE FULL DEMO

//DIRECTIVE
Vue.directive('string', 
    inserted(el, bind) 
        /** 
        * Here you can manipulate the element as you need.
        */

        el.insertAdjacentText('beforeend', bind.value); 
    
);

//TEMPLATE
<template>
  <component :is="element.tag" contenteditable="true" v-string="element.content">
    <div contenteditable="false">
      <span>delete</span>
    </div>
  </component>
</template>

【讨论】:

【参考方案2】:

就像 Seblor 说的,v-html 可以处理嵌套的 html 字符串。

只需将 RenderString 组件替换为 &lt;div v-html="element.content"/&gt; 即可满足您的需求。

使用hello&lt;b&gt;hey&lt;/b&gt; 的给定示例进行测试:

Vue.component('VElement', 
  name: "VElement",
  props: 
    element: 
      required: false,
      default: null
    ,
  ,
  template: '\
    <component :is="element.tag" contenteditable="true">\
      <div contenteditable="false">\
        <span class="delete-obj" :id="\'delete\'+element.id">delete</span>\
      </div>\
      <div v-html="element.content"/>\
    </component>'
)

new Vue(
  el: '#app'
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <v-element :element="id:1, tag:'div', content:'hello<b>hey</b>'" />
</div>

【讨论】:

我的问题是我不希望 element.content 位于内部 div 中,我希望它直接位于父 div 中而不是包裹在内部,如果我在外部 div 上使用 v-html里面的 div 不见了

以上是关于Vue js 用 html 内容渲染文本的主要内容,如果未能解决你的问题,请参考以下文章

《Vue如何渲染文本》

Vue基础

用JS自制表格软件玩数据3. 构建实时渲染器

Vue模板内容

Vue专题-js常用指令

如何使用来自 CMS 的服务器端渲染内容来补充 Vue.js?