Javascript 是否可以从单个文件comp向全局Vue组件添加内容?

Javascript 是否可以从单个文件comp向全局Vue组件添加内容?,javascript,vue.js,vuejs2,vue-component,Javascript,Vue.js,Vuejs2,Vue Component,我已经制作了一个全局组件,它将呈现我们想要的内容 这个组件非常简单 <template> <section id="help" class="collapse" > <div class="container-fluid"> <slot /> </div> </section> </template> <script> export de

我已经制作了一个全局组件,它将呈现我们想要的内容

这个组件非常简单

<template>
  <section
    id="help"
    class="collapse"
  >
    <div class="container-fluid">
      <slot /> 
    </div>
  </section>
</template>

<script>
  export default {
    name: 'VHelp',
  };
</script>
然后在我的
VElementsGenerator
comp中,我有一个render函数,它使用虚拟DOM中的render元素从一个类似

<script>
  import {
    cloneDeep,
    isEmpty,
  } from 'lodash';

  export default {
    name: 'VElementsGenerator',
    props: {
      elements: {
        type: Array,
        required: true,
      },
    },
    methods: {
      iterateThroughObject(object, createElement, isNestedElement = false) {
        const generatedElement = [];

        for (const entry of object) {
          const nestedElements = [];
          let elementConfig = {};

          if (typeof entry.config !== 'undefined') {
            elementConfig = cloneDeep(entry.config);
          }

          if (entry.nestedElements) {
            nestedElements.push(this.iterateThroughObject(entry.nestedElements, createElement, true));
          }

          generatedElement.push(createElement(
            entry.type,
            isEmpty(elementConfig) ? entry.value : elementConfig,
            nestedElements
          ));

          if (typeof entry.parentValue !== 'undefined') {
            generatedElement.push(entry.parentValue);
          }
        }

        if (isNestedElement) {
          return generatedElement.length === 1 ? generatedElement[0] : generatedElement;
        }

        return createElement('div', generatedElement);
      },
    },
    render(createElement) {
      if (this.elements) {
        return this.iterateThroughObject(this.elements, createElement);
      }

      return false;
    },
  };
</script>

进口{
cloneDeep,
我是空的,
}来自“lodash”;
导出默认值{
名称:“VElementsGenerator”,
道具:{
要素:{
类型:数组,
要求:正确,
},
},
方法:{
IterateThrowObject(对象,createElement,IsNesteElement=false){
const generatedElement=[];
for(对象的常量输入){
常量嵌套元素=[];
让elementConfig={};
if(typeof entry.config!==“未定义”){
elementConfig=cloneDeep(entry.config);
}
if(条目.嵌套元素){
push(this.iteratethrawobject(entry.nestedElements,createElement,true));
}
GenerateElement.push(createElement(
entry.type,
isEmpty(elementConfig)?entry.value:elementConfig,
嵌套元素
));
if(typeof entry.parentValue!==“未定义”){
GenerateElement.push(entry.parentValue);
}
}
if(isNestedElement){
return generatedElement.length==1?generatedElement[0]:generatedElement;
}
返回createElement('div',GenerateElement);
},
},
渲染(createElement){
如果(本.元素){
返回this.iteratethrawobject(this.elements,createElement);
}
返回false;
},
};
第二种方法工作得很好,但是如果我想渲染复杂的数据,渲染函数中使用的对象非常长,读取起来非常复杂

因此,我试图找到另一种方法,仅当我希望在子组件上添加内容时,才将内容添加到基本布局中使用的全局组件中

我不能直接在儿童公司内部使用这个
VHelp
组件,因为HTML页面架构将完全错误

我想知道这是否可以从单个文件comp向组件槽添加内容(最好是HTML),而无需重新创建组件的新实例

此外,我认为在Vuex存储中将HTML保存为字符串是非常难看的。所以我甚至不知道这是否可行,是否需要完全改变我尝试的方式


有什么想法吗?

在存储中,您应该只存储数据,而不是HTML结构。解决此问题的方法是将v-help组件内容的当前状态存储在存储中。然后,您将拥有一个带有插槽的
v-help
组件(就像您已经提议的那样)。您应该根据商店中的状态传递不同的内容。下面是一个抽象的例子:

<v-help>
  <content-one v-if="$store.state.content === 'CONTENT_ONE' />
  <content-two v-else-if="$store.state.content === 'CONTENT_TWO' />
  <content-fallback v-else />
</v-help>
当然,这取决于您的需求,特别是如果这是实现这一目标的最佳方式,那么需要使用多少不同的场景。如果我理解正确,您正在将帮助元素保存到应用商店。您还可以在其中保存当前选定帮助元素的数组,并直接在
v-help
组件中显示它们


编辑

当然,您也可以将静态组件(或其名称)保存在存储中。然后,您可以在子组件中动态决定哪些内容显示在
v-help
中。以下是一个例子:

<v-help>
  <component :is="$store.state.helpComponent" v-if="$store.state.helpComponent !== null" />
</v-help>

另请参阅动态组件的文档(
语法):

是的,如果我在
v-help
中有一个默认内容,这将很好地工作。但是我可以将所有内容都放在
v-help
中,并且我无法提前知道将传递给此组件的内容。每个页面上的内容都是独一无二的,这就是为什么我不能用你解释的方式。好吧,这些内容来自哪里?来自服务器请求或静态vue组件?这是在vue上定义的静态内容component@Jérôme如果它是一个静态组件,并且您需要在子组件中决定应该使用哪个组件,那么您可以在存储中存储组件的名称。我添加了一个例子。
<script>
  import {
    cloneDeep,
    isEmpty,
  } from 'lodash';

  export default {
    name: 'VElementsGenerator',
    props: {
      elements: {
        type: Array,
        required: true,
      },
    },
    methods: {
      iterateThroughObject(object, createElement, isNestedElement = false) {
        const generatedElement = [];

        for (const entry of object) {
          const nestedElements = [];
          let elementConfig = {};

          if (typeof entry.config !== 'undefined') {
            elementConfig = cloneDeep(entry.config);
          }

          if (entry.nestedElements) {
            nestedElements.push(this.iterateThroughObject(entry.nestedElements, createElement, true));
          }

          generatedElement.push(createElement(
            entry.type,
            isEmpty(elementConfig) ? entry.value : elementConfig,
            nestedElements
          ));

          if (typeof entry.parentValue !== 'undefined') {
            generatedElement.push(entry.parentValue);
          }
        }

        if (isNestedElement) {
          return generatedElement.length === 1 ? generatedElement[0] : generatedElement;
        }

        return createElement('div', generatedElement);
      },
    },
    render(createElement) {
      if (this.elements) {
        return this.iterateThroughObject(this.elements, createElement);
      }

      return false;
    },
  };
</script>
<v-help>
  <content-one v-if="$store.state.content === 'CONTENT_ONE' />
  <content-two v-else-if="$store.state.content === 'CONTENT_TWO' />
  <content-fallback v-else />
</v-help>
<div>
  <button @click="$store.commit('setContentToOne')">Content 1</button>
</div>
state: {
  content: null
},
mutations: {
  setContentToOne(state) {
    state.content = 'CONTENT_ONE';
  }
}
<v-help>
  <component :is="$store.state.helpComponent" v-if="$store.state.helpComponent !== null" />
</v-help>
<template>
  test component
</template>

<script>
export default {
  name: 'test-component'
};
</script>
<div>
  <button @click="$store.commit('setHelpComponent', 'test-component')">Set v-help component to 'test-component'</button>
</div>
<template>
  <button @click="$store.commit('setHelpComponent', testComponent)">Set v-help component to testComponent (imported)</button>
</template>

<script>
import TestComponent from '@/components/TestComponent';

export default {
  name: 'some-child-component',
  computed: {
    testComponent() {
      return TestComponent;
    }
  }
};
</script>
<template>
  <button @click="$store.commit('setHelpComponent', testComponentName)">Set v-help component to 'test-component'</button>
</template>

<script>
import TestComponent from '@/components/TestComponent';

export default {
  name: 'some-child-component',
  computed: {
    testComponentName() {
      return TestComponent.name;
    }
  }
};
</script>
state: {
  helpComponent: null
},
mutations: {
  setHelpComponent(state, value) {
    state.helpComponent = value;
  }
}