• 解锁前端Vue3宝藏级资料 第五章 Vue 组件应用 5 (Vue 插件)


      想了解Vue插件所以你看了官方文档却看不懂,或者你想知道Vue.use()方法和插件的关系。在本文档中,我们将参照文档讲解插件制作的基础知识,了解基础知识后,我们将制作与更实用的下拉菜单和脚本加载相关的插件。读完之后,您应该知道如何创建自己的插件以及如何添加插件。

    第一章 Vue3项目创建 1 Vue CLI 创建vue项目
    第一章 Vue3项目创建 2 使用 Webpack 5 搭建 vue项目
    第一章 Vue3项目创建 3 Vite 创建 vue项目
    第二章 Vue3 基础语法指令
    第三章 Vue Router路由器的使用
    第四章 VUE常用 UI 库 1 ( element-plus,Ant ,naiveui,ArcoDesign)
    第四章 VUE常用 UI 库 2 ( ailwind 后台框架)
    第五章 Vue 组件应用 1( Props )
    第五章 Vue 组件应用 2 ( Emit )
    第五章 Vue 组件应用 3( Slots )
    第五章 Vue 组件应用 4 ( provide 和 inject )
    第五章 Vue 组件应用 5 (Vue 插件)
    第六章 Pinia,Vuex与axios,VueUse 1(Pinia)
    第六章 Pinia,Vuex与axios,VueUse 2(Vuex)
    第六章 Pinia,Vuex与axios,VueUse 3(VueUse)
    第六章 Pinia,Vuex与axios,VueUse 4(axios)
    第七章 TypeScript 上
    第七章 TypeScript 中
    第七章 TypeScript 下 创建Trello 任务管理器
    第八章 ESLint 与 测试 ( ESLint )
    第八章 ESLint 与 测试 ( Jest )
    第八章 ESLint 与 测试 (TypeScript 中Jest与检测环境集成)

    1插件的创建

      在项目src文件夹下创建plugins文件夹,在文件中新建一个zhtPlugin.js文件。我们在zhtPlugin.js文件中创建项目的插件类代码。

      添加插件有二种方法 一种是执行install方法,第二种是则执行函数,这两种方式都可以创建插件。

    • 执行install方法
    • 创建函数
    ---------------install方法创建插件-------------------
    const zhtPlugin = {
        install() {
         alert("这是一个简单的插件");
        },
      };
    export default zhtPlugin;
    ---------------创建函数方法创建插件-------------------
    const zhtPlugin = () => {
      console.log("这是一个简单的插件");
    };
    export default zhtPlugin;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

      在main.js文件中使用 createApp() 初始化 Vue 应用实例,通过Vue 应用实例调用 use() 方法将插件添加到我们的项目应用程序中来。打开 main.js 文件并导入zhtPlugin配置类,将插件zhtPlugin指定到 app.use() 方法中。

    import { createApp } from 'vue'
    import App from './App.vue'
    import zhtPlugin from './plugin/zhtPlugin';
    const app = createApp(App)
    app.use(zhtPlugin)
    app.mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

      我们也可以不通过import来导入插件类,直接在main.js文件中创建插件类的对象或者函数,直接 装入到app.use()方法中来。

    import { createApp } from 'vue';
    import App from './App.vue';
    const app = createApp(App);
    const zhtPlugin = {
      install() {
        console.log('我的插件');
      },
    };
    app.use(zhtPlugin);
    app.mount('#app');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

      如果你想知道 Vue 的版本,你可以通过 app.version 访问它。通过使用版本信息,可以根据操作版本执行不同的处理。

    2 插件参数

      在插件中是可以设置参数的,插件是通过这些参数来进行数据传递。参数是设置在插件的install方法和函数中。下面我们创建一个接收两个参数的插件类,插件类接收的两个参数,一个是Vue 的 createApp 生成的应用程序对象,第二个是Json对象它保存了系统设置数据。

    • app 是默认参数,它是 vue 组件引用对象里面包含了所有vue组件的数据。例如 使用app.version 获得vue3版本号。
    • options 自定义参数, 需要开发者自己定义对象内容。

    在zhtPlugin.js文件中的创建下面的代码内容,打印出自定义参数与app组件内容等等信息。

    const zhtPlugin = {
      install(app, options) {
        console.log(options);
        console.log(app);
        console.log('我的插件');
        console.log(app.version);
      },
     };
    export default zhtPlugin;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

      然后在main.js文件中的 app.use() 方法中的传入zhtPlugin插件对象与自定义对象参数。自定义对象是json数据格式。插件中的app参数非常特殊不需要在app.use中来书写出来,直接在install方法或者插件函数()中定义在第一个位置就可以了。

    import { createApp } from 'vue'
    import App from './App.vue'
    import zhtPlugin from './plugin/zhtPlugin';
    const app = createApp(App)
    //vue中插入zhtPlugin插件和它的参数
    app.use(zhtPlugin,{name:"参数"})
    app.mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

      在浏览器后台中会打印出来,options传入的数据内容,vue对象的内容,vue版本号3.2.45。

    在这里插入图片描述

      现在您了解了插件的基础知识,您可能想知道用实际代码编写了哪些插件。遇到这种情况,请搜索“推荐的vue插件”等。有各种插件可用,所以如果你选择其中一个并查看GitHub页面,你会发现设置方法中使用了Vue.use方法,源代码中使用了install方法。我想你可以确认. 如果你有幸拥有一个简单的插件,通读代码将有助于你更好地理解插件。
      在本文档中,我们将参考开源插件DropDownMenu创建一个简单的下拉菜单插件。如果你能了解如何创建一个实用的插件,那么创建自己的插件的门槛应该会低很多。

    3 插件中Vue.component 注册组件

      在插件中可以注册其他vue组件到插件中来,这些注册的组件通过插件一起引入到vue项目中成为全局组件。很多开源UI框架就是通过插件的这个原理将自己定义好的vue组件和css,模板引入到项目中来的。方便开发者随时随地的使用这个UI框架中的样式和功能。

    ​  在plugins文件夹中创建一个 MyPlugin.js 文件。在这个文件中创建一个MyPlugin插件类,在这个类中我们使用 app.component 方法来添加一个组件到这个插件中来。app.component方法也叫组件注册,在上面的组件注册章节中对它有过介绍,如果对它还是不熟悉的可以重新看一下上面的章节重新了解一下。插件类在 install 方法中使用 Vue.component() 注册一个可以在整个 Vue 项目中使用的全局组件。注意在插件类中Vue.component() 这个方法的Vue对象实际上是app,所以写法为app.component 。

    import zhtbs from '../components/zhtbs.vue';
    const myPlugin = {
      install(app, options) {
        // 注册一个zhtbs组件到Vue成为全局组件
        app.component('zhtbs', zhtbs);
      },
    };
    export default myPlugin;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在项目src目录下components文件中创建一个zhtbs.vue文件,在文件中写入以下代码。

    
    
    
    • 1
    • 2
    • 3
    • 4

    在main.js文件中将myPlugin插件导入,在使用app.use将插件注册到 Vue 对象中来。

    import { createApp } from 'vue'
    import App from './App.vue'
    import zhtPlugin from './plugin/zhtPlugin';
    import myPlugin from './plugin/myPlugin'
    const app = createApp(App)
    app.use(zhtPlugin,{name:"参数"})
    app.use(myPlugin,{name:"参数"})
    app.mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在App.vue中写入下面的代码,我们可以直接在文件中的template模板中调用插件中注册的zhtbs组件了。

    <script setup>
    script>
    <template>
    <h1>欢迎你h1>
    <zhtbs />
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    浏览器中显示的内容,表示调用zhtbs组件成功了,插件配置信息生效了。

    在这里插入图片描述

    每次插件注册一个新的 app.component组件,开发时候的npm run dev都需要重新启动一次,组件才能加载成功

    4 插件中的组件slot和props使用

    ​  我们将上面讲到的插件注册组件,子组件与父组件之间的slot和props值传递,组件中的事件监听和函数等知识融合到一起综合使用。在项目开发中通常都是很多个知识点与概念综合在一起被应用的。

    ​  首先在components目录下创建一个文件zhtMenu.vue,在zhtMenu.vue中会使用slot(插槽)和props(道具)这个两个方法与引用它的父文件进行参数通信。为了使zhtMenu.vue中的功能通用,文件中的按钮和列表都使用了slot(插槽),在父组件中来描述这些slot中的信息内容,而不是在zhtMenu.vue文件本身中来描述自己的模板内容。在 zhtMenu.vue 文件中我们设置了两个slot(插槽),为了方便使用将一个设置为未命名的默认slot(插槽),别一个slot(插槽)命名为 dropdown。

    <script setup>script>
    <template>
      <div class="dropdown">
          //默认
        <button><slot>slot>button>
        <div>
            //命名为 dropdown
          <slot name="dropdown">slot>
        div>
      div>
    template>
    <style>
    .dropdown {
      display: inline-block;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在插件类zhtPlugin中注册zhtMenu.vue组件到整个项目中来。

    import zhtMenu from '../components/zhtMenu.vue';
    const myPlugin = {
      install(app, options) {
        app.component('zhtMenu', zhtMenu);
      },
    };
    export default myPlugin;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ​  zhtMenu在插件中被注册成功后,在App.vue文件直接使用中zhtMenu标签,在标签中设置子组件会用到的Slot 的内容。第一个默认 Slot的参数会传递一个字符串到zhtMenu.vue文件的按钮中,这个字符串会显示成按钮的名字。第二个Slot参数dropdown(Slot),它的内容会插入到zhtMenu.vue文件中的对应的slot name="dropdown"位置中。

    <script setup>script>
    <template>
      <div>
          <h3>定义自己的插件组件h3>
        <drop-down-menu>
          信息列表
          <template v-slot:dropdown>
            <a class="dropdown-item" href="#">Vue.jsa>
            <a class="dropdown-item" href="#">java spring boota>
            <a class="dropdown-item" href="#">nodea>
            <a class="dropdown-item" href="#">pythona>
            <a class="dropdown-item" href="#">goa>
          template>
        drop-down-menu>
      div>
    template>
    
    <style scoped>
    .dropdown-item {
      display: block;
      padding: 0.25rem 1.5rem;
      font-weight: 400;
      color: #212529;
      text-decoration: none;
    }
    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

    在浏览器显示一个按钮和一个列表,下面我们将添加按钮显示与隐藏功能。

    在这里插入图片描述

    ​  按钮显示与隐藏功能实现需要 ref 函数定义一个反应变量 show,通过这个show 来控制列表内容的显示和隐藏。我们将show默认值设置为 false,在将它和 v-show 指令绑定,这时候浏览器列表会被隐藏起来。

    <script setup>
    import { ref } from 'vue';
    const show = ref(false);
    script>
    <template>
      <div>
        <h3>定义自己的插件组件h3>
        <zhtMenu v-model="show">
          信息列表
          <template v-slot:dropdown>
            <a class="dropdown-item" href="#">Vue.jsa>
            <a class="dropdown-item" href="#">java spring boota>
            <a class="dropdown-item" href="#">nodea>
            <a class="dropdown-item" href="#">pythona>
            <a class="dropdown-item" href="#">goa>
          template>
        zhtMenu>
      div>
    template>
    <style scoped>
    .dropdown-item {
      display: block;
      padding: 0.25rem 1.5rem;
      font-weight: 400;
      color: #212529;
      text-decoration: none;
    }
    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

    ​  由于我们将组件设置了 v-model指令,因此可以在zhtMen.vue文件中将show值作为 props 的 modalValue值来接收。

    <script setup>
    const props = defineProps({
        //获得父组件 v-model 中的show 值
      modelValue: Boolean,  <-------------|
    });                                   |
    script>                             |
    <template>                            |
      <div class="dropdown" >             |
        <button><slot>slot>button>    |
        <div v-show="modelValue">    <----|
           name="dropdown">slot>
        div>
      div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ​  现在需要一个点击事件来完成列表的显示和隐藏功能。创建一个onShowMenu函数,在函数中使用emit的方法来方法修改modelValue中的值,emit方法参数是update:modalValue事件,它会改变父组件this.modalValue中的值。通过在父组件App.vue文件接收到子组件的emit事件,来完成点击按钮时show值在true和false之间切换。最后在将onShowMenu函数与按钮的click事件绑定在一起。

    <script setup>
    const props = defineProps({
      modelValue: Boolean,
    });
    //获得父组件的事件参数
    const emit = defineEmits(['update:modelValue']);
    const onShowMenu = () => {
      //设置事件参数
      emit('update:modelValue', !props.modelValue);
    };
    script>
    <template>
      <div class="dropdown" >
        <button @click="onShowMenu"><slot>slot>button>
        <div v-show="modelValue">
          <slot name="dropdown">slot>
        div>
      div>
    template>
    <style>
    .dropdown {
      display: inline-block;
    }
    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

    ​  现在我们完成了列表的显示与隐藏功能,在浏览中点击按钮就会切列表的换显示与隐藏。

    点击父组件任何地方隐藏列表

    ​  下面我们来写一点有难度的代码,当我们点击子组件以外的地方,显示状态下的列表会被隐藏。在子组件范围内只有点击按钮才会将显示状态下的列表隐藏起来。

    ​  首先在App.vue文件中添加一个反应ref函数的响应式变量closeOnClick,以便在父组件来控制子组件的函数,closeOnClick值通过props中传递到子组件。

    <script setup>
    import { ref } from 'vue';
    const show = ref(false);
    const closeOnClick = ref(true);------控制函数属性
    script>
    <template>
      <div>
        <h3>定义自己的插件组件h3>
        <zhtMenu  v-model="show" :closeOnClick="closeOnClick">
          信息列表
          <template v-slot:dropdown>
            <a class="dropdown-item" href="#">Vue.jsa>
            <a class="dropdown-item" href="#">java spring boota>
            <a class="dropdown-item" href="#">nodea>
            <a class="dropdown-item" href="#">pythona>
            <a class="dropdown-item" href="#">goa>
          template>
        zhtMenu>
      div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    ​  在zhtMen.vue文件通过props来获得到父组件中的closeOnClick值,然后在文件中添加事件侦听器来检测点击事件是否在zhtMen组件之中触发。首先导入 onMounted 和 onUnmounte函数到子组件中来,创建 onMounted 和 onUnmounte函数,在它们的生命周期钩子中添加事件监听器。
    ​  我们在创建这个事件监听器函数,在这个函数中进行事件组件与子组件是否是同一组件的逻辑判断,如果判断为treu再判断closeOnClick是否为true与列表是否是显示状态,判断结构为true隐藏列表信息。

    <script setup>
    import { onMounted, onUnmounted, ref } from 'vue';
    //将html元素装入target变量。中对应模板中 
    const target = ref(null); const props = defineProps({ modelValue: Boolean, //获得App.vue中的值 closeOnClick: { type: Boolean, default: true, }, }); const emit = defineEmits(['update:modelValue']); const toggleMenu = () => { emit('update:modelValue', !props.modelValue); }; //设置监听事件 onMounted(() => { if (props.closeOnClick) { document.addEventListener('click', clickOutside); } }); //设置事件监听 onUnmounted(() => { if (props.closeOnClick) { document.removeEventListener('click', clickOutside); } }); //监听事件业务逻辑函数 const clickOutside = (event) => { //判断是否为同一个html元素发出的事件 if (!target.value.contains(event.target)) { //判断列表状态,和closeOnClick状态 if (props.modelValue && props.closeOnClick) { emit('update:modelValue', false); } } }; script> <template> // 不需要监听关闭列表的事件监听元素装入到target中 ref="target" <div class="dropdown" ref="target"> <button @click="toggleMenu" ><slot>slot>button> <div v-show="modelValue"> <slot name="dropdown">slot> div> div> template> <style> .dropdown { display: inline-block; } 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
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    ​  由于事件中可以获取到被点击的元素,所以我们检查被点击的元素是否包含在

    将html元素装入到反应函数中

    开发小技巧可以将模板中的html元素通过ref指令装入到反应函数中来。

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5 插件中加载script 标签

    ​  使用第三方库(如 Google Map)时,您可能需要在 head 标签中插入一个 script 标签。在这种情况下,您可能正在使用诸如 vue-plugin-load-script 之类的库。vue-plugin-load-script 的内容也很简单,我们来创建一个插件作为参考。在下拉菜单中,我们确认了如何使用组件添加插件。这里,我们确认如何使用函数添加插件。

    ​  在 plugins 文件夹下创建一个 LoadScript.js 文件。编写代码,使得添加插件后在应用程序的组件中执行this.$loadScript时,可以执行LoadScript中描述的loadScript函数。

    const LoadScript = {
        install(app) {
          const loadScript = () => {
            console.log('加载 Script Plugin 生成');
          };
          app.config.globalProperties.$loadScript = loadScript;
        },
      };
      export default LoadScript;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    script setup语法中使用getCurrentInstance获得全局引用。

    <script setup>
    import { onMounted,getCurrentInstance} from 'vue';
    const {proxy} =getCurrentInstance();
    onMounted(() => {
      proxy.$loadScript();
    });
    script>
    <template>
      <h1>加载 Script Pluginh1>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    component 方法加载

    <template>
      <h1>加载 Script Pluginh1>
    template>
    <script>>
    export default {
      mounted() {
        this.$loadScript();
      },
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    script setup语法与component 混合加载

    <script>
    import { onBeforeMount, defineComponent } from 'vue'
    let that = this
    export default defineComponent({
      beforeCreate() {
        that = this
      },
    })
    script>
    <script setup>
    import { onMounted } from 'vue';
    onMounted(() => {
      that.$loadScript();
    });
    script>
    <template>
      <h1>Load Script Pluginh1>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    如果您在浏览器中检查它,您将在 veloper 工具控制台中看到“加载脚本插件”。我能够弄清楚如何使用插件执行该功能。

  • 相关阅读:
    上传代码到GitHub仓库
    Java面向对象(进阶)-- super关键字的使用与子类对象实例化全过程
    数据库基本增删改查语法和多表联查的方式
    论文阅读【3】Efficient Estimation of Word Representations in Vector Space
    【并发编程】线程间的通信
    三角函数画图
    AutoJSPro薅羊毛脚本源码
    物体6D位姿估计方法总结
    如何才能搭建高质量的在线产品手册呢?
    regexp_extract用法
  • 原文地址:https://blog.csdn.net/zhtbs/article/details/132986483