Vueはダイアログのカプセル化を実装します

Vueはダイアログのカプセル化を実装します

ビジネスを書くときによくあるシナリオは、異なるページで同じフォームを呼び出す必要があることです。一般的なインタラクションは、ポップアップウィンドウの形式でフォームを表示することですが、各ページでフォームコンポーネントを繰り返し導入するのは面倒な場合があります。

解決策は2つあります。

  1. ルートコンポーネントに動的コンポーネントを導入し、ビジネスでthis.$root.openDialog(name, props)を通じて動的コンポーネントの表示形式を制御する
  2. これをプラグインにカプセル化して呼び出します。例: this.$dialog('EditDialog.vue', props)

もちろん、ビジネス Dialog コンポーネントには一連の仕様が必要です。Props は onOk および onCancel コールバックを受け取り、データ内に表示プロパティを定義します。

<テンプレート>
  <el-dialog :title="タイトル" :visible.sync="表示可能" 本文に追加>
    <!-- ビジネスコード -->
  </el-ダイアログ>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  props: ['onOk', 'ビジネスに必要なその他のプロパティ'],
  データ() {
    戻る {
      表示: 偽
    }
  }
}
</スクリプト>

Vue2 ライティング

Vue2ではプラグインとして書いた方が個人的には楽だと感じています。実装は以下のとおりです。一部の操作はミックスインを使用して業務から切り離しています。

欠点は、コンポーネントが動的に挿入され、コンポーネントを表示するには Vue devtools を更新する必要があることです。

const ミックスイン = {
  マウント() {
    document.body.appendChild(this.$el)
    this.visible = true
  },
  時計:
    表示(値) {
      // アニメーション終了後にインスタンスを破棄する if (value === false) {
        タイムアウトを設定する(() => {
          これを破棄します。
          if (this.$el && this.$el.parentNode) {
            this.$el.parentNode.removeChild(this.$el)
          }
        }, 400)
      }
    }
  }
}

エクスポートデフォルト{
  インストール(Vue, オプション) {
    Vue.prototype.$dialog = (名前、プロパティ) => {
      // プラグインの場所を基準に、静的コンパイル時に import('../components/dialogs/' + name) がチェックされます
        .then(モジュール => {
          const コンポーネント = module.default
          const ミックスイン = コンポーネント.ミックスイン || []
          mixins.push(mixin) // 自動的に開き、ライフサイクル関数と破棄操作を動的にミックスインします。component.mixins = mixins
          Vue.extend(コンポーネント) を返します
        })
        .then(ダイアログ => {
          const ダイアログ = 新しいダイアログ({
            propsData: props || {}
          })
          ダイアログ.$mount()
        })
    }
  }
}

呼び出し方法は次のとおりです。矢印関数を使用すると、onOk コールバックの this ポインターを回避できることに注意してください。

this.$dialog('GroupEdit.vue', {
  タイプ: '編集'、
  グループ: {}、
  オンOK: () => {
    this.freshList()
  }
})

Vue3プラグインのバージョンの記述

残念ながら、Vue3 のアップグレードにより、Vue.extend と $mount がなくなり、コンポーネントはアプリケーション内でのみレンダリングできるようになりました。

各アプリケーション間のデータは分離されているため、プラグインなどを再度導入する必要があります。同時に、やりとりをしたい場合も面倒です。同じ vuex インスタンスを導入すればできるはずですが、試していません。

結合を減らすために、レンダリングをマウントするための新しいアプリケーションのみを作成することができます

'vue' から {createApp、defineComponent} をインポートします。
'element-plus' から ElementPlus をインポートします

const ミックスイン = {
  マウント() {
    document.body.appendChild(this.$el)
    this.visible = true
  },
  時計:
    表示(値) {
      // アニメーション終了後にインスタンスを破棄する if (value === false) {
        タイムアウトを設定する(() => {
          this.$.appContext.app.unmount()
        }, 400)
      }
    }
  }
}

エクスポートデフォルト{
  インストール(アプリ) {
    app.config.globalProperties.$dialog = (名前、プロパティ) => {
      インポート('../components/dialogs/' + 名前)
        .then(モジュール => {
          const コンポーネント = module.default
          mixins = component.mixins || [] とします。
          mixins.push(ミックスイン)
          コンポーネント.mixins = ミックスイン

          defineComponent(コンポーネント) を返します
        })
        .then(ダイアログ => {
          const app = createApp(ダイアログ、props || {})
          app.use(ElementPlus)
          app.mount(document.createElement('div'))
        })
    }
  }
}

Vue3 動的コンポーネントの記述

Vue3ではプラグイン版も要件を満たしていますが、完全に新規アプリケーションです。これにアクセスするのはまだ少し面倒です。業務では$root、vuex、routerを使用します。

したがって、Vue3 では動的コンポーネントの方が優れています。

ルートコンポーネントに動的コンポーネントを導入し、いくつかの制御変数を定義する

<テンプレート>
  <ルータービュー></ルータービュー>
  <component :is="currentDialog" v-bind="currentDialogProps" />
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  データ() {
    戻る {
      現在のダイアログ: null、
      現在のダイアログプロパティ: null
    }
  }
}
</スクリプト>

this.$root.$dialog() を呼び出すと、見た目が醜くなります。実際には、プラグインの効果を手動でシミュレートすることもできます。

const app = createApp(App)
定数 vm = app.mount('#app')

initDialog(アプリ、vm)

関数 initDialog(app, vm) {
  const ミックスイン = {
    マウント() {
      this.visible = true
    },
    時計:
      表示(値) {
        // アニメーション終了後にインスタンスを破棄する if (value === false) {
          タイムアウトを設定する(() => {
            this.$root.currentDialog = null
            this.$root.currentDialogProps = {}
          }, 400)
        }
      }
    }
  }

  app.config.globalProperties.$dialog = (名前、プロパティ) => {
    import('./components/dialogs/' + name).then(module => {
      const コンポーネント = module.default
      mixins = component.mixins || [] とします。
      mixins.push(ミックスイン)
      コンポーネント.mixins = ミックスイン
      // defineComponent(component) は必要ありません
      vm.currentDialog = markRaw(コンポーネント)
      vm.currentDialogProps = markRaw(props || {})
    })
  }
}

ちょっとしたハックな書き方

Vue3コンポーネントインスタンスはアプリケーションインスタンスを取得します

vm.$.appContext.app == アプリ

Vue3 アプリケーション インスタンスはコンポーネント インスタンスを取得します。_instance は開発環境でのみアクセスできることに注意してください。

app._instance.proxy == vm
app._instance.root.proxy == vm
app._instance.ctx.$root == vm

まだいくつかのトリックがありますが、使用しない方がよいでしょう。

const app = createApp(App)
定数 vm = app.mount('#app')

process.env.NODE_ENV === 'production'の場合{
  アプリ._インスタンス = {
    プロキシ: vm、
    根: {
      プロキシ: vm
    },
    ctx: {
      $ルート:vm
    }
  }
}

Vue のダイアログ カプセル化の実装に関するこの記事はこれで終わりです。Vue ダイアログ カプセル化に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • vue+element-ui プロジェクトでダイアログ コンポーネントをカプセル化する方法の詳細な説明
  • より使いやすいダイアログコンポーネントをカプセル化するプロセスの詳細な説明

<<:  Linuxファイルシステム操作の実装

>>:  MySQL エラー: 接続数が多すぎる場合の解決策

推薦する

CentOS 7 での mysql 5.7 のインストール チュートリアル

1. 公式MySQL Yumリポジトリをダウンロードしてインストールする 実行ファイル: mysql...

MySQL マスター スレーブ データが矛盾しています。プロンプト: Slave_SQL_Running: 解決策はありません

この記事では、MySQL マスターとスレーブ データ間の不一致の解決方法と、プロンプト「Slave_...

MySQL 5.7.20\5.7.21 無料インストール版のインストールと設定のチュートリアル

参考までに、mysql 5.7.20 / 5.7.21 をダウンロード、インストール、構成します。具...

MySQL の完全なデータベース バックアップからデータベースとテーブルを復元する方法

公式の MySQL ダンプ ツールで、特定のデータベースのみを復元するにはどうすればよいですか?完全...

Dockerのクイックガイド

Docker は、安全で繰り返し可能な環境でソフトウェアを自動的にデプロイする方法を提供し、コンピュ...

Linux で実行中のすべてのプロセスを表示する方法

ps コマンドを使用できます。プロセスの PID など、現在実行中のプロセスに関する関連情報を表示で...

Centos7 esxi6.7 テンプレートの実際のアプリケーションの詳細な説明

1. Centos7.6システムを作成し、システムを最適化する1. NetworkManagerをオ...

UTF-8 ファイルの Unicode 署名 BOM (バイト オーダー マーク) の問題

最近、UTF8 エンコードの中国語 Zen Cart Web サイトをデバッグしているときに奇妙な現...

Nginx を使用してグレースケール リリースを実装する

グレースケールリリースとは、白と黒をスムーズに移行できるリリース方法を指します。 ABテストとは、グ...

HTMLテーブルではテーブルの外側の境界線のみが表示されます

質問があります。Dreamweaver で、3 行 1 列のログイン フォーム (ログイン、登録、パ...

MySQLでよく使われる4つのストレージエンジンについて簡単に説明します。

よく使われる4つのMySQLエンジンの紹介(1):MyISAMストレージエンジン:トランザクションや...

uniapp プロジェクトをデスクトップ アプリケーションとしてパッケージ化する方法

Electronのインストール cnpm 電子をインストール -g electron-package...

SSHを使用してDockerサーバーに接続する方法

初めて docker に触れたときは本当に戸惑いました。初心者向けのチュートリアルを長い間読みました...

JavaScript のプライベート クラス フィールドと TypeScript のプライベート修飾子の詳細な説明

目次JavaScript のプライベート クラス フィールドとプライバシーの必要性JavaScrip...

MySQL トリガーの基本的な使い方(作成、表示、削除など)の詳細な説明

目次1. MySQLトリガーの作成: 1. MySQLトリガー作成構文: 2. MySQL作成構文の...