Nuxt:将动态组件挂载到尚未渲染的 DOM
Posted
技术标签:
【中文标题】Nuxt:将动态组件挂载到尚未渲染的 DOM【英文标题】:Nuxt: Mounting dynamic components to the DOM that is not rendered yet 【发布时间】:2019-03-17 13:59:53 【问题描述】:场景:
我在universal
模式下使用 Nuxt。该应用程序与一个无头 CMS 配合使用,该 CMS 提供了应呈现的组件的简单布局,以及组件名称及其道具 - 如下所示:
[
"tag": "div",
"class": "col",
"component": "dogs",
"props":
"dogs": [
"id": 1,
"name": "Barky"
,
"id": 2,
"name": "Jumpy"
]
,
"tag": "div",
"class": "col",
"component": "cats",
"props":
"cats": [
"id": 1,
"name": "Miouwy"
,
"id": 2,
"name": "Fluffy"
]
]
据我了解,我必须在 Nuxt 制作“快照”并将其交付给客户端之前将组件应用到 DOM。我的计划是在created()
生命周期中挂载组件——也就是说,只看名称,而不是要走的路。
主要问题: 我想将组件动态挂载到尚不存在的 DOM。
作为我想逃避的事情的一个例子 - 在 Nuxt 交付快照之后安装组件 - 在 mounted()
生命周期中。
<template>
<section class="container">
<div ref="layout-container" class="row"></div>
</section>
</template>
<script>
import mapGetters from 'vuex';
import Vue from 'vue';
import Dogs from '@/components/Dogs';
import Cats from '@/components/Cats';
export default
components:
Dogs,
Cats
,
fetch( store )
store.dispatch('landing/updateContent');
,
computed:
...mapGetters(
content: 'landing/content',
)
,
beforeCreate()
Vue.component('dogs', Dogs);
Vue.component('cats', Cats);
,
mounted()
this.content.forEach((item) =>
const CompClass = Vue.component(item.component);
const instance = new CompClass( propsData: item.props ).$mount();
this.$refs['layout-container'].appendChild(instance.$el);
)
;
</script>
非常感谢您提前提供任何指示!
编辑:回购这个例子:https://github.com/jpedryc/nuxt-test-render
【问题讨论】:
【参考方案1】:尝试使用dynamic components 实现此功能
模板:
<component :is="item.component" />
脚本:
components: cats: Cats, dogs: Dogs ,
那么你就不需要直接的 DOM 操作技巧了。当 Nuxt 在服务器上运行时(因为您在服务器上没有真正的 DOM),这将无法工作,并且还会阻止反应系统获取 pets 数组中的更改。
【讨论】:
感谢您的帮助。这个解决方案在定义的布局中会很好,但是上面的 items 数组是定义多个组件的多级对象数组(带有“子”键)的简化。我认为解决此问题的最佳方法是在将 DOM 提供给客户端之前尝试在服务器端渲染 DOM。【参考方案2】:解决方案 我的主要问题是创建渲染布局并在 DOM 已交付给客户端后尝试将其连接起来。相反,我应该在虚拟 Vue DOM 中渲染组件——就在“快照”时刻之前。
这就是我最终所做的——不安装渲染的组件:
<template>
<section class="container">
<page-component/> <!-- A component without <template>, but with render() -->
</section>
</template>
PageComponent 仅包含:
import ...
export default
components:
Dogs,
Cats,
,
beforeCreate()
Vue.component('dogs', Dogs);
Vue.component('cats', Cats);
,
render: function (h)
return createDynamicLayout(h);
,
createDynamicLayout(h)
只是一个创建树的简单函数:
return h('div', 'class': 'row' , [
h('div', 'class': 'col' , h(<somwhere_call_dogs_component>)),
h('div', 'class': 'col' , h(<somwhere_call_cats_component>)),
])
【讨论】:
以上是关于Nuxt:将动态组件挂载到尚未渲染的 DOM的主要内容,如果未能解决你的问题,请参考以下文章
15《Vue 入门教程》Vue 动态组件 &amp; keep-alive