22 vue3之全局函数和变量&插件编写

globalProperties

由于Vue3 没有Prototype 属性 使用 app.config.globalProperties 代替 然后去定义变量和函数

Vue2与 Vue 3的区别

// 之前 (Vue 2.x)

Vue.prototype.$http = () => {}
const app = createApp({})

app.config.globalProperties.$http = () => {}

main.ts定义全局变量

复制代码
app.config.globalProperties.$env = "env";

main.ts定义全局过滤器函数

在Vue3 移除了filter函数 我们可以使用全局函数代替

复制代码
// 全局函数使用案例
type Filter = {
  format: <T extends any>(str: T) => T;
};
// 声明要扩充@vue/runtime-core包的声明.
// 这里扩充"ComponentCustomProperties"接口, 因为他是vue3中实例的属性的类型.
declare module "@vue/runtime-core" {
  export interface ComponentCustomProperties {
    $filters: Filter;
  }
}
app.config.globalProperties.$filters = {
  format<T extends any>(str: T): string {
    return `coookie-${str}`;
  },
};

组件中使用

二种不同的方式获取值,推荐使用第二种

复制代码
<template>
  <div class="">{{ $env }}</div>
  <div class="">{{ $filters.format("nihao") }}</div>
</template>

<script setup lang="ts">
import { log } from "console";
import {
  getCurrentInstance,
  ComponentInternalInstance,
} from "vue";
// 第一种方式
const { appContext } = <ComponentInternalInstance>(
  getCurrentInstance()
);
console.log(appContext.config.globalProperties.$env);
// 第二种方式
const app = getCurrentInstance();
console.log(app?.proxy?.$filters.format("js"));
</script>

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

编写全局插件

插件知识

插件有二种形式 一是导出对象形式 二是函数

导出对象形式必须包含install方法

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

loading.vue

需defineExpose对外暴露 当前组件的属性和方法

javascript 复制代码
<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对外暴露 当前组件的属性和方法
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>

index.ts

createVNode vue提供的底层方法 可以给我们组件创建一个虚拟DOM 也就是Vnode

render 把我们的Vnode 生成真实DOM 并且挂载到指定节点 这里是挂载到body上

javascript 复制代码
import { App, VNode, createVNode, render } from "vue";
import Loading from "./loading.vue";

// 插件有二种形式 一是导出对象形式  二是函数
// 导出对象形式必须包含install方法
export default {
  // Vue.use(Loading) 会自动调用install方法
  install(app: App) {
    //app 是全局的
    console.log("loading插件被注册了", Loading); // 现在获取到的Loading无法正常使用 需要createVNode通过转成Vnode,再用render函数挂载到全局
    let vnode: VNode = createVNode(Loading); //createVNode vue提供的底层方法 可以给我们组件创建一个虚拟DOM 也就是Vnode
    console.log(vnode); // 此时就是个vnode 但是component上是没有值的,故需要用render函数挂载
    render(vnode, document.body); // //render 把我们的Vnode 生成真实DOM 并且挂载到指定节点 这里是挂载到body上
    /*   let el: any = document.querySelector("#app");
    render(vnode, el);
    console.log("el", el); */ // 此时setupState中就有我们index.vue组件挂载的值

    // console.log(vnode.component?.setupState); //  不建议使用这种方式
    // vnode.component?.setupState?.show();

    // console.log(vnode.component?.exposed);  //建议使用这种方式,但index.vue需要抛出对应的defineExpose
    // Vue 提供的全局配置 可以自定义
    app.config.globalProperties.$loading = {
      // 需要注册为全局其他组件才能使用
      show: () => vnode.component?.exposed?.show(),
      hide: () => vnode.component?.exposed?.hide(),
    };
    // app.config.globalProperties.$loading.show(); //测试loading
  },
};

main.ts

javascript 复制代码
import Loading from "./index.ts"; //引入插件

app.use(Loading); // 加载插件
type Lod = {
  show: () => void;
  hide: () => void;
};
//编写ts loading 声明文件放置报错 和 智能提示
declare module "@vue/runtime-core" {
  export interface ComponentCustomProperties {
    $loading: Lod;
  }
}
declare module "vue" {
  export interface ComponentCustomProperties {
    $loading: Lod;
  }
}

使用插件

javascript 复制代码
<template>
  <div></div>
</template>

<script setup lang="ts">
import { ref, reactive, 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>
相关推荐
装疯迷窍_A2 小时前
以举证方位线生成工具为例,分享如何在Arcgis中创建Python工具箱(含源码)
开发语言·python·arcgis·变更调查·举证照片
Leisureconfused6 小时前
【记录】Node版本兼容性问题及解决
前端·vue.js·npm·node.js
Trustport7 小时前
ArcGIS Maps SDK For Kotlin 加载Layout中的MapView出错
android·开发语言·arcgis·kotlin
GIS地信小匠1 天前
(30)ArcGIS Pro 查找相同项+删除相同项:矢量数据去重实操
arcgis·空间分析·数据处理·gis教程·arcgls pro
jonyleek1 天前
【JVS更新日志】物联网、动态首页插件、在线白板插件4.15更新说明!
物联网·插件·物联网平台·jvs·更新日志·动态首页·白板插件
We་ct1 天前
前端包管理工具与Monorepo全面解析
前端·javascript·npm·pnpm·yarn·monorepo·包管理
李昊哲小课1 天前
安装 npm/pnpm/yarn 换国内镜像 统一目录管理全局包+缓存
前端·缓存·npm·pnpm·yarn
城数派1 天前
2025年我国乡镇的平均高程数据(Excel\Shp格式)
数据库·arcgis·信息可视化·数据分析·excel
虹科网络安全1 天前
艾体宝洞察|NPM供应链攻击:复杂的多链加密货币攻擊渗透流行软件包
前端·npm·node.js
AIFarmer2 天前
npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确, 然后再试一次。
前端·npm·node.js