Write a vue3 global API component by hand

factsdefeatwords 2021-09-15 10:51:47

Vue3 It has been officially released for some time , About Vue3 There are also a lot of articles , combined API、Typescript、 The source code is introduced in great detail , But about the global api There seems to be little introduction to this component , So let's share Vue3 How to develop and use a global api Components

Let's go over it first vue2 How to implement in

With a alert Component as an example

<template>
<transition name="alert-fade" @after-leave="destroyElement">
<div class="alert" v-if="show">
<div class="ht-modal" @click="close"></div>
<div class="alert-box" :style="'width:'+ width">
<div class="alert-header">
<i class="iconfont icon-error alert-close" @click="close"></i>
</div>
<div class="alert-body">
{{ message }}
</div>
<div class="alert-footer">
<slot name="footer">
<div class="alert-btn" @click="close"> determine </div>
</slot>
</div>
</div>
</div>
</transition>
</template>
<script>
export default {
name: 'Alert',
props: {
width: {
type: String,
required: false,
default: '30%',
},
msg: {
type: String,
required: false,
default: () => 'some message'
},
handleClose: {
type: Function,
required: false,
default: null
}
},
data () {
return {
show: true,
message: this.msg
}
},
methods: {
close($event) {
this.show = false
this.$emit('close', $event)
},
destroyElement() {
this.handleClose && this.handleClose()
}
},
}
</script>
 Copy code 

The file is named alert.vue, Create... In the same directory alert.js file

import Main from './alert.vue'
const Alert = {}
Alert.install = Vue => {
let instance
let show = false
let AlertConstructor = Vue.extend(Main)
const loadAlert = options => {
if ( show ) return
let { handleClose } = options
options.handleClose = () => {
handleClose && handleClose()
show = false
}
instance = new AlertConstructor({
propsData: options
})
const component = instance.$mount()
document.body.appendChild(component.$el)
}
Vue.prototype.$alert = loadAlert
}
export default Alert
 Copy code 

The key here is to call Vue Upper extend Method to inherit alert Component properties , Of course, you can also directly create a new Vue Example to achieve the same effect , because Vue2 Is through instantiation Vue Constructor to create an example , So the api Method is bound to the prototype object of the constructor to implement inheritance

import Alert from 'alert.js'
import Vue from 'vue'
Vue.use(Alert)
new Vue(...).$mount(el)
 Copy code 

After registration , We can pass anywhere this To call this method to render the component

 this.$alert({
width: '50%',
msg: ' This is an overall situation api Components ',
handleClose: function() {
console.log(' I was shut down !!!')
}
})
 Copy code 

That's right Vue2 How to develop and use a api A brief review of the components , that Vue3 What is the difference between the implementation in , Let's move on

Vue3 Pass through createApp Method returns an instance object , And cancelled extend Method , We mentioned above that we can create a new instance object to implement , So let's draw a gourd and draw a gourd to realize

import { createApp } from 'vue'
import Main from './alert.vue'
const Alert = {}
Alert.install = app => {
let instance
let container = null
const loadAlert = options => {
if (container) return
let { handleClose } = options
options.handleClose = () => {
handleClose && handleClose()
document.body.removeChild(container)
instance.unmount()
container = null
}
container = document.createElement('div')
instance = createApp(Main, options)
instance.mount(container)
document.body.appendChild(container)
}
app.config.globalProperties.$alert = loadAlert
}
export default Alert
 Copy code 

Follow 2 There are several differences in the implementation of , First, instantiate the operation through createApp To achieve , Secondly, there are no more $mount Method , This lets us mount dom The operation of becomes more complicated , But the general idea is the same , Finally, the method is added in a different way ,2 Is added directly to the prototype object ,3 Is added to the instance application config On the global properties of the object , The following registration and use methods are exactly the same

Let's go further ,Vue3 One of the most important features is combinatorial api, It allows us to write code very flexibly , So we actually use vue The ultimate reason for a component is to use its responsive rendering dom The ability to perform rendering operations portable and efficiently , So related api There are mainly createVnode、h as well as render, We can also use these api To achieve the same effect

import { h, createVNode, render } from 'vue'
 Copy code 

h And createVnode Methods return a vnode object , They have the same effect , You can mix it up

const vnode = h(Main, options)
const vnode = createApp(Main, options)
 Copy code 

Finally, we need to call render Methods the incoming vnode And the parent element to mount

render(vnode, container)
 Copy code 

Finally, our code can be changed to

import { h, createVNode, render } from 'vue'
import Main from './alert.vue'
const Alert = {}
Alert.install = app => {
let container = null
const loadAlert = options => {
if (container) return
let { handleClose } = options
options.handleClose = () => {
handleClose && handleClose()
document.body.removeChild(container)
container = null
}
container = document.createElement('div')
const vnode = h(Main, options)
//const vnode = createVNode(Main, options) // You can also use createVnode Methods to replace h
render(vnode,container)
document.body.appendChild(container)
}
app.config.globalProperties.$alert = loadAlert
}
export default Alert
 Copy code 

It's not hard to see , We just put createApp The behavior becomes to create vnode, And then call render Method mount to container On , that createApp The same operation is performed internally , We just extract the methods we need to execute , This is also a combination api One of the advantages of , I'll introduce correspondence whenever I need it api, Avoid code redundancy

Finally, let's analyze 2 and 3 The global call mode of ,2 Through prototype chain inheritance , By means of Vue Exposed on the prototype object of the constructor api Method , On the application singleton , For global call ;3 It is through Proxy Override the read behavior by proxy ,this.$alert What is actually accessed is app.config.globalProperties.$alert Method

Please bring the original link to reprint ,thank
Similar articles

2021-09-15

2021-09-15