-2

我想要做的是有一个根元素,其中包含一个包含内部 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>

我已经尝试过上述方法,并且尝试过使用插槽。我可以用 vanilla JavaScript like 解决它element.innerText,但我不想这样做。主要目标是当他们键入时元素是可编辑的,他们正在编辑将被呈现的 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<b>hey</b>在单击内部时进行编辑,我不希望它包裹在其他任何东西中,如果我将 v-html 放在外部 div 上,内部 div 就消失了。

4

2 回答 2

2

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

JS FIDDLE 完整演示

//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>
于 2021-05-05T02:47:45.357 回答
1

就像 Seblor 所说的,v-html 将使用嵌套的 html 字符串。

简单地用 a 替换RenderString组件<div v-html="element.content"/>就可以得到你想要的。

用给定的例子测试hello<b>hey</b>

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>

于 2021-05-02T03:25:32.777 回答