Heim > Web-Frontend > View.js > Wie vue3 die Tags defineAsyncComponent und Component verwendet, um dynamische Rendering-Komponenten zu implementieren

Wie vue3 die Tags defineAsyncComponent und Component verwendet, um dynamische Rendering-Komponenten zu implementieren

王林
Freigeben: 2023-05-12 17:55:21
nach vorne
1372 Leute haben es durchsucht

1. Grundlegende dynamische Einführung von Komponenten:

Einfache dynamische Einführung bedeutet, dass das Frontend weiß, welche Komponenten eingeführt werden müssen, und mehrere Komponenten in die übergeordnete Komponente einführt, diese jedoch nicht rendert Wenn die Bedingungen erfüllt sind, wird die angegebene Komponente an einem bestimmten Ort gerendert.

<template>
	 <custom-modal ref="custom"></custom-modal>
</template>
<script>
 import {
    reactive,
    ref,
    shallowReactive,
    onActivated,
    defineAsyncComponent,
  } from &#39;vue&#39;;
 const customModal = defineAsyncComponent(() => import(&#39;./modal/CustomModal.vue&#39;));
 const custom = ref();
 </script>
Nach dem Login kopieren

Das obige Beispiel besteht darin, die Montagekomponente über defineAsyncComponent von vue zu implementieren und sie customModal zuzuweisen. Sie können &lt direkt verwenden Die Vorlage ;custom-modal> wird als Beschriftung verwendet oder kann dem Attribut is in der Komponente zugewiesen werden. Das Attribut is verweist auf eine Variable, und der Wert der Variablen kann durch das Geschäft dynamisch geändert werden Logik zum Implementieren mehrerer Komponenten. Hin und her gerendert defineAsyncComponent实现挂载组件,并赋值给customModal ,模板中可以直接使用<custom-modal>作为标签使用,也可以将它赋值给component中的is属性,is属性执向一个变量,可通过业务逻辑动态,更改该变量的值,就可以实现多个组件进行来回的渲染了

<template>
<component :is="componentKey" ref="custom"></component>
</template>
 import {
    reactive,
    ref,
    shallowReactive,
    onActivated,
    defineAsyncComponent,
  } from &#39;vue&#39;;
 const componentKey = ref(null);
 const components: any = shallowReactive({});
 const customModal = defineAsyncComponent(() => import(&#39;./modal/CustomModal.vue&#39;));
 componentKey  = customModal
Nach dem Login kopieren

二、复杂的引入:不确定到底引入什么组件,组件的路径由后端返回

将以上代码 添加到项目代码中,并不能实现,虽然引入不报错,但是ref一直为undefined,无法调用动态组件内的open函数。
不断尝试了很多次,得出以下结论

1.起初是在按钮的click函数内去挂载自定义组件并调用ref函数的,ref为undefined。
尝试多次不能实现功能(这里是挂载与调用最合适的位置),
2.接着又在初始化配置数据时(查询后端sql),axios的then函数内挂载组件,然后点击按钮的地方调用ref内的函数,ref依旧为null。
3. 接着在最外层,调用初始化时挂载,也就是生命周期函数体内,测试还是一样的结果。
4. 接着发现带有async函数体内挂载组件,也无法完成。
5.单独写个函数,不加async,函数内挂载组件,然后再生命周期外调用该函数,按钮内调用ref内的方法,成功弹窗。这并不是我想要的,因为路径不是固定的,它要等到后端sql放回结果,才能执行。

总结:上面的多次测试,得出以下结论,都不能让动态组件ref对象有值
1、不能在组件的事件函数内挂载,

Wie vue3 die Tags defineAsyncComponent und Component verwendet, um dynamische Rendering-Komponenten zu implementieren

2、不能在axios的then函数体内挂载

Wie vue3 die Tags defineAsyncComponent und Component verwendet, um dynamische Rendering-Komponenten zu implementieren

3、不能在带有async声明的函数体内挂载

Wie vue3 die Tags defineAsyncComponent und Component verwendet, um dynamische Rendering-Komponenten zu implementieren

4、不能在vue的生命周期内挂载

Wie vue3 die Tags defineAsyncComponent und Component verwendet, um dynamische Rendering-Komponenten zu implementieren

5、只能在最外层挂载实现,这时ref才是个对象。

好在天无绝人之路;脑海里有个思路:
页面初始化时将项目里所有的全局挂载view组件扔到一个object内,使用component组件,is:对应object内指定的组件对象,然后通过后端的数据,这时后端就不用给组件路径了,给个组件名,我从object中找到挂载的组件然后将对象给is。
const modules = import.meta.glob(&#39;@/views/*/**.vue&#39;);

<template>
<component :is="componentKey" ref="custom"></component>
</template>
<script>
 import {
    reactive,
    ref,
    shallowReactive,
    onActivated,
    defineAsyncComponent,
  } from &#39;vue&#39;;
	
	//声明componentkey,用于告诉component当前挂载什么组件,components为一个对象,存放多个不确定的自定义组件。
  const componentKey = ref(null);
  const components: any = shallowReactive({});

  // 组件挂载
  const initTableConfig = (gridId, type) => { 
   queryTableConfig({ gridId }).then(({ data }) => {
      if (type === &#39;main&#39;) {
        Object.assign(mainConfig, data);
        tabsKey.value = -1;
      } else {
        tabsDetail.value.push(data);
        tabsKey.value = tabsDetail.value.length - 1;
      }
      // 涉及到自定义组件的部分,这里需要提前挂载,在用到时不至于ref为null
      XEUtils.objectEach(data.action, (action, key) => {
        if (
          action.modalCfg &&
          action.modalCfg.type === &#39;CustomModal&#39; &&
          action.modalCfg.src
        ) {
          components[action.actionId] = defineAsyncComponent(
            () => import(`../../../${action.modalCfg.src}`)
          );
          //注意:这里的路径后端只能返回相对路径,不能使用@/xxx/xxx.vue ,不能使用src/xxx/xxx.vue,只能./xxx.vue或者../../xxx/xxx.vue。由于并不确定组件在什么位置,避免容易出错的原则,我在前端通过../../../的形式将路径回退到src下,后端只需要从src下配置路径即可,不用考虑那么多了。如后端src的值为src/xxx/xxx/xxx.vue 则在前端合成的路径就为../../../src/xx/xxx/xxx.vue
          componentKey.value = components[action.actionId];
          // 为什么componentKey.vue在这里赋值,在后面点击窗口后又赋值,这里能不能省略。
		//	答:这里省略的话,到点击按钮触发时会报错,第一次点击会报错,第二次点击不会报错,窗口正常弹出。可能是因为,组件挂载时并没有引入组件,只在使用时才引入,如果上面不提前将挂载好的组件引入进来,后面触发事件触发时引入在调用ref,执行太快,costom就会报错,所以才会点两次才弹窗。
        }
      });
    });
  };
 </script>
Nach dem Login kopieren

2. Komplexe Einführung: Nicht sicher, welche Komponente eingeführt werden soll, der Pfad der Komponente wird vom Backend zurückgegeben

Add Der obige Code zum Projektcode kann nicht implementiert werden, obwohl bei der Einführung kein Fehler gemeldet wird, ist ref immer undefiniert und die offene Funktion in der dynamischen Komponente kann nicht aufgerufen werden. Nachdem wir es viele Male versucht hatten, kamen wir zu folgendem Schluss

1 Zunächst haben wir die benutzerdefinierte Komponente gemountet und die Ref-Funktion in der Klickfunktion von aufgerufen Die Schaltfläche, ref ist undefiniert. Nach vielen Versuchen kann die Funktion nicht realisiert werden (dies ist der am besten geeignete Ort zum Mounten und Aufrufen).

2 Mounten Sie sie dann beim Initialisieren der Konfigurationsdaten (Abfragen des Back-End-SQL). in der then-Funktion der Axios-Komponente und rufen Sie dann die Funktion in ref auf, wo auf die Schaltfläche geklickt wird, ref ist immer noch null.

3. Rufen Sie dann in der äußersten Schicht den Mount während der Initialisierung auf, dh innerhalb des Lebenszyklusfunktionskörpers sind die Testergebnisse immer noch dieselben.
4. Dann stellte ich fest, dass die Montage von Komponenten innerhalb des asynchronen Funktionskörpers nicht abgeschlossen werden konnte.

5. Schreiben Sie eine separate Funktion, ohne Async hinzuzufügen, mounten Sie die Komponente in der Funktion, rufen Sie dann die Funktion außerhalb des Lebenszyklus auf, rufen Sie die Methode in der Referenz in der Schaltfläche auf und das Fenster wird erfolgreich angezeigt. Dies ist nicht das, was ich möchte, da der Pfad nicht festgelegt ist und nicht ausgeführt werden kann, bis das Backend-SQL die Ergebnisse zurückgibt. #🎜🎜##🎜🎜#Zusammenfassung: Die oben genannten mehreren Tests haben zu folgender Schlussfolgerung geführt: Das dynamische Komponentenreferenzobjekt darf keinen Wert haben#🎜🎜#1 Es kann nicht innerhalb der Ereignisfunktion der Komponente gemountet werden , #🎜🎜# #🎜🎜#Wie verwendet vue3 defineAsyncComponent- und Component-Tags, um dynamische Rendering-Komponenten implementieren“ /> #🎜🎜##🎜🎜#2. Es kann nicht im then-Funktionskörper von axios gemountet werden #🎜🎜##🎜🎜#<img src=#🎜🎜##🎜🎜#3. Kann nicht in einer Funktion gemountet werden Körper mit asynchroner Deklaration#🎜🎜##🎜 🎜#Wie verwendet vue3 defineAsyncComponent und Komponenten-Tags zum Implementieren dynamischer Rendering-Komponenten#🎜 🎜##🎜🎜#4. Es kann nicht während des Lebenszyklus von vue gemountet werden#🎜🎜##🎜🎜#Wie vue3 defineAsyncComponent- und Component-Tags verwendet, um dynamische Rendering-Komponenten zu implementieren#🎜🎜##🎜🎜#5. Es kann nur gemountet werden und auf der äußersten Ebene implementiert, und dann ist ref ein Objekt. #🎜🎜##🎜🎜# Glücklicherweise gibt es immer eine Möglichkeit; ich habe eine Idee im Kopf: #🎜🎜# Wenn die Seite initialisiert ist, werfen Sie alle global gemounteten Ansichtskomponenten im Projekt in ein Objekt und verwenden Sie das Komponentenkomponente ist: Entspricht dem im Objekt angegebenen Komponentenobjekt und übergibt dann die Backend-Daten. Zu diesem Zeitpunkt muss das Backend den Komponentennamen nicht angeben, ich finde die bereitgestellte Komponente aus dem Objekt und geben Sie dann das Objekt an is. #🎜🎜#const module = import.meta.glob('@/views/*/**.vue'); // Alle Projektpfade abrufen #🎜🎜#Module sind alle in Ansichten Die Relativer Pfad von Vue, dann Schleife, implementieren Sie die Montage im Schleifenkörper und speichern Sie es in einem Objekt, wobei der Schlüssel der Projektname des relativen Pfads ist (Sie können Folgendes abfangen). #🎜🎜##🎜🎜##🎜🎜# Mit den oben genannten Ideen wurde durch wiederholtes Testen und Implementieren die endgültige Funktion realisiert. #🎜🎜##🎜🎜#
		} else if (action.modalCfg.type === &#39;CustomModal&#39;) {
  		// 这里的actionid和组件是对应的,所以在按钮触发后,通过按钮携带的actionid能取到对应的组件。
          componentKey.value = components[action.actionId];
          custom.value.init(row);
        }
Nach dem Login kopieren
#🎜🎜##🎜🎜# Klicken Sie auf die Schaltfläche, um das Ereignis auszulösen und festzulegen, welche Komponente das Popup-Fenster angezeigt wird #🎜🎜##🎜🎜#rrreee#🎜🎜#Danach Die obige Methode: irgendwo Bei der Montage wird kein Fehler gemeldet, was eine perfekte Lösung ist. #🎜🎜#Hinweis: Das Mounten und Verwenden von Ref können nicht im selben Methodenkörper erfolgen. Wenn möglich, wird das Mounten beim Laden der Seite durchgeführt und es wird kein Fehler gemeldet, wenn Ref aufgerufen werden muss. #🎜🎜#

Das obige ist der detaillierte Inhalt vonWie vue3 die Tags defineAsyncComponent und Component verwendet, um dynamische Rendering-Komponenten zu implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage