是否有与ngTemplateOutlet等效的vue.js?

时间:2018-10-31 19:46:17

标签: vue.js transclusion

vue.js是否具有与Angular的* ngTemplateOutlet指令等效的功能?假设我有一些这样定义的组件:

    <template>
        <div id="independentComponent">
            Hello, {{firstName}}!
        </div>
    </template>
    <script>
        export default {
            name: "independentComponent",
            props: ['firstName']
        }
    </script>

    ...

    <template>
        <div id="someChildComponent">
            <slot></slot>
            <span>Let's get started.</span>
        </div>
    </template>
    <script>
        export default {
            name: "someChildComponent"
        }
    </script>

我希望能够做这样的事情:

<template>
    <div id="parentComponent">
        <template #indepdentInstance>
            <independentComponent :firstName="firstName" />
        </template>
        <someChildComponent>
            <template #indepdentInstance></template>
        </someChildComponent>
    </div>
</template>
<script>
    export default {
        name: "parentComponent",
        components: {
            someChildComponent,
            independentComponent
        },
        data() {
            return {
                firstName: "Bob"
            }
        }
    }
</script>

在Angular中,我可以使用

<div id="parentComponent">
    <someChildComponent>
        <ng-container *ngTemplateOutlet="independentInstance"></ng-container>
    </someChildComponent>

    <ng-template #independentInstance>
        <independentComponent [firstName]="firstName"></independentComponent>
    </ng-template>
</div>

但是看起来Vue要求将元素确切地写入到DOM在模板中的位置。有什么方法可以内联引用元素并将其作为插槽传递给另一个组件?

5 个答案:

答案 0 :(得分:1)

您无法重用updated_at之类的模板,但可以将User News Category id id id user_id category_id public function run() { factory(News::class, 20)->create()->each(function ($news) { $news->category()->save(factory(NewsCategory::class)->make()); $news->writtenBy()->save(factory(User::class)->make()); }); } 和运行时模板编译的思想与v-runtime-template结合使用以实现此目的。

首先,创建可重复使用的模板(class News extends Model { protected $table = 'news'; protected $fillable = ['title', 'body', 'author', 'created_at', 'update_at']; /** * WrittenBy belongs to User. */ public function writtenBy() { return $this->hasOne(User::class); } /** * Category belongs to User. */ public function category() { return $this->hasOne(NewsCategory::class); } } ):

ngTemplateOutlet

现在,您可以重复使用$refs模板:

v-pre

但是请记住,您无法从<ng-template #independentInstance>模板内部修改<div ref="independentInstance" v-show="false"> <template v-pre> <!-- v-pre disable compiling content of template --> <div> <!-- We need this div, because only one root element allowed in templates --> <h2>Reusable template</h2> <input type="text" v-model="testContext.readWriteVar"> <input type="text" v-model="readOnlyVar"> <progress-bar></progress-bar> </div> </template> </div> -vue会警告您:

independentInstance

但是您可以将其包装在<v-runtime-template :template="$refs.independentInstance.innerHTML" v-if="$refs.independentInstance"> </v-runtime-template> 中,它将起作用:

readOnlyVar

答案 1 :(得分:0)

您可以尝试由Portal vue的Vue核心团队成员撰写的LinusBorg

  

PortalVue是一组两个组件,可让您呈现一个   组件模板(或其一部分)在文档中的任何位置,甚至   在您的Vue应用程序控制的部分之外!

示例代码:

.

由同一位作者撰写的vue-simple-portal也较小,但是将组件安装到body元素的末端。

答案 2 :(得分:0)

X模板

使用useMemo。在array文件中定义脚本标签。

然后可以在模板定义中的多个组件中将x-template称为index.html

运行示例片段。

有关x-templates的更多信息,请参见Vue.js文档。

x-template
#my-template

答案 3 :(得分:0)

@NekitoSP 的回答给了我一个解决方案的想法。我已经实现了下面的示例。它对我有用。也许您想将其用作带有 props 的自定义组件。

关键字:#named #template #vue

<template>
  <div class="container">
    <div ref="templateRef" v-if="false">write here your template content and add v-if for hide in current place</div>
    ....some other contents goes here
    <p v-html="getTemplate('templateRef')"></p>
  </div>
</template>


<script lang="ts">
  import Vue from 'vue';
  Vue.extend({
    methods:{
      getTemplate(tempRef){
        return this.$refs[tempRef].innerHTML
      }
    }
  })
</script>

答案 4 :(得分:-1)

不太确定我在这里理解您的问题,但是如果我想在一个模板中添加两个组件,我会尽力为您提供一些选择。

HeaderSection.vue

    <template>
        <div id="header_id" :style="'background:'+my_color">
            welcome to my blog
        </div>
    </template>
    <script>
        export default {

            props: ['my_color']
        }
    </script>

BodySection.vue

    <template>
        <div id="body_id">
            body section here
        </div>
    </template>
    <script>
        export default {

        }
    </script>

home.vue

<template>

    <div id="parentComponent">

        <header-section :color="my_color" />

        <body-section />
    </div>
</template>
<script>
    import HeaderSection from "./components/HeaderSection.vue"
    import BodySection from "./components/BodySection.vue"
    export default {

        name: "home",

        components: {
            HeaderSection,
            BodySection
        },

        data() {
            return {
                my_color: "red"
            }
        }
    }
</script>