ホームページ > 記事 > ウェブフロントエンド > 解決できない「動的マウント」の問題をVueを使って解決してみよう
一部の特殊なシナリオでは、コンポーネントを使用するタイミングが決定できない、または使用したいコンポーネントが Vue のテンプレート内で決定できない場合があります。この場合、コンポーネントを動的にマウントするか、ランタイム コンパイルを使用してコンポーネントを動的に作成してマウントする必要があります。
今日は、実際のプロジェクトから始めて、実際に顧客の問題を解決するときにコンポーネントを動的にマウントする方法を確認し、動的マウントの問題を解決する完全なプロセスを示します。
スプレッドシート コントロール SpreadJS が実行されているとき、次のような関数があります。セルをクリックすると、セルの内容を編集するための入力ボックスが表示されます。ユーザーは、カスタム セル タイプの仕様に従って入力ボックスのフォームをカスタマイズし、必要に応じてフォーム フォーム入力タイプを統合できます。
この入力ボックスの作成と破棄は、セル タイプの対応するメソッドを継承することによって実現されます。そのため、ここで問題が発生します。この動的作成メソッドは、VUE テンプレートで単純に構成して直接使用することはできません。 [関連する推奨事項: vuejs ビデオ チュートリアル ]
少し前に、お客様から次のような質問がありました。コントロールのカスタム セルは次のような Vue コンポーネントをサポートしていますか? ElementUIのオートコンプリート?
前述の問題のため:
# 長い間考えた後、私はお客様に真剣に答えました。「コンポーネントの運用ライフサイクルは、一貫性がないので使用できません」と言いましたが、彼は再び話題を変え、この問題は汎用コンポーネントを使用して解決できると言いました。
問題は正常に解決されました。
しかし、このどうしようもない「使えない」が、最近では真夜中の夢の中でも越えられないハードルにもなっている。
その後、ある日 Vue のドキュメントを見ていたら、App は実行中に #app にマウントされているのではないかと思いました。理論的には、他のコンポーネントも必要な Dom に動的にマウントできるはずなので、作成タイミングの問題は解決されます。
ドキュメントの表示を続けましょうグローバル APIVue.extend(options) は extend によって作成されます。 Vue インスタンスは、$mount メソッドを使用して DOM 要素に直接マウントできます。これはまさに必要なことです。
<div id="mount-point"></div> // 创建构造器 var Profile = Vue.extend({ template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount('#mount-point')
SpreadJS カスタム セルの例に従って AutoCompleteCellType を作成し、セルに設定します。
function AutoComplateCellType() { } AutoComplateCellType.prototype = new GC.Spread.Sheets.CellTypes.Base(); AutoComplateCellType.prototype.createEditorElement = function (context, cellWrapperElement) { // cellWrapperElement.setAttribute("gcUIElement", "gcEditingInput"); cellWrapperElement.style.overflow = 'visible' let editorContext = document.createElement("div") editorContext.setAttribute("gcUIElement", "gcEditingInput"); let editor = document.createElement("div"); // 自定义单元格中editorContext作为容器,需要在创建一个child用于挂载,不能直接挂载到editorContext上 editorContext.appendChild(editor); return editorContext; } AutoComplateCellType.prototype.activateEditor = function (editorContext, cellStyle, cellRect, context) { let width = cellRect.width > 180 ? cellRect.width : 180; if (editorContext) { // 创建构造器 var Profile = Vue.extend({ template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount(editorContext.firstChild); } };
実行し、ダブルクリックして編集状態に入りますが、エラーが見つかりました
#エラー メッセージによると、現時点では 2 つの解決策があります。[Vue 警告]: テンプレート コンパイラが利用できない Vue のランタイム専用ビルドを使用しています。テンプレートをレンダリング関数にプリコンパイルするか、コンパイラに含まれるビルドを使用してください。
<template> <div> <p>{{ firstName }} {{ lastName }} aka {{ alias }}</p> </div> </template> <script> export default { data: function () { return { firstName: "Walter", lastName: "White", alias: "Heisenberg", }; }, }; </script> import AutoComplate from './AutoComplate.vue' AutoComplateCellType.prototype.activateEditor = function (editorContext, cellStyle, cellRect, context) { let width = cellRect.width > 180 ? cellRect.width : 180; if (editorContext) { // 创建构造器 var Profile = Vue.extend(AutoComplate); // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount(editorContext.firstChild); } };
ダブルクリックして編集状態に入り、コンポーネントの内容を確認します
次のステップでは、カスタム セルについても、次の設定を行う必要があります。コンポーネントContentの編集を取得し、コンポーネントにpropsを追加すると同時に、マウント時に作成されるVueComponentインスタンス上のすべてのpropsコンテンツを直接取得することで、対応する操作でデータ取得設定を実現できます。
AutoComplate.vue を更新し、プロパティを追加し、編集用の入力を追加します。
<template> <div> <p>{{ firstName }} {{ lastName }} aka {{ alias }}</p> <input type="text" v-model="value"> </div> </template> <script> export default { props:["value"], data: function () { return { firstName: "Walter", lastName: "White", alias: "Heisenberg", }; }, }; </script>
this.vm を通じて VueComponent インスタンスを保存し、getEditorValue メソッドと setEditorValue メソッドで VUE コンポーネントの Value を取得して設定します。 。編集後、$destroy() メソッドを呼び出して、動的に作成されたコンポーネントを破棄します。
AutoComplateCellType.prototype.activateEditor = function (editorContext, cellStyle, cellRect, context) { let width = cellRect.width > 180 ? cellRect.width : 180; if (editorContext) { // 创建构造器 var Profile = Vue.extend(MyInput); // 创建 Profile 实例,并挂载到一个元素上。 this.vm = new Profile().$mount(editorContext.firstChild); } }; AutoComplateCellType.prototype.getEditorValue = function (editorContext) { // 设置组件默认值 if (this.vm) { return this.vm.value; } }; AutoComplateCellType.prototype.setEditorValue = function (editorContext, value) { // 获取组件编辑后的值 if (editorContext) { this.vm.value = value; } }; AutoComplateCellType.prototype.deactivateEditor = function (editorContext, context) { // 销毁组件 this.vm.$destroy(); this.vm = undefined; };
プロセス全体が実行されました。必要なのは、AutoComplate.vue で入力を ElementUI の el-autocomplete に置き換え、対応するメソッドを実装することだけです。
結果実際、動的マウントは複雑な操作ではありません。Vue の例を理解した後、vm を介してインスタンスを操作し、動的マウントやランタイム コンパイルされたコンポーネントを柔軟に使用することは難しくありません。
実は、すべての解決策は Vue チュートリアルの入門チュートリアルに記載されていますが、スキャフォールディングを使用したり、さまざまなツールを使用したりすることで、Vue の本来の目的が忘れられ、単純な問題がかえって複雑になってしまいます。
今日の共有はここで終了します。今後はさらに本格的で興味深いコンテンツをお届けします~
プログラミング関連の知識をさらに詳しく知りたい場合は、次のサイトをご覧ください: プログラミング入門! !
以上が解決できない「動的マウント」の問題をVueを使って解決してみようの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。