About my realization of the vue functional pop-up window overflowing the project

vue functional pop-up window

I have read a lot of articles before, and I always wanted to make my own, mainly based on secondary packaging and Vue.extend. I will share the pitfalls I stepped on and how to deal with them.

The main functions are as follows:

  1. support title
  2. Load child component rendering
  3. Provides a communication mechanism callback
  4. Promise

Journey

Me: Today I want to make a showDialog function popup window

Crazy research (all kinds of Baidu), 1 hour later… I rely on, it seems that there is nothing I want, look through the api Vue.extend to create a subclass, okay, I will use you

One operation, display and close showDialog has been implemented… But what about loading subcomponents? Do I pass a path and mount it using import(path) with dynamic components?

showDialog({<!-- -->
    title:'Title'
    path: 'demo'
})

If you have a thought, you will report an error. Import does not support dynamic variables. The path is undefined. Oh, and require() can be used. Hey, now you can dynamically load subcomponents. Let’s test it and submit it. commit -m ‘feat complete functional popup’

Day 2

Supervisor: Why can’t my uni project run anymore?

Me: I started it with a knowing smile (obviously I don’t know that I caused the problem!) What happened to the node stack overflow, it was fine before I submitted the functional pop-up window, but it didn’t work. Damn, delete my code, it’s ok started

Inside of me: what rubbish performance

Me: Tell everyone, it seems to be a problem with the pop-up window, I have registered him from the global, you update the code

evening

My heart: Why did I report an error, so I started to review, and I remembered that there was an article before. The difference between require() and import() is roughly synchronous and asynchronous loading, import() only loads relevant content when calling and is lazy. In router, we use lazy loading of routes because of import(). require() is different. It will load the content synchronously from the beginning. uni can’t be started. I will load the components synchronously, and the related dependencies will be parsed, resulting in an overflow problem. This is also a problem. The reason why I didn’t plan to use require() at the beginning, of course, require() is still very commonly used when loading some pictures, this is because of its synchronous loading feature To, and then analyze uni compiled error webpack related, I tried to configure require() on-demand reference configuration but I did not seem to be successful, So let me explain why using import(path) fails, because a variable webpack4 set by path belongs to static path will cause the parsing to fail. To sum up the above problems, you can come up with a solution. I don’t use path. I pass a uiLoader function, which is ()=>import('demo') It’s like lazy loading of routes, but after debugging, this is indeed feasible

After a lot of tossing, I will show you how to realize it, based on the secondary packaging of uview u-modal

Implementation

There must still be a vue file

xxx-modal.vue

<template>
<view>
<u-modal
        :show-title="false"
        @confirm="confirm"
        :title="title"
        v-model="model.visible"
        :show-cancel-button="true"
        :show-confirm-button="true"
>
<component:is="component" v-if="component"></component>
</u-modal>
</view>
</template>

<script>
export default {<!-- -->
name: 'Tsl-Dialog',
props: {<!-- -->
uiLoader: {<!-- -->
type: Function,
},
title: {<!-- -->
type: String,
},
onClose: {<!-- -->
type: Function,
},
onSuccess: {<!-- -->
type: Function,
},
},
data() {<!-- -->
return {<!-- -->
component: null,
model: {<!-- -->
visible: false,
},
emitter: null,
};
},
methods: {<!-- -->
async on() {<!-- -->
this.model.visible = true;

this.uiLoader().then(() => {<!-- -->
this.component = this.uiLoader;
});
},
confirm() {<!-- -->
\t\t\t\t// Data collection
this.onSuccess(this.emitter);
},
cancel() {<!-- -->
this. onClose();
},
},
created() {<!-- -->},
mounted() {<!-- -->
// cannot use import() uni compilation should be using webpack4 does not support variable input
uni.$on('POST_ACTION', (v) => {<!-- -->
this. emitter = v;
});
},
beforeDestroy() {<!-- -->
uni.$off('POST_ACTION');
},
};
</script>

<style lang="scss" scoped></style>

Description:

When it is on, mount the component on the communication by executing uiLoadeer or use bus because it needs to be Promise, so my internal components receive POST_ACTION stores the information and executes the callback

showDialog.js

// Because it is the final version, some parameters can be ignored
import Modal from './modal.vue';
import Vue from 'vue';

const Instance = Vue. extend(TslModal);

function showDialog(props) {<!-- -->
const {<!-- --> title, uiLoader, content, showButton = false, borderRadius = 30, confirmColor = '#2979ff', cancelColor = '#606266' } = props;

return new Promise((resolve, reject) => {<!-- -->
const dialogContext = new Instance();

// Mount the loader
dialogContext.uiLoader = uiLoader;
// mount props
dialogContext.title = title;
dialogContext. content = content;
dialogContext. borderRadius = borderRadius;
dialogContext.confirmColor = confirmColor;
dialogContext. cancelColor = cancelColor;
if (showButton) {<!-- -->
dialogContext.showConfirmButton = true;
dialogContext.showCancelButton = true;
}
// open the popup
dialogContext.on();
// success button callback
dialogContext.onSuccess = function (v) {<!-- -->
props.onSuccess & amp; & amp; props.onSuccess(v);
resolve(v);
remove();
};
// mount dom
document.body.appendChild(dialogContext.$mount().$el);
// cancel event
dialogContext.cancel = function () {<!-- -->
dialogContext. close();
remove();
};
// remove mount dom
function remove() {<!-- -->
document.body.removeChild(dialogContext.$mount().$el);
}
});
}

export default showDialog;

Description:

Introduce the modal component through Vue.extend() and then construct an instance. If you are not too familiar with the internal source code, you can add it one by one, using Promise There is a confirmation and cancel button at the bottom of the package pop-up window. When you click Confirm, execute resolve(v) and send the corresponding data. Remember to remove the dom< when closing /strong> The order is from top to bottom. We manually call on and open the pop-up window and load the component at the same time. Because we mounted uiLoader at the top at the beginning, soon already exists when it is executed. Finally, export can be used to import or mount the prototype

How to use

import showDialog from '@/components/modal/showDialog';

showDialog({<!-- -->
    title: 'I am a pop-up window',
    showButton: true,
    borderRadius: 0,
    content: '123',
    uiLoader: () => import('./demo.vue'), uni.$emit('POST_ACTION', 'value'); in demo
    onSuccess: (res) => {<!-- -->
    console.log('postaction1', res); // value
},
}).then((res) => {<!-- -->
    console.log('postaction', res); // value
});

content is still supported and uiLoader priority, I made a judgment internally

Conclusion:

As a bug repair engineer, I realized that my knowledge is still not enough in this implementation. Through this problem, I slowly analyzed and finally dealt with it. In fact, the process is still a bit difficult. Isn’t it the employment winter recently? I hope you can still put your mind at ease and always keep yourself at the edge. I’m pretty good at it, and I can only learn a little bit every day. If I can surpass 50% of my peers, I will be satisfied. Knowledge reserves are still very important, so I should probably prepare more A few k more than the current salary, so that you will be competitive. Finally, I would like to send you a sentence: There is always a chance or two in the world, fill my thousand and eight thousand dreams

syntaxbug.com © 2021 All Rights Reserved.