Vue3 渲染一个可扩展的异步组件列表

Posted

技术标签:

【中文标题】Vue3 渲染一个可扩展的异步组件列表【英文标题】:Vue3 rendering a extensible list of async components 【发布时间】:2021-01-28 02:49:42 【问题描述】:

请你帮我解决这个问题。 经过长时间寻找答案,我找不到解决方法。我真的是 Vue 的新手。 让我再解释一下。

我有一个在调用时创建的异步组件。它有一个模板,该模板根据它收到的 JSON 构建表单。该组件创建正常,并且正在以正确的方式加载所有字段。这是结构:

<template>
  <div class="constraint_supercontainer col-lg-12">    
    <form class="constraint_group" v-for="constraint in constraints.data.constraints" :key="constraint">
      <div class="constraint_field">
        <label class="constraint_label">constraint.label</label>
        <select class="constraint_select" v-bind:name="constraint.name" v-bind:id="constraint.name">
          <option value="" selected disabled>-- SELECCIONE --</option>
          <option v-for="value in constraint.values" :key="value" v-bind:value="value['value']"> value['label'] </option>
        </select>
      </div>
    </form>
  </div>
</template>

<script>
const api_route = "<api_route>";

export default 
  name: 'Constraint',
  async setup()
    const response = await fetch(api_route+'get-conditions');
    const constraints = await response.json();

    return  constraints ; 
   
;
</script>

在这一步中,一切都很好。但是在主应用程序构造函数中,我需要有一种方法来创建该组件的多个实例(约束)并将它们呈现在同一个 DOM 元素中。我找到了使用 Vue.extend 函数在 Vue2 中执行此操作的方法,但现在它不再存在。在 Vue3 中,这仅适用于第一个元素,如果我再次调用该函数,则会出现错误。这是我的主要组件的结构:

<template>
  <div id="app">
    <div class="toolbar">
      <button @click="add">Agregar grupo condicional</button>
    </div>
    <div id="constraints_list" ref="constraints_list">
      <div v-for="item in constraints_group" :key="item">
        <Suspense>
          <Constraint></Constraint>
        </Suspense>
      </div>
    </div>
  </div>
</template>

<script>
import Constraint from './components/Constraint'
import  h  from 'vue';

export default 
    name: 'app',
    components:  
        Constraint 
    ,
    data() 
      return 
        constraints_group: [],
        constraint_count: 0,
        constraint:
            gender: null
        
      
    ,
    mounted () 
      this.addConstraintBlock();
    ,
    methods: 

      addConstraintBlock() 
          this.constraint_count++;
          let instance = h(Constraint);
          this.constraints_group.push(instance);
      
    ,

</script>

这是我尝试创建第二个错误时的错误: This is the error when I create the second component and try to do the same flow as the first

我在这篇文章中找到 https://www.reddit.com/r/vuejs/comments/iwc7o4/vue3_what_happen_to_vueextend/ 一个“创建了 Vue.extend 函数的解决方法”的人,但该项目对我不起作用,它给了我以下错误:

Failed to compile.

./node_modules/mount-vue-component/dist/index.cjs.js 11:10
Module parse failed: Unexpected token (11:10)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| 
|   let vNode = vue.createVNode(component, props, children);
>   if (app?._context) vNode.appContext = app._context;
|   if (el) vue.render(vNode, el);
|   else if (typeof document !== 'undefined' ) vue.render(vNode, el = document.createElement('div'));

我试图弄清楚如何使用该加载器,但是,即使在我安装了加载器(以及许多其他加载器)、配置了 babel.config.json(如我发现的那样)等之后,还是没有运气。还尝试了重新创建代码在项目中,但也不起作用。

所以,在这一点上,我没有更多的想法。我试图找到更多方法,但我所做的一切都给了我一个错误。如果有人能给我一个想法、解决方法或什么的,我将非常非常感激不尽。

【问题讨论】:

【参考方案1】:

我觉得这不是关于 Vue 3,而是关于 Vue 的一般性......

在 Vue 中,您几乎从不在 &lt;script&gt; 块中创建组件实例(有些人会这样做,但这通常是因为他们不了解 Vue 的工作原理)。 Vue 是“声明式”和“数据驱动”的框架。这意味着您的模板输出是由数据驱动的——您无需创建组件,而是修改数据,模板将根据该数据为您生成组件...

检查这个简单的例子:

const piece = Vue.component('Piece', 
  props: ['number'],
  template: `<div> Piece  number  </div>`
)

const app = new Vue(
  el: "#app",
  components:  piece ,
  data() 
    return 
      counter: 0,
      pieces: []
    
  ,
  methods: 
    addPiece() 
      this.pieces.push(this.counter)
      this.counter++
    
  
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <button type="button" @click="addPiece">Add Piece</button>
  <hr>
  <Piece v-for="piece in pieces" :key="piece" :number="piece"/>
</div>

【讨论】:

以上是关于Vue3 渲染一个可扩展的异步组件列表的主要内容,如果未能解决你的问题,请参考以下文章

使用 s-s-r 时无法在 vue3 中使用异步组件

vue3.0组件监听异步数据,watch与reactive 的应用, watch与computed, 还有ref的使用

vue3.0组件监听异步数据,watch与reactive 的应用, watch与computed, 还有ref的使用

vue3.0组件监听异步数据,watch与reactive 的应用, watch与computed, 还有ref的使用

Webpack的代码分包&&Vue3中定义异步组件分包&&refs的使用

35 Vue3异步组件