VUE3项目里的全局方法和全局过滤器封装

1,890 阅读2分钟

搭建一个vue3项目是很快的,但是之前很多写法都不能用了,这里就记录汇总一下项目里的差别,然后记录下全局方法和过滤器的封装。

创建实例

    //main.js
    import { createApp } from 'vue'
    import router from './router'
    import ElementPlus from 'element-plus'
    // pinia
    import { createPinia } from 'pinia'
    import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
    const pinia = createPinia()
    pinia.use(piniaPluginPersistedstate)
    
    const app = createApp(App)
    app.use(pinia).use(router).use(ElementPlus)
    window.vm = app.mount('#app')

创建vue实例的方式变成了createApp,然后use组件的方式添加,最后app.mount挂到根节点#app上。

全局挂载Axios

之前vue2想全局挂载一个方法非常简单,用prototype就可以了。

    import axios from 'axios'
    Vue.prototype.$axios = axios

但是现在vue3无法使用vue.prototype的方式,官方提供了一种新的方法。

    //main.js
    app.config.globalProperties.$axios = axios // 使用globalProperties挂载
    //page.vue
    import { getCurrentInstance } from 'vue'
    //以下两种方法都是通过getCurrentInstance来获取上下文
    //方法1:
    //通过`getCurrentInstance`方法获取当前实例,再根据当前实例找到全局实例对象`appContext`,进而拿到全局实例的`config.globalProperties`
    const currentInstance = getCurrentInstance()
    const { $axios } = currentInstance.appContext.config.globalProperties
    $axios.get('/api/url').then(res => {
        console.log(res)
    })
    //方法2:
    //通过`getCurrentInstance`方法获取上下文,这里的`proxy`就相当于`this`
    const { proxy } = getCurrentInstance()
    proxy.$axios.get('/api/url').then(res => {
        console.log(res)
    })
    

可以通过打印getCurrentInstance()看到其中有很多全局对象,如:$route$router$store。如果全局使用了ElementUI后,还可以拿到$message$dialog等等。

全局方法

上述方式添加全局方法较为繁琐,因为setup()中获取不到this,还需要通过getCurrentInstance来获取上下文,每次使用方法都比较繁琐,故通过mixin的方式添加全局的工具类。

    //common.js
    const Common = {
        glParseTime (time, cFormat) {
            //...
            return time_str
        },
    } 
    export default Common;
    //main.js
    import common from '@/components/util/common';
    app.mixin({
      methods: {
        ...common
      }
    })
    //page.vue
    <span>{{glParseTime(new Date())}}</span>

在组件内就可以直接调用方法,不需要多写一行代码,非常方便,但是这样可维护性就会变差一些,所以全局方法的命名我都在前面添加gl开头,避免调用的方法寻不到来源,若通用方法多了,可以以模块为命名前缀,方便快速识别。

全局过滤器

vue3里面是取消了过滤器filter的,可以通过定义全局方法的方式,定义一个全局过滤器。

    //registerFilter.js
    import moment from 'moment';

    const filters = {
      //时间戳转换(毫秒)
      timeReturn(value) {
        return value ? moment(+value).format('YYYY-MM-DD') : '--';
      }
    }

export default filters;
    //main.js
    import filters from '@/components/core/registerFilter';
    
    // 全局过滤器
    app.config.globalProperties.$filters = filters
    //page.vue
    <template>
        <span>{{proxy.$filters.timeReturn(new Date())}}</span>
    </template>
    <script setup>
        import { getCurrentInstance } from 'vue'
        const { proxy } = getCurrentInstance()
    </script>