将标记注入现有的Vue组件

时间:2019-06-21 05:15:51

标签: vue.js vuejs2

我想将标记注入到现有组件中。

这是一个简单的例子:

<!-- Arbitrary component X -->
<template>
  <div>
    <!-- I want a headline here -->
    foo!
  </div>
</template>

我知道我可以通过插入<slot/>然后使用<X><h1>Hello world!</h1></X>来实现。但是,我想动态地无需编辑原始组件

这是我使用高阶分量的想法:

import X from '~/components/X';
import injectHeadline from '~/hoc/injectHeadline.js';

export default {
  components: {
    X: injectHeadline(X, 'Hello world!')
  }
}

使用

<!-- injectHeadline.js -->
export default (component, headline) => Vue.component({
    render(createElement) {
        let result = createElement(component);

        <!-- (*) somehow insert <h1>{{ headline }}</h1> here. How? -->

        return result;
    }
})

但是,我没有运气来操纵(*)中的渲染结果。我尝试摆弄result.context.$children,但这无济于事。 任何想法?

2 个答案:

答案 0 :(得分:1)

可以使用与React中相同的模板扩展方法,在VNode呈现为DOM之前修改其层次结构,如this answer中所述:

export default (WrappedComponent, headline) => Vue.component({
  extends: WrappedComponent,
  render(h) {
    const elements = this.$options.extends.render.call(this, h);
    elements.children.unshift(<h1>{headline}</h1>));
    return elements;
  }
});

答案 1 :(得分:0)

就这么简单

<script>
export default {
  functional: true,
  render: function(createElement, context) {
    return createElement("div", context.slots().default);
  }
};
</script>

btw我将其设置为可以提高性能(在这种情况下不需要vnode)

在您的代码中,您可以这样做

let result = createElement(component,this.$slots.default);