跳至主要內容

自定义全局插件

大约 2 分钟

自定义全局插件

学习 Vue3 第三十章(编写 Vue3 插件) _小满 zs 的博客-CSDN 博客_vue3 插件写法open in new window

插件 | Vue.js (vuejs.org)open in new window

插件 | Vue.js (vuejs.org)open in new window

Plugins | Vue.js (vuejs.org)open in new window

插件是一种呢能够为 Vue 添加全局功能的工具代码

  • 会用插件

    import { createApp } from "vue";
    
    const app = createApp({});
    
    app.use(myPlugin, {
      /* 可选的选项 */
    });
    

插件是一个拥有 install() 方法的对象, 或者简单的就只是一个函数, 它自己就是安装函数

, 接收应用实例和传递给 app.use() 的额外选项

const myPlugin = {
  install(app, options) {
    // 配置此应用
  },
};

示例: 写一个 loading 插件:

AnotherLoading.vue:

<script setup lang="ts">
import { ref } from "vue";

let isShow = ref<boolean>(false);

const show = () => {
  isShow.value = true;
};

const hide = () => {
  isShow.value = false;
};

defineExpose({
  show,
  hide,
  isShow,
});
</script>

<template>
  <div v-if="isShow" class="loading">
    <div class="loading-content">loading...</div>
  </div>
</template>

<style lang="less" scoped>
.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>

AnotherLoading.ts

import { App, createVNode, VNode, render } from "vue";
import AnotherLoading from "./AnotherLoading.vue";

export default {
  install(app: App) {
    const vnode: VNode = createVNode(AnotherLoading);
    render(vnode, document.body);
    console.log(AnotherLoading);
    console.log(vnode.component?.exposed);
    app.config.globalProperties.$AnotherLoading = {
      show: vnode.component?.exposed?.show,
      hide: vnode.component?.exposed?.hide,
    };
    // app.config.globalProperties.$AnotherLoading.show()
  },
};

main.ts

import { createApp } from "vue";
import App from "./App.vue";
import "./assets/css/reset.less";
import Card from "./components/Card.vue";
import AnotherLoading from "./components/AnotherLoading/AnotherLoading";

// export const app = createApp(App)
const app = createApp(App);

// 定义 Filter 类型, 作为 $filters 的返回类型
type Filter = {
  format: <T>(str: T) => string;
};

// Loading 插件类型定义
type ALP = {
  show: () => void;
  hide: () => void;
};

// 添加声明
declare module "@vue/runtime-core" {
  export interface ComponentCustomProperties {
    $filters: Filter;
    $env: string;
    // Loading 插件
    $AnotherLoading: ALP;
  }
}

// 注册全局过滤器
app.config.globalProperties.$filters = {
  format<T>(str: T): string {
    return `233${str}`;
  },
};

app.config.globalProperties.$env = "dev";

// 注册 Loading 插件
app.use(AnotherLoading);

// 注册全局组件以及别名
app.component("Card", Card).mount("#app");

AnotherLoadingTest.vue

<script setup lang="ts">
import { ComponentInternalInstance, getCurrentInstance } from "vue";

const { appContext } = getCurrentInstance() as ComponentInternalInstance;

const showLoading = () => {
  console.log(appContext);
  appContext.config.globalProperties.$AnotherLoading.show();
  setTimeout(() => {
    appContext.config.globalProperties.$AnotherLoading.hide();
  }, 2000);
};
</script>

<template>
  <div>
    <button @click="showLoading">切换</button>
  </div>
</template>

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