• 松哥手把手教你在 Vue3 中自定义插件



    最近在录 TienChin 项目,项目涉及到了 Vue 中插件的定义,因此整了这么一篇文章,手把手教大家在 Vue3 中定义插件,这个技能掌握了,就可以看懂 TienChin 前端代码了。

    1. Vue 插件

    在 Vue 中,一些简单的功能,我们可以直接定义为全局方法,然后挂到 Vue 上就能使用了,例如在 vhr 中,我们将网络请求方法进行封装,然后挂到了 Vue.prototype 上就可以了,类似下面这样:

    import {postRequest} from "./utils/api";
    
    Vue.prototype.postRequest = postRequest;
    
    • 1
    • 2
    • 3

    然后在使用的地方,就可以通过 this.postRequest 去使用了。

    小伙伴们需要注意,这个在 Vue3 中有所变化,prototype 变为了 config.globalProperties,也就是在 Vue3 中再想要挂载全局方法,应该是 const app = createApp(App);app.config.globalProperties.useDict = useDict 这种形式了(具体我将在 TienChin 项目中和大家细聊)。

    这也算是一种插件定义方式,但是这种一般适用于一些工具方法,无法定义一些比较复杂的插件,复杂的插件还是得通过 Vue 中提供的插件定义方式来定义。

    2. 自定义插件

    2.1 基本用法

    首先我们新建一个目录 plugins 专门用来放我们的插件,然后在这个目录中新建一个 index.js 文件用来开发插件,内容如下:

    export default {
        install: (app, options) => {
            console.log("我的第一个插件")
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    install 中的方法将会被自动执行。

    接下来我们就可以在 main.js 中引入我们这个插件了:

    const app = createApp(App);
    
    import plugin from './plugins'
    
    app.use(plugin);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    app.use 就表示引入插件,引入插件之后,插件中的 install 方法就会被自动执行。

    app.use 方法接收两个参数,第一个参数就是我们导入的插件 js 对象,第二个参数是可选的,大家看到插件定义时候的 install 方法有两个参数,第一个参数是 Vue 实例,这是自动传入的,第二个参数 options 则是我们在 app.use 中,通过第二个参数传入进来的。当然上面这个例子中松哥没有传递第二个参数。

    好了,如此配置之后,接下来启动项目,控制台就可以看到有日志打出了。

    这样的插件未免过于简单,接下来我们就给这个插件加点料。

    2.2 加入组件

    首先我们定义一个新的组件,如下:

    <template>
        <div>
            <h1><a href="http://www.javaboy.org">javaboya>h1>
        div>
    template>
    
    <script>
        export default {
            name: "MyBanner"
        }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后我们现在就可以在插件中将这个组件注册为一个全局组件了,如下:

    import MyBanner from "@/plugins/components/MyBanner";
    
    export default {
        install: (app, options) => {
            console.log("我的第一个插件")
            app.component('my-banner', MyBanner);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    首先在插件中导入这个组件,然后通过 app 进行组件注册,注册完成后,我们就可以在项目任意位置使用 my-banner 组件了,如下:

    <template>
        <div>
            <my-banner>my-banner>
        div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    最终显示效果如下:

    2.3 加入指令

    我们甚至还可以在插件中注册一个指令,如下:

    import MyBanner from "@/plugins/components/MyBanner";
    
    export default {
        install: (app, options) => {
            console.log("我的第一个插件")
            app.component('my-banner', MyBanner);
            app.directive("font-size", (el, binding, vnode) => {
                var size = 16;
                switch (binding.arg) {
                    case "small":
                        size = 16;
                        break;
                    case "large":
                        size = 32;
                        break;
                    default:
                        size = 48;
                        break;
                }
                el.style.fontSize = size + "px";
            });
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    现在,我们就可以在项目中随时随地去使用这个指令了,例如在我们刚刚自定义的 my-banner 中使用这个指令:

    <template>
        <div>
            <h1><a href="http://www.javaboy.org" v-font-size:small>javaboya>h1>
        div>
    template>
    
    <script>
        export default {
            name: "MyBanner"
        }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    我们甚至可以通过 options 将指令中字体的大小动态的传进来,如下:

    import MyBanner from "@/plugins/components/MyBanner";
    
    export default {
        install: (app, options) => {
            console.log("我的第一个插件")
            app.component('my-banner', MyBanner);
            app.directive("font-size", (el, binding, vnode) => {
                var size = 16;
                switch (binding.arg) {
                    case "small":
                        size = options.small;
                        break;
                    case "large":
                        size = options.large;
                        break;
                    default:
                        size = options.defaut;
                        break;
                }
                el.style.fontSize = size + "px";
            });
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    options 是插件注册时候传入的一个 JSON 参数,small、large 以及 default 分别对应的字体多大,要看插件注册时传入的值:

    const app = createApp(App);
    
    import plugin from './plugins'
    
    app.use(plugin, {small: 16, large: 32, default: 48});
    
    • 1
    • 2
    • 3
    • 4
    • 5

    第二个参数,大家看,就是 options 参数的值。

    现在大家想想我们平时用 ElementUI 的时候,Vue.use 方法,传入 ElementUI,再传入一些其他参数,看了上面这个例子,ElementUI 引入到底是怎么个引入法现在大家就明白了吧。

    2.4 provide & inject

    在插件中,也可以通过 provide 来提供一个方法,在需要使用该方法的地方,通过 inject 注入方法,然后就可以使用了,如下:

    import MyBanner from "@/plugins/components/MyBanner";
    
    export default {
        install: (app, options) => {
            console.log("我的第一个插件")
            app.component('my-banner', MyBanner);
            app.directive("font-size", (el, binding, vnode) => {
                var size = 16;
                switch (binding.arg) {
                    case "small":
                        size = options.small;
                        break;
                    case "large":
                        size = options.large;
                        break;
                    default:
                        size = options.defaut;
                        break;
                }
                el.style.fontSize = size + "px";
            });
            const clickMe = () => {
                console.log("==========clickMe=========")
            }
            app.provide('clickMe', clickMe);
        }
    };
    
    • 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

    在需要使用的地方,通过 inject 注入方法后就可以使用了,如下:

    <template>
        <div>
            <h1><a href="http://www.javaboy.org" v-font-size:small>javaboya>h1>
        div>
    template>
    
    <script>
    
        import {inject} from "vue";
    
        export default {
            name: "MyBanner",
            mounted() {
                const clickMe = inject('clickMe');
                clickMe();
            }
        }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3. 小结

    整体上来说,通过这种方式来自定义插件,能够实现的内容比较丰富。如果只是想挂一个全局方法来用,那么其实是没有必要定义插件的。如果只是想挂载一个全局方法,在 Vue2 中可以按照如下方式使用:

    Vue.prototype.postRequest = postRequest;
    
    • 1

    在 Vue3 中则可以通过如下方式:

    app.config.globalProperties.useDict = useDict
    
    • 1
  • 相关阅读:
    spark算子讲解
    深度学习论文阅读目标检测篇(七)中英对照版:YOLOv4《Optimal Speed and Accuracy of Object Detection》
    52. N皇后 II(难度:困难)
    MybatisPlus学习
    GTID主从
    Sanic​——Python函数变成API的神器
    精通 Verilog HDL 设计之编码风格(1)引言
    开发那些事儿:利用C++下载视频及记录到数据库,出现数据库报错该如何解决?
    opencv-python之位平面分解与数字水印
    前端语言报错
  • 原文地址:https://blog.csdn.net/u012702547/article/details/126116858