【问题标题】:Vue js render text with html contentVue js 用 html 内容渲染文本
【发布时间】: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; 消失了,取而代之的是字符串

标签: javascript html vue.js vue-component vue-dynamic-components


【解决方案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 不见了
    猜你喜欢
    • 2018-08-10
    • 2021-04-21
    • 1970-01-01
    • 2016-12-16
    • 2021-04-09
    • 2017-02-27
    • 1970-01-01
    • 2019-12-21
    • 2021-11-10
    相关资源
    最近更新 更多