如何在Vue 2.5中从带有html标签的字符串创建VNode?

Ric*_*-MX 2 javascript vue.js

我正在尝试创建一个呈现Feather Icons程序包的功能组件,但无法弄清楚最后一步。这是我得到的:

这是我的FeatherIcon.vue组件。

<script>
const feather = require("feather-icons");

export default {
  components: {},
  props: {
    type: {
      required: true,
      type: String
    }
  },
  mounted() {},
  render(createElement) {
    return createElement(
      "svg",
      {attrs: feather.icons[this.type].attrs },
      feather.icons[this.type].contents
    );
  }
};
</script>
Run Code Online (Sandbox Code Playgroud)

根据Vue docs的第三个参数,它应该是:

// {String | Array}
// Children VNodes, built using `createElement()`,
// or using strings to get 'text VNodes'. Optional.
Run Code Online (Sandbox Code Playgroud)

但是,我的第三个参数feather.icon [this.type] .contents的结果是一个在svg标记内包含“ innerHTML”的字符串:

"<line x1="6" y1="3" x2="6" y2="15"></line><circle cx="18" cy="6" r="3"></circle><circle cx="6" cy="18" r="3"></circle><path d="M18 9a9 9 0 0 1-9 9"></path>"
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,如何将feather.icon [this.type] .contents转换为一组VNode?

我已经尝试使用DOMParser并使用parseFromString但没有运气。任何的想法?

Ber*_*ert 5

您可以使用数据对象domProps属性。

该对象还允许您绑定普通的HTML属性以及DOM属性(例如innerHTML)(这将替换v-html指令)

这是一个例子。

console.clear()

const content = `
  <line x1="6" y1="3" x2="6" y2="15"></line>
  <circle cx="18" cy="6" r="3"></circle>
  <circle cx="6" cy="18" r="3"></circle>
  <path d="M18 9a9 9 0 0 1-9 9"></path>
`

new Vue({
  el: "#app",
  render(h){
    return h("svg", {domProps:{innerHTML: content}})
  }
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app"></div>
Run Code Online (Sandbox Code Playgroud)

对于您的情况,您只需将innerHTML设置为羽毛的内容。

另外,请注意,如果没有模板,通常只使用纯Javascript文件。您不需要单个文件组件。所以你的组件将是

FeatherIcon.js

const feather = require("feather-icons");

export default {
  props: {
    type: {
      required: true,
      type: String
    }
  },
  render(createElement) {
    return createElement(
      "svg",
      {
        attrs: feather.icons[this.type].attrs,
        domProps: {
          innerHTML: feather.icons[this.type].content
        }
      });
  }
};
Run Code Online (Sandbox Code Playgroud)

最后,您提到要使它成为一个功能组件,在这种情况下,您可以执行以下操作:

const FeatherIcon = {
  functional: true,
  props: {
    type: {
      required: true,
      type: String
    }
  },
  render(h, context){
    const {contents, attrs} = feather.icons[context.props.type]
    return h("svg", {attrs, domProps: {innerHTML: contents}})
  }
};
Run Code Online (Sandbox Code Playgroud)

这是一个工作示例。

const feather = require("feather-icons");

export default {
  props: {
    type: {
      required: true,
      type: String
    }
  },
  render(createElement) {
    return createElement(
      "svg",
      {
        attrs: feather.icons[this.type].attrs,
        domProps: {
          innerHTML: feather.icons[this.type].content
        }
      });
  }
};
Run Code Online (Sandbox Code Playgroud)
const FeatherIcon = {
  functional: true,
  props: {
    type: {
      required: true,
      type: String
    }
  },
  render(h, context){
    const {contents, attrs} = feather.icons[context.props.type]
    return h("svg", {attrs, domProps: {innerHTML: contents}})
  }
};
Run Code Online (Sandbox Code Playgroud)