Purpose, in fact, in order to use the js way to call popover
The purpose of a plug-in is to invoke the pop-up component in js fashion. Custom content. Don’t worry about the code in popover use. No need to write popover HTML code. This is a simple popover call, custom slot contents, configurable parameters, and event callbacks.
methods:{
openDialog(){
this.$Modal({
// The popover contains nested components
component: xxx,
// Nested components pass properties
componentProps: {},// Popover property Settings
props: {},// Event callback
methods: {}}); }}Copy the code
Writing in the front
The application Element – UI is mostly used in real development scenarios. So the plug-in takes el-Dialog as an example. In theory, it can be extended to any UI component library related popover business, here we can draw inferinferies.
This article is for technology sharing, achievement sharing, if there is a need to forward use, please bring the original link. Thank you ~ if there is a better way to welcome communication ~ finally, is to write the original intention of the document is actually very simple, is for your thumbs up
Start your little hands
Daily development status.
- Redundant code
Multiple popovers need to be defined and multiple properties need to be defined. And set these properties to true or false during business use.
- Poor reusability
Pages have a lot more non-business logic control code (less readable). For example, the control code will be written to the parent page of the first shell when the second shell is opened inside the first shell.
- Poor maintainability
Irrelevant code interspersed in the business process, poor decoupling. Maintenance is also relatively demanding. You need to look up the properties that control whether the popover displays or not. Centuries have passed
Component development or as far as possible decoupling. Let the use of arbitrary. Business code is more independent. Component reusability is all improved.
In everyday coding
When the business needs more than one popover when the basic is as follows, barabara coding… Of course, there may be other encapsulation methods used. But simply write properties that control whether the popovers are visible or not and how parameters are passed to child components. The second is that the child component business process is completed to call back, etc. These seemingly tedious but seemingly necessary things. Writing like this is a little bit not pretty (actually lazy, don’t want to write so much code. Simple is good, minimalism is better)
<template>
/ /... For example - balla balla some popover code.........
<el-dialog
title="Basic Vehicle Information"
width="50%"
append-to-body
destroy-on-close
:visible="carInfoVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="closeCarInfo"
>
<info
v-if="carInfoVisible"
:info-id="infoId"
:car-info-visible="carInfoVisible"
@close="closeCarInfo"
/>
</el-dialog>
<el-dialog
title="Vehicle Operation Information"
width="50%"
append-to-body
destroy-on-close
:visible="carInfoWorkVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="closeCarWork"
>
<work
v-if="carInfoWorkVisible"
:info-id="infoId"
:car-info-visible="carInfoWorkVisible"
@close="closeCarWork"
/>
</el-dialog>
/ /... If there is any other business you need to repeat ++.........
</template>
export default {
data(){
return {
closeCarInfo:false.carInfoWorkVisible:false. A little... }},methods: {... A little bit of popover component event callback...closeCarWork(){}}}Copy the code
Lazy cancer sets in and starts thinking
Can these cookie-cutter things be optimized? If you use popovers of JS calls, you should save some code. Then it would be nice if the contents of the popover could be passed by themselves.
- You don’t just want to control whether pop-ups are displayed or not and pass parameters. Make variables in data really big.
- The content component of each popover page is arbitrary and easy to use. Parameter passing and event callbacks are simple and self-definable.
Inspired, other component library JS calls look like this
methods:{
openDialog(){
this.$Modal({
title: 'Js'.content: 'This is a popup with a Js call'}); }}Copy the code
And this is what I expected.
- Popover properties can be set
- Make it easy to customize popover nested components
- You can set the transfer properties of custom popover nested components
- You can set event callbacks for custom popover nested components
methods:{
openDialog(){
this.$Modal({
// The popover contains nested components
component: xxx,
// Nested components pass properties
componentProps: {},// Popover property Settings
props: {},// Event callback
methods: {}}); }}Copy the code
Implementation approach
We instantiate an El-Dialog component and set the default slots of El-Dialog each time we use the call. Consider peer use and nested use. So when you instantiate a component, you createElement a div. Elements mounted as components. And put the element in the body. So the code should look something like this.
import Vue from 'vue'
let instance
const Modal = function ({ component, methods, props, componentProps }) {
const dom = document.createElement('div')
document.body.appendChild(dom)
instance = new Vue({
el: dom,
})
}
export default Modal
Copy the code
So how to render the popover and define the popover nested components?
Scheme 1 Template template rendering method (GG)
That’s the way it started. Balabalcoding… The following
import Vue from 'vue'
import { Dialog } from 'element-ui'
let instance
const template =
'
+
'<Plugin v-on:close="close" :componentProps="componentProps"> </Plugin>' +
'</Dialog>'
const Modal = function ({ component, methods, props, componentProps }) {
const dom = document.createElement('div')
document.body.appendChild(dom)
instance = new Vue({
el: dom,
template,
components: {
Dialog: Dialog,
Plugin: component
},
data() {
return {
title:'Popover description Title'.showModal:true. It's not flexible if there are more parameters... }},methods: {
close(){
this.showModal = false}}})return instance
}
export default Modal
Copy the code
After some debugging, I found that the scheme was not very good. Compile warnings and handle warnings in real time. If you have multi-parameter passing, the follow-up is also a disaster. So this is where I end up. If there are students who can complete the verification, please leave a message to inform us.
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
Copy the code
Scheme 2 render function render way
Render due to its own use of relatively less. It is simple to use, just render as a single label. Plus the way of writing a little uncomfortable, has been ignored when the general. Component rendering wasn’t even considered. The first argument to createElement supports the component option object !!!! . That means you can render components. biubiu coding… Wait a minute, in that way how do you determine the content component of the popover? We all know that the contents of an El-Dialog are inserted through slot slots. Can Render set up slots? The answer is yes. By setting scopedSlots.
Click to learn more about the Render function.
// @returns {VNode}
createElement(
// {String | Object | Function}
// An HTML tag name, component option object, or
Resolve an async function of any of the above. Required fields.
'div'.// {Object}
// A data object corresponding to the attribute in the template. Optional.
{
// (see next section for details)
},
// {String | Array}
// Child virtual nodes (VNodes), built from 'createElement()',
// You can also use strings to generate "text virtual nodes". Optional.
[
'Write some words first.',
createElement('h1'.'A headline'),
createElement(MyComponent, {
props: {
someProp: 'foobar'}})])// Drill down into the data object
{
// The format of the scope slot is
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props= > createElement('span', props.text)
},
// If the component is a child of another component, specify a name for the slot
slot: 'name-of-slot',}Copy the code
After reviewing the render documentation. The final essence is to render– to make the template write.
import Vue from 'vue'
import { Dialog } from 'element-ui'
let instance
const Modal = function ({ component, methods, props, componentProps }) {
const dom = document.createElement('div')
document.body.appendChild(dom)
instance = new vue({
el: dom,
data () {
return {
showModal: true}},components: {
Dialog: Dialog,
Plugin: component
},
render (createElement) {
return createElement(
'Dialog', {
scopedSlots: {
default: () = > createElement('Plugin')}})},})return instance
}
export default Modal
Copy the code
Finally adjust the passprops
Bound to the callbackmethods
. Components inside the popover. It doesn’t have to be pure all the time. Look at the popovervisible:true
Rendering is available.render
Can render according to the data responsively. Set up thescopedSlots
Render at display time.
import Vue from 'vue'
import { Dialog } from 'element-ui'
let instance
const Modal = function ({ component, methods, props, componentProps }) {
if (Vue.prototype.$isServer) return
const dom = document.createElement('div')
document.body.appendChild(dom)
instance = new Vue({
el: dom,
data () {
return {
showModal: true}},components: {
Dialog: Dialog,
Plugin: component
},
render (createElement) {
const plugin = this.showModal ? () = > createElement('Plugin', {
props: {
...componentProps
},
on: {
close: (e) = > this.close(e), ... methods } }) :null
return createElement(
'Dialog', {
props: {
visible: this.showModal, ... props },on: {
close: (e) = > this.close(e)
},
scopedSlots: {
default: plugin
}
})
},
methods: {
close () {
this.showModal = false
document.body.removeChild(this.$el)
this.$destroy()
}
}
})
return instance
}
export default Modal
Copy the code
The plug-in USES
It can be imported from main.js and loaded into the Prototype prototype.
// main.js
import modal from '@/plugins/modal'
Vue.prototype.$modal = modal
// Use pop-ups in js mode, configuration mode to complete parameter passing, event callback
this.$modal({
// Popover nested components pass properties
componentProps: {
id: '7676043D-F0DA-80DA-1CBD-BDD7068B3A77'
},
// The popover contains nested components
// component: Table, // synchronize
component: (resolve) = > require(['./cube-table-list.vue'], resolve), / / asynchronous
// Popover property Settings
props: {
title: 'Basic Info popup'
// width: '520px',
// fullscreen: false
},
// Event callback
methods: {
refresh: (e) = > {
console.log(e, '--x-x-x-')}}})Copy the code
Popovers are called as js.
Invoke the component as js. Determines popover content by configuration. You can omit some of these non-business and non-business attributes and methods. It doesn’t matter to our code whether popovers close or not. Call render when needed, destroy when closed. Support infinite pole nesting, multiple peer use. Let development focus more on business development.
// This is the code
<template>
/ /... For example - balla balla some popover code.........
<el-dialog
title="Basic Vehicle Information"
width="50%"
append-to-body
destroy-on-close
:visible="carInfoVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="closeCarInfo"
>
<info
v-if="carInfoVisible"
:info-id="infoId"
:car-info-visible="carInfoVisible"
@close="closeCarInfo"
/>
</el-dialog>
/ /... N++ popup window...
</template>
Copy the code
Use correspondence mapping.
In the final
This code plug-in is my original design, because before this also tried to find a similar solution. I haven’t found the right one. And then you have this article that you see. Of course, if there are similarities, right when I did not see ~.
This article is for technology sharing, achievement sharing, if there is a need to forward use, please bring the original link. Thank you ~ if there is a better way to welcome communication ~ finally, is to write the original intention of the document is actually very simple, is for your thumbs up
Start your little hands