preface

The research idea of this paper is to read Element source code, and then automatically write components step by step to improve their corresponding functions.

Today we’ll look at how Element’s Loading component is written.

Basic implementation

In Element, using the v-loading command on the tag enables the loading component to display hidden functions. In the most basic implementation, we will not use this feature. Instead, we will put the el-loading tag in the test page.

Test code:

<template> <div> <! --> <el-loading /> </div> </template> <script> import ElLoading from '.. /.. /components/Loading/loading.vue' export default { name: 'LoadingShownPage', components: { ElLoading } }Copy the code

Component code:

<template>
     <transition name="el-loading-fade">
         <div
            class="el-loading-mask">
            <div class="el-loading-spinner">
                <svg class="circular" viewBox="25 25 50 50">
                    <circle class="path" cx="50" cy="50" r="20" fill="none"/>
                </svg>
            </div>
        </div>
     </transition>
</template>

<script>
export default {
}
</script>
Copy the code

The effect:

As you can see, our component only needs a few simple tags to achieve the effect.

Using the v-loading command to display and hide the loading component

In our study of InputNumber, we first used the custom command directive to add a persistent V-repeat -click event to the component. This time, you need to customize a v-loading command. The difference is that this is not a local component registration, but a global registration:

import Vue from 'vue'; import Loading from './loading.vue'; const Mask = Vue.extend(Loading); Vue.directive('loading', {bind: function(el, binding, vnode) {// The element to which el binds can be used to manipulate the DOM directly. // binding Binds the object associated with the value. // vnode current virtual node const mask = new mask ({el: document.createElement('div'), }) console.log('mask',mask) el.instance = mask; // Place loading component instance on el.instance el.mask = mask.$el; el.appendChild(el.mask); // Add the LOADING component's DOM to the bound component'S DOM // Control the loaing display to hide binding.value && toggleLoading(el, binding); } update: function(el, binding) { if (binding.oldValue ! == binding.value) { toggleLoading(el, binding); }}})Copy the code

This simply introduces the file with the code to the page and makes it execute. The v-loading command is supported globally.

Next, implement the logic that controls the display and hiding of loading.

First add data named Visible to the Loading component. Then add v-show=”visible” to the root div. Then control visible in toggleLoading.

const toggleLoading = (el, If (binding.value) {// v-loading=ture el.instance.visible = true; } else { // v-loading=false el.instance.visible = false; }}Copy the code

Loading is now dynamically displayed and hidden when we change the true/false of v-loading.

Importing the Loading component through a vUE plug-in

Now we are using the method introduced directly in the test page:

// directive.js is the file in which the above code is located. /.. /components/Loading/directive.js'Copy the code

Now let’s do it as a plugin.

In a directive. In js:

const loadingDirective = {}; Loadingdirective. install = Vue => {// put the above content here... } export default loadingDirectiveCopy the code

In the main. In js:

import loadingDirective from './components/Loading/directive.js'

Vue.use(loadingDirective);
Copy the code

After testing, v-loading is still easy to use. Loading components can be divided into command mode and service mode. The principle of command mode has been basically understood.

Support region loading

Add style el-loading-parent-relative to elements bound to V-loading. The principle is to find an element’s position: relative;

if (el.originalPosition ! == 'absolute' && el.originalPosition ! == 'fixed') { addClass(el, 'el-loading-parent--relative'); }Copy the code

Effect:

Support global loading

Write v-load. fullscreen=”loading” on the test page. The fullscreen modifier is added.

Then in the toggleLoading method write:

if (binding.value) { // v-loading=ture el.instance.visible = true; if (binding.modifiers.fullscreen) { addClass(el.mask, 'is-fullscreen'); }}Copy the code

If there is a fullscreen modifier, add the IS-Fullscreen style. The principle is to make loading component position: fixed; . This is full screen loading again.

Using Loading as a service

Loading can also be controlled in the following way

// Enable loading const loading = this.$loading(); // Close loading loading.close();Copy the code

Write a service.js file

import Vue from 'vue'; import loadingVue from './loading.vue'; import { addClass } from '.. /.. /utils/dom' const LoadingConstructor = Vue.extend(loadingVue); LoadingConstructor.prototype.close = function() { this.visible = false; } const loadingService = () => { let instance = new LoadingConstructor({ el: document.createElement('div'), }); if (instance.originalPosition ! == 'absolute' && instance.originalPosition ! == 'fixed') { addClass(parent, 'el-loading-parent--relative'); } document.body.appendChild(instance.$el); instance.visible = true; return instance; } export default loadingService;Copy the code

Using loadingService in main.js:

import loadingService from './components/Loading/service.js'
Vue.prototype.$loading = loadingService;
Copy the code

This can be done with the above code. This uses Loading everywhere in service mode.

conclusion

By studying the Loading component, we can get to know many knowledge points. Including custom commands, the use of custom command modifiers, custom plug-ins, to vue. prototype mount object, vue. extend declaration Vue components, etc.

Yards cloud: gitee.com/DaBuChen/my…

Other component source code study:

Element component source research -Button

Element component source research -Input Input box

Element component source research -Layout, Link, Radio

Element component source research -Checkbox multi-checkbox

Element component source research -InputNumber counter

Element component source code study -Loading component

Element component source research -Message component