场景:
我在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。
在mounted()
生命周期中,作为我想避免的事情的一个示例(在Nuxt提供快照后安装组件)。
<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
答案 0 :(得分:0)
模板:
<component :is="item.component" />
脚本:
components: { cats: Cats, dogs: Dogs },
那么您就不需要直接的DOM操作技巧。当Nuxt在服务器上运行时,这是行不通的(因为服务器上没有真正的DOM),并且还阻止了反应系统拾取pets数组中的更改。
答案 1 :(得分:0)
解决方案
我的主要问题是创建渲染的布局,并尝试在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>)),
])