Vue3之自定义插件

932 阅读1分钟

插件

  • 插件是自包含的代码,通常向 Vue 添加全局级功能。你如果是一个对象需要有install 方法 Vue 会帮你自动注入到install 方法 你如果是 function 就直接当 install 方法去使用

使用插件

  • 在使用 createApp() 初始化 Vue 应用程序后,你可以通过调用 use() 方法将插件添加到你的应用程序中。

  • 实现一个Loading

// Loading/index.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>

重点,向外暴露方法 defineExpose({})

defineExpose({ isShow, show, hide })

然后可以在Loading.ts中去查找到暴露的方法

// Vue 提供的全局配置 可以自定义
app.config.globalProperties.$loading = {
  show: () => vnode.component?.exposed?.show(),
  hide: () => vnode.component?.exposed?.hide()
}
// Loading.ts
import { createVNode, VNode, render, App } from "vue";
import Loading from './index.vue';
export default {
  install(app: App) {
    // createVNode vue提供的底层方法 可以给我们组件创造一个vdom 也就是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()
    }
  }
}

在main.ts里注册

// main.ts
// 组件所在位置 .ts文件
import Loading from './components/pluginComponent/Loading/Loading'

// 扩展声明 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
declare module 'vue' {
  export interface ComponentCustomProperties {
    $loading: {
      show: () => void,
      hide: () => void
    }
  }
}
app.use(Loading)

在页面中使用

<button @click="handleChange">切换</button>
<script setup lang="ts">
  import { getCurrentInstance, ComponentInternalInstance } from 'vue';
  
// 全局插件的使用
const {appContext} = getCurrentInstance() as ComponentInternalInstance

const handleChange = () => {
  appContext.config.globalProperties.$loading.show()
  // 3后关闭
  setTimeout(() => {
    appContext.config.globalProperties.$loading.hide()
  }, 3000);
}
</script>

效果

image.png

image.png