単純な動的導入とは、フロントエンドがどのコンポーネントを導入するかを認識し、複数のコンポーネントを親コンポーネントに導入しますが、レンダリングはせず、特定の条件を満たすことを意味します。 、指定されたコンポーネントを特定の場所にレンダリングします。
<template> <custom-modal ref="custom"></custom-modal> </template> <script> import { reactive, ref, shallowReactive, onActivated, defineAsyncComponent, } from 'vue'; const customModal = defineAsyncComponent(() => import('./modal/CustomModal.vue')); const custom = ref(); </script>
上記の例は、vue の defineAsyncComponent
を通じてマウント コンポーネントを実装し、それを customModal
に割り当てます。<custom-modal> は、で直接使用できます。テンプレート ;
はタグとして使用されるか、コンポーネントの is 属性に割り当てられます。is 属性は変数を指します。変数の値はビジネス ロジックを通じて動的に変更でき、複数のコンポーネントで変更できます。
<template> <component :is="componentKey" ref="custom"></component> </template> import { reactive, ref, shallowReactive, onActivated, defineAsyncComponent, } from 'vue'; const componentKey = ref(null); const components: any = shallowReactive({}); const customModal = defineAsyncComponent(() => import('./modal/CustomModal.vue')); componentKey = customModal
上記のコードをプロジェクト コードに追加することはできません。導入部ではエラーは報告されませんが、 ref は常に未定義であり、動的コンポーネントの open 関数を呼び出すことはできません。
何度も試した結果、次の結論に達しました
1. まず、カスタム コンポーネントをマウントし、ボタンのクリック関数で ref 関数を呼び出します。 ref が未定義でした。
何度試しても機能が実現できない(マウントと呼び出しに最適な場所です)
2. その後、構成データの初期化(バックエンドSQLへのクエリ)時にコンポーネントがマウントされます。 axios の then 関数、その後、ボタンがクリックされた場所で ref の関数が呼び出されますが、ref はまだ null です。
3. 次に、最外層で、初期化中にマウントを呼び出します (つまり、ライフサイクル関数本体内で) テスト結果は同じです。
4. すると、async 関数本体内のコンポーネントのマウントが完了できないことがわかりました。
5. async を追加せずに別の関数を作成し、関数内でコンポーネントをマウントし、ライフサイクルの外で関数を呼び出すと、ボタンの ref 内のメソッドを呼び出すと、ウィンドウが正常にポップアップします。パスが固定されておらず、バックエンド SQL が結果を戻すまで実行できないため、これは私が望むものではありません。
要約: 上記の複数のテストにより、次の結論が得られました: 動的コンポーネント ref オブジェクトに値を持つことは許可されません
1。コンポーネントのイベント関数内にマウントすることはできません
2. axios の then 関数本体にはマウントできません
##3. 関数本体にはマウントできませんasync 宣言4. vue のライフサイクル中はマウントできません。5. のみ可能です。最外層に実装することになりますが、このときrefはオブジェクトとなります。 幸いなことに、確実なパスはありませんが、私の頭の中にアイデアがあります:
ページが初期化されたら、プロジェクト内でグローバルにマウントされたすべてのビュー コンポーネントをオブジェクトにスローし、そのコンポーネント コンポーネントを使用します。 is: 対応する オブジェクトで指定されたコンポーネントオブジェクトはバックエンドデータを介して渡されます このとき、バックエンドはコンポーネントのパスを与える必要はありませんが、コンポーネント名を与えます オブジェクトからマウントされたコンポーネントを見つけて、の対象です。
const modules = import.meta.glob('@/views/*/**.vue'); // すべてのプロジェクト パスを取得します
mudules はビュー パス内のすべての vue に相対的ですをループし、ループ本体でマウントを実装し、オブジェクトに格納します。キーは相対パスのプロジェクト名です (以下でインターセプトできます)。
上記のアイデアのもと、テストと実装を繰り返し、最終的な機能を実現しました。
<template> <component :is="componentKey" ref="custom"></component> </template> <script> import { reactive, ref, shallowReactive, onActivated, defineAsyncComponent, } from 'vue'; //声明componentkey,用于告诉component当前挂载什么组件,components为一个对象,存放多个不确定的自定义组件。 const componentKey = ref(null); const components: any = shallowReactive({}); // 组件挂载 const initTableConfig = (gridId, type) => { queryTableConfig({ gridId }).then(({ data }) => { if (type === 'main') { 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 === 'CustomModal' && 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>
ボタンをクリックしてイベントをトリガーし、ポップアップ ウィンドウにどのコンポーネントがポップアップするかを決定します
} else if (action.modalCfg.type === 'CustomModal') { // 这里的actionid和组件是对应的,所以在按钮触发后,通过按钮携带的actionid能取到对应的组件。 componentKey.value = components[action.actionId]; custom.value.init(row); }
注: ref のマウントと使用を同じメソッド本体内で行うことはできません。可能であれば、ページがロードされるときにマウントが実行され、ref を呼び出す必要があるときにエラーは報告されません。
以上がvue3 がどのようにdefineAsyncComponent タグとコンポーネント タグを使用して動的レンダリング コンポーネントを実装するかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。