Javascript 在Vue.js的匿名组件中包装收到的插槽(VNode)

Javascript 在Vue.js的匿名组件中包装收到的插槽(VNode),javascript,html,vue.js,vue-component,Javascript,Html,Vue.js,Vue Component,我想收到两个指定的插槽slotOne和slotTwo。它们位于子组件中的this.$scopedSlots.slotOne和this.$scopedSlots.slotTwo,并包含vNode。如何将这些插槽(VNode)包装到新组件中,以便有条件地呈现它们,如下所示: 子组件: <template> <div> <keep-alive> <component :is="wrapperComponentContainin

我想收到两个指定的插槽
slotOne
slotTwo
。它们位于子组件中的
this.$scopedSlots.slotOne
this.$scopedSlots.slotTwo
,并包含vNode。如何将这些插槽(VNode)包装到新组件中,以便有条件地呈现它们,如下所示:

子组件:

<template>
  <div>
    <keep-alive>
      <component :is="wrapperComponentContainingProperSlot"></component>
    </keep-alive>
  </div>
</template>
<template>
  <child>
    <template v-slot:slotOne>
      ...
    </template>
    <template v-slot:slotTwo>
      ...
    </template>
  </child>
</template>

父组件:

<template>
  <div>
    <keep-alive>
      <component :is="wrapperComponentContainingProperSlot"></component>
    </keep-alive>
  </div>
</template>
<template>
  <child>
    <template v-slot:slotOne>
      ...
    </template>
    <template v-slot:slotTwo>
      ...
    </template>
  </child>
</template>

...
...

我猜这个问题的核心是,如何从另一个组件内部的vNode创建组件?

我相信我希望实现这一点的动机是基于错误的前提,即当父组件被销毁时,
不会被销毁。事实并非如此。尽管如此,我还是找到了如何将插槽包装到它们自己的组件中,包括匿名组件和命名组件

子组件:

<template>
  <component :is="componentToRender"></component>
</template>

<script>
import Vue from 'vue';

export default {
  computed: {
    componentToRender() {
      return this.showSlotOnesGlobally
        ? new this.SlotOneWrapperComponent(this)
        : new this.SlotTwoWrapperComponent(this);
    },
  },
  /* Assume a parent further up in the tree provided this data */
  inject: {
    showSlotOnesGlobally: 'showSlotOnesGlobally'
  },
  methods: {
    SlotOneWrapperComponent(context) {
      return Vue.component('SlotOneContentWrapper', {
        render() {
          return context.$scopedSlots.slotOne();
        },
      });
    },
    SlotTwoWrapperComponent(context) {
      return Vue.component('SlotTwoContentWrapper', {
        render() {
          return context.$scopedSlots.slotTwo();
        },
      });
    },
  },
};
</script>
<template>
  <child>
    <template v-slot:slotOne>
      ...
    </template>
    <template v-slot:slotTwo>
      ...
    </template>
  </child>
</template>

从“Vue”导入Vue;
导出默认值{
计算:{
componentorender(){
全局返回此.showslotones
?新的this.SlotoneWrapper组件(this)
:新建this.slottwwrapperComponent(this);
},
},
/*假设提供此数据的树中更高的父级*/
注入:{
ShowSlotonesGlobal:“ShowSlotonesGlobal”
},
方法:{
SlotOneWrapperComponent(上下文){
返回Vue.component('SlotOneContentWrapper'{
render(){
返回上下文。$scopedSlots.slotOne();
},
});
},
SlotTwoWrapperComponent(上下文){
返回Vue.component('SlotTwoContentWrapper'{
render(){
返回上下文。$scopedSlots.slotTwo();
},
});
},
},
};
父组件:

<template>
  <component :is="componentToRender"></component>
</template>

<script>
import Vue from 'vue';

export default {
  computed: {
    componentToRender() {
      return this.showSlotOnesGlobally
        ? new this.SlotOneWrapperComponent(this)
        : new this.SlotTwoWrapperComponent(this);
    },
  },
  /* Assume a parent further up in the tree provided this data */
  inject: {
    showSlotOnesGlobally: 'showSlotOnesGlobally'
  },
  methods: {
    SlotOneWrapperComponent(context) {
      return Vue.component('SlotOneContentWrapper', {
        render() {
          return context.$scopedSlots.slotOne();
        },
      });
    },
    SlotTwoWrapperComponent(context) {
      return Vue.component('SlotTwoContentWrapper', {
        render() {
          return context.$scopedSlots.slotTwo();
        },
      });
    },
  },
};
</script>
<template>
  <child>
    <template v-slot:slotOne>
      ...
    </template>
    <template v-slot:slotTwo>
      ...
    </template>
  </child>
</template>

...
...
要使它们成为匿名组件,只需将
Vue.component('SlotOneContentWrapper',
Vue.component('SlotTwoContentWrapper',
替换为
Vue.extend(


如果有人能提供一个更简洁的解决方案,那就太好了。

我相信我想要实现这一点的动机是基于这样一个错误的前提,即当父级被销毁时,
不会被销毁。事实并非如此。不过,我确实找到了如何将插槽包装到自己的组件中,包括匿名和非匿名组件命名的

子组件:

<template>
  <component :is="componentToRender"></component>
</template>

<script>
import Vue from 'vue';

export default {
  computed: {
    componentToRender() {
      return this.showSlotOnesGlobally
        ? new this.SlotOneWrapperComponent(this)
        : new this.SlotTwoWrapperComponent(this);
    },
  },
  /* Assume a parent further up in the tree provided this data */
  inject: {
    showSlotOnesGlobally: 'showSlotOnesGlobally'
  },
  methods: {
    SlotOneWrapperComponent(context) {
      return Vue.component('SlotOneContentWrapper', {
        render() {
          return context.$scopedSlots.slotOne();
        },
      });
    },
    SlotTwoWrapperComponent(context) {
      return Vue.component('SlotTwoContentWrapper', {
        render() {
          return context.$scopedSlots.slotTwo();
        },
      });
    },
  },
};
</script>
<template>
  <child>
    <template v-slot:slotOne>
      ...
    </template>
    <template v-slot:slotTwo>
      ...
    </template>
  </child>
</template>

从“Vue”导入Vue;
导出默认值{
计算:{
componentorender(){
全局返回此.showslotones
?新的this.SlotoneWrapper组件(this)
:新建this.slottwwrapperComponent(this);
},
},
/*假设提供此数据的树中更高的父级*/
注入:{
ShowSlotonesGlobal:“ShowSlotonesGlobal”
},
方法:{
SlotOneWrapperComponent(上下文){
返回Vue.component('SlotOneContentWrapper'{
render(){
返回上下文。$scopedSlots.slotOne();
},
});
},
SlotTwoWrapperComponent(上下文){
返回Vue.component('SlotTwoContentWrapper'{
render(){
返回上下文。$scopedSlots.slotTwo();
},
});
},
},
};
父组件:

<template>
  <component :is="componentToRender"></component>
</template>

<script>
import Vue from 'vue';

export default {
  computed: {
    componentToRender() {
      return this.showSlotOnesGlobally
        ? new this.SlotOneWrapperComponent(this)
        : new this.SlotTwoWrapperComponent(this);
    },
  },
  /* Assume a parent further up in the tree provided this data */
  inject: {
    showSlotOnesGlobally: 'showSlotOnesGlobally'
  },
  methods: {
    SlotOneWrapperComponent(context) {
      return Vue.component('SlotOneContentWrapper', {
        render() {
          return context.$scopedSlots.slotOne();
        },
      });
    },
    SlotTwoWrapperComponent(context) {
      return Vue.component('SlotTwoContentWrapper', {
        render() {
          return context.$scopedSlots.slotTwo();
        },
      });
    },
  },
};
</script>
<template>
  <child>
    <template v-slot:slotOne>
      ...
    </template>
    <template v-slot:slotTwo>
      ...
    </template>
  </child>
</template>

...
...
要使它们成为匿名组件,只需将
Vue.component('SlotOneContentWrapper',
Vue.component('SlotTwoContentWrapper',
替换为
Vue.extend(


如果有人能提供一个更简洁的解决方案,那就太好了。

在子组件中应该在哪里呈现
slotOne
slotTwo
?您没有在模板中的任何地方使用它们。这是可以做到的。但是,将
放在父组件中有什么好处呢?子组件正在尝试封装ate用于确定渲染哪个插槽的逻辑(在我的情况下,基于我们是否在移动设备上运行),并且,我们希望向每个插槽添加
keep alive
功能。据我所知,这需要将
slotOne
slotTwo
包装到它们自己的插槽中(匿名?)组件-我只是不知道如何做lol。在子组件中应该在哪里呈现
slotOne
slotTwo
?您没有在模板中的任何位置使用它们。这是可以做到的。但是,将
放在父组件中有什么好处呢?子组件正在尝试封装用于反编译的逻辑确定要渲染的插槽(在我的情况下,取决于我们是否在移动设备上运行),并且,我们希望为每个插槽添加
保持活动
功能。据我所知,这需要将
slotOne
slotTwo
包装到它们自己的插槽中(匿名?)组件-我只是不知道如何做,哈哈。