• vue3学习(十三)---全局定义事件及编写vue插件


    全局定义事件 globalProperties

    之前我们使用vue2的时候使用Vue.prototype会将loading、toast、axios等定义为全局属性方便后期使用。

    Vue3没有prototype属性,使用app.config.globalProperties来绑定属性和事件。

    const app = createApp({})
    app.config.globalProperties.$http = () => {}
    
    • 1
    • 2

    自定义全局过滤器

    声明文件要写,不然TS无法正确类型 推导

    app.config.globalProperties.$filters = {
      format<T extends any>(str: T): string {
        return `$${str}`
      }
    }
    
     声明文件 不然TS无法正确类型 推导
    
    type Filter = {
        format<T>(str: T): string
    }
     
    // 声明要扩充@vue/runtime-core | vue 包的声明.
    // 这里扩充"ComponentCustomProperties"接口, 因为他是vue3中实例的属性的类型.
    declare module 'vue' {
        export interface ComponentCustomProperties {
            $filters: Filter
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    template中可以直接读取

    <template>
    	<div>
    	{($filters.format("的飞机')}}
    	div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    js中需要getCurrentInstance获取当前实例,然后在实例中获取

    import { getCurrentInstance, ComponentInternalInstance } from 'vue';
     
    const { appContext } = <ComponentInternalInstance>getCurrentInstance()
     
    console.log(appContext.config.globalProperties.$filters);
     
    推荐第二种方式
     
    import {ref,reactive,getCurrentInstance} from 'vue'
    const app = getCurrentInstance()
    console.log(app?.proxy?.$filters.format('js'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    扩展:vueuse库


    编写Vue3插件

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

    你如果是function 就直接当install 方法去使用。

    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
    }
    setup形式默认不向外部暴露属性和方法,无法像vue2一样直接能获取到子组件的实例方法
    
    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    2. 编写核心loading.ts

    import {  createVNode, render, VNode, App } from 'vue';
    import Loading from './index.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()
            }
     
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    3.main.ts中注册、编写声明文件

    main.ts
    
    import Loading from './components/loading'
     
     
    let 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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    4.页面中使用

    <template>
     
      <div></div>
     
    </template>
     
    <script setup lang='ts'>
    import { ref,reactive,getCurrentInstance} from 'vue'
    const  instance = getCurrentInstance()  
    const loading = instance?.proxy?.$Loading;
    loading.show()
    setTimeout(()=>{
     loading.hide()
    },5000)
     
     
    // console.log(instance)
    </script>
    <style>
    *{
      padding: 0;
      margin: 0;
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    5.手写源码

    import type { App } from 'vue'
    import { app } from './main'
     
    interface Use {
        install: (app: App, ...options: any[]) => void
    }
     
    const installedList = new Set()
     
    export function MyUse<T extends Use>(plugin: T, ...options: any[]) {
        if(installedList.has(plugin)){
          return console.warn('重复添加插件',plugin)
        }else{
            plugin.install(app, ...options)
            installedList.add(plugin)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    获取文件md5值
    【项目实训】后端逻辑完善
    k8s篇二之、操作命令 与 yml配置文件编写
    C及C++标准与QT版本介绍
    使用jQuery获取不同元素的ID
    0时区格林威治时间转换手机当地时间-Android
    AP5186 三功能 LED 降压型恒流芯片 手电筒 LED芯片
    1995-2020年全国各省二氧化碳排放量面板数据
    JVM调优记录
    win11 无法登录微软账号
  • 原文地址:https://blog.csdn.net/weixin_43932245/article/details/134060730