Vue 自定义插件

157 阅读1分钟

一、参考

学习Vue3 第三十章(编写Vue3插件)_@vue/runtime-core-CSDN博客

Vue 定义全局变量和函数 - 掘金 (juejin.cn)

二、创建流程

假设现在需要创建一个加载插件,在用户登录页面时,会加载3秒

2.1 创建插件页面

创建 loading.vue 页面:

<template>
    <div v-if="isShow" class="loading">
        <div class="loading-content">Loading...</div>
    </div>
</template>
    
<script setup lang='ts'>
import { ref } from 'vue';
const isShow = ref(false)//定位loading 的开关
 
const show = () => {
    isShow.value = true
}
const hide = () => {
    isShow.value = false
}
//对外暴露 当前组件的属性和方法
defineExpose({
    isShow,
    show,
    hide
})
</script>
 
 
    
<style scoped lang="less">
.loading {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.8);
    display: flex;
    justify-content: center;
    align-items: center;
    &-content {
        font-size: 30px;
        color: #fff;
    }
}
</style>

2.2 插件导出

创建 loading.ts :

import { createVNode, render, VNode, App } from 'vue';
import Loading from './loading.vue'
 
export default {
    install(app: App) {
        //createVNode vue提供的底层方法 可以给我们组件创建一个虚拟DOM 也就是Vnode
        const vnode: VNode = createVNode(Loading)
        //render 把我们的Vnode 生成真实DOM 并且挂载到指定节点
        render(vnode, document.body)
        // Vue 提供的全局配置 可以自定义
        app.config.globalProperties.$loading = {
            show: () => vnode.component?.exposed?.show(),
            hide: () => vnode.component?.exposed?.hide()
        }
 
    }
}

2.3 加载插件

main.ts 添加如下内容:

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import loading from './components/loading'

export const app =  createApp(App)
app.use(loading)

type Lod = {
    show: () => void,
    hide: () => void
}
//编写ts loading 声明文件放置报错 和 智能提示
declare module '@vue/runtime-core' {
    export interface ComponentCustomProperties {
        $loading: Lod
    }
}

app.mount('#app')

2.4 插件使用

<template>
 
    <div></div>
   
  </template>
   
  <script setup lang='ts'>
  import { getCurrentInstance} from 'vue'

  const  instance = getCurrentInstance()  
  instance?.proxy?.$loading.show()
  setTimeout(()=>{
    instance?.proxy?.$loading.hide()
  },5000)
   
   
  // console.log(instance)
  </script>
  <style>
  *{
    padding: 0;
    margin: 0;
  }
  </style>

2.5 页面效果

20231122_200151.gif