Practice of dynamically creating dialog according to file name in vue+el-element

Practice of dynamically creating dialog according to file name in vue+el-element

background

The usual practice of using dialog boxes in a project is to encapsulate the dialog box into a component, import it where it is used, and then add it to the template, use visible.sync to control the display/hide of the dialog box, and listen to the confirm event to handle the user clicking OK. as follows:

 <confirm-dialog
     v-if="confirmDialogVisible"
     :title="$t(`mineData.tips.deleteDataset`)"
     :visible.sync="confirmDialogVisible"
     @confirm="confimHandler"
 ></confirm-dialog>

In the encapsulated dialog, it is also necessary to update visible when closing and trigger the confirm event when confirming:

 methods: {
    close() {
        this.$emit("update:visible", false);
    },
    confirm() {
        this.close();
        this.$emit("confirm");
    }
}

This approach not only causes all dialog components to be introduced when the page is initialized, which affects the loading speed, but also causes a lot of trouble when many dialog boxes are introduced into the page, which makes the page very messy: you need to insert a section of HTML for each dialog box, maintain a separate visible variable for each dialog box, add a confirm event listener for each dialog box...

Most of these operations are irrelevant to the business, and they are extremely similar.

So, is there a way to dynamically create a dialog through js?

createDialog("confirm-dialog.vue");

Just like above, you can open the dialog box according to the file name, without defining visible and adding a bunch of HTML and event callbacks, and you don’t even need to introduce the dialog component first!

Isn’t it simple! Are you excited? Keep reading.

accomplish

1. Encapsulated /utils/dialogControl.js

import Vue from 'vue'
async function createDialog (fileName, data) {
  const dialogsContext = require.context(
    '../components', // Define the scope of the search file true,
    /([a-zA-Z\-0-9]+)\.vue$/, // define file name rule 'lazy'
  )
  // Find the file with the passed name and load it let match = dialogsContext.keys().find((key) => key.includes(fileName))
  if (!match) return
  let componentContext = await dialogsContext(match)
  let temp = componentContext.default
  return new Promise(function (resolve, reject) {
    // Initialize configuration parameters let opt ​​= {
      data
    }
    let component = Object.assign({}, temp)
    let initData = {
      visible: true
    }
    Object.assign(initData, component.data())
    opt.data && Object.assign(initData, JSON.parse(JSON.stringify(opt.data)))
    component.data = function () {
      return initData
    }
    // Create a constructor to create an instance and mount let DialogC = Vue.extend(component)
    let dialog = new DialogC()
    // Close event let _onClose = dialog.$options.methods.onClose
    dialog.onClose = function () {
      resolve()
      dialog.$destroy()
      _onClose && _onClose.call(dialog)
      document.body.removeChild(dialog.$el)
    }
    // callback event let _onCallback = dialog.$options.methods.onCallback
    dialog.onCallback = function (...arg) {
      try {
        _onCallback && _onCallback()
        resolve(arg)
        dialog.$destroy()
        _onClose && _onClose.call(dialog)
        document.body.removeChild(dialog.$el)
      } catch (e) {
        console.log(e)
      }
    }
    dialog.$mount()
    // Clicking the close button will change visibility
    dialog.$watch('visible', function (n, o) {
      dialog === false && dialog.onClose()
    })
    document.body.appendChild(dialog.$el)
  })
}

export { createDialog }

illustrate:
1. You need to specify the path to search for files and the regular expression to match the name, so that some unnecessary files can be filtered out

2. Receive a fileName parameter to match the dialog file to be opened, and the data parameter is the data passed to the dialog box, which will be merged into the component's data

3. Use the visible variable to control the display/hide of the dialog box

4. Define an onClose method to close the dialog box, which can be used to close the dialog box

5. The onCallback method is used to pass values ​​to the parent component that calls the dialog box, such as passing values ​​to the parent component when clicking the OK button

2.dialog file definition

For example, in /components/ConfirmDialog.vue, the visible variable is used to control display/hide, onClose handles the close event, and the callback of the confirm button is onCallback (which is consistent with the definition in dialogControl.js).

<template>
    <el-dialog title="Prompt" :visible.sync="visible" width="30%">
        <span>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nesciunt quis
            perspiciatis fugiat molestiae provident accusantium repudiandae fugit
            Minima, eaque, repellat quibusdam iste sed ad? Debitis qui praesentium
            minus incidunt esse!
        <span slot="footer" class="dialog-footer">
            <el-button @click="onClose">Cancel</el-button>
            <el-button type="primary" @click="onCallback(true)">OK</el-button>
        </span>
    </el-dialog>
</template>

<script>
export default {
  data () {
    return {}
  },
  methods: {
  }}
</script>

3. Use

Introduce the createDialog method in dialogControl and directly pass in the file name to open it.

If there are other attributes, put them into the second parameter in the form of key-value pairs. These attributes will be merged into the data of the dialog component, so these attributes can be used directly in the dialog component.

The createDialog method gets a promise object, and its then method can get the result returned by confirm.

<template>
  <div>
    <h1>This is an show page</h1>
    <el-button type="primary" @click="openDialog">Open</el-button>
  </div>
</template>

<script>
import { createDialog } from "@/utils/dialogControl";
export default {
  methods: {
    openDialog() {
      let dialog = createDialog("confirm-dialog.vue");
      dialog.then((v) => {
        if (v) {
          console.info("OK");
        }
      });
    },
  },
};
</script>

The effect is as follows:

If you are still using the method at the beginning of the article to call the dialog box, then hurry up and use this method!

refer to:

https://www.freesion.com/article/43311065748/

This is the end of this article about the practice of dynamically creating dialogs based on file names in vue+el-element. For more relevant el-element dynamic creation of dialog content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of how to encapsulate dialog components in vue+element-ui projects
  • ElementUI displays multiple Dialogs on the same page
  • Solution to the failure of closing the dialog pop-up window in element-ui
  • Example of using Element Dialog
  • How to clear the verification condition after closing the dialog in element ui
  • Detailed explanation of element ui dialog box el-dialog closing event

<<:  CentOS 7.6 batch add, modify and delete virtual network cards operation introduction

>>:  HTML framework_Powernode Java Academy

Recommend

Collapsed table row element bug

Let's take an example: The code is very simple...

Detailed explanation of Linux zabbix agent deployment and configuration methods

1. Install zabbix-agent on web01 Deploy zabbix wa...

Example of how to enable Slow query in MySQL

Preface Slow query log is a very important functi...

MySQL5.7.27-winx64 version win10 download and installation tutorial diagram

MySQL 5.7 installation We are learning MySQL data...

Select web page drop-down list and div layer covering problem

Questions about select elements in HTML have been...

Linux server SSH cracking prevention method (recommended)

1. The Linux server configures /etc/hosts.deny to...

Introduction to vim plugin installation under Linux system

Table of contents Install vim plugin manager Add ...

Introduction to query commands for MySQL stored procedures

As shown below: select name from mysql.proc where...

Detailed installation process of Jenkins on Linux

Table of contents 1. Install JDK 2. Install Jenki...

Is the tag li a block-level element?

Why can it set the height, but unlike elements lik...

Detailed explanation of common usage of MySQL query conditions

This article uses examples to illustrate the comm...

Analysis of Mysql transaction characteristics and level principles

1. What is a transaction? A database transaction ...