程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Vue2

    • Vue简介
    • Vue 基础使用
    • Vue的基础指令
    • 过滤器(Filters)
    • 侦听器(Watch)
    • 计算属性(computed)
    • vue-cli
    • vue.config.js配置
    • Vue组件
    • 生命周期和数据共享
    • Vue 组件实例与数据代理 (this)
    • $refs 引用
    • 动态组件
    • 插槽 (Slots)
    • 混入 (Mixin)
    • 自定义指令 (directives)
    • 插件 (Plugins)
      • 1. 定义插件
      • 2. 使用插件
        • 全局使用插件
        • 在插件中使用传递的数据
        • 在组件中使用插件提供的功能
      • 3. 原则和注意事项
      • 4. 插件在 <template> 中的使用
      • 5. 直接挂载插件到 Vue 原型
        • 手动配置 插件 (axios)
        • 在组件中使用 (axios)
      • 6. 第三方插件实现示例
        • 插件内部实现
        • 使用插件示例
        • 插件内部实现解析
        • 可选参数和必传参数
    • 初识Vue-router
    • Vue-router的常见用法
  • Vue3

  • vue3 + TS 项目集成

  • Vue全家桶
  • Vue2
scholar
2024-08-01
目录

插件 (Plugins)

# 插件 (Plugins)

插件是用于增强 Vue 的功能,通过 install 方法给 Vue 或 Vue 实例添加方法,定义全局指令等。

功能

  • 增强 Vue 的功能
  • 通过 install 方法给 Vue 或 Vue 实例添加方法,定义全局指令等

本质

插件本质上是一个包含 install 方法的对象。

  1. install 方法的第一个参数是 Vue。
  2. 第二个及后续参数是插件使用者传递的数据(通常是一个对象)。

注意事项

在 Vue 插件的 install 方法中,虽然你可以定义多个参数,但在实际开发中,建议将所有的配置参数打包成一个对象传递给插件的 install 方法,这样可以保持代码的整洁和易维护性。

# 1. 定义插件

定义一个插件对象,该对象包含 install 方法。可以在 install 方法中添加全局过滤器、全局指令、全局混入和实例方法,并接收用户传递的配置参数。

// myPlugin.js
const myPlugin = {
  install(Vue, options = {}) {  // 第二个参数是一个对象,用于接收用户传递的配置参数
    // 1. 添加全局过滤器
    Vue.filter('myFilter', function(value) {
      return value.toUpperCase();
    });

    // 2. 添加全局指令
    Vue.directive('my-directive', {
      bind(el, binding, vnode) {
        el.style.color = binding.value;
      }
    });

    // 3. 配置全局混入
    Vue.mixin({
      created() {
        console.log('混入的 created 钩子');
      }
    });

    // 4. 添加实例方法
    Vue.prototype.$myMethod = function() {
      console.log('这是实例方法');
    };
    Vue.prototype.$myProperty = '这是实例属性';

    // 使用 options 参数
    console.log('插件的选项:', options);
    if (options.someOption) {
      // 根据传递的选项参数执行某些操作
      console.log('插件选项 someOption 为 true');
    }
  }
};

export default myPlugin;
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

# 2. 使用插件

使用 Vue.use() 方法来安装插件。Vue.use() 会调用插件的 install 方法,并传入 Vue 作为第一个参数,第二个参数是用户传递的配置对象。

# 全局使用插件

在 main.js 文件中引入插件并全局注册。

// main.js
import Vue from 'vue';
import App from './App.vue';
import myPlugin from './myPlugin';

// 使用插件并传递选项参数
Vue.use(myPlugin, { someOption: true });

new Vue({
  render: h => h(App),
}).$mount('#app');
1
2
3
4
5
6
7
8
9
10
11

在上述代码中,Vue.use(myPlugin, { someOption: true }) 调用了插件的 install 方法,并传递了一个包含配置选项的对象 { someOption: true } 作为第二个参数。

# 在插件中使用传递的数据

在插件的 install 方法中,第二个及后续参数可以作为 options 参数接收并使用。下面是一个详细的示例,展示了如何使用传递的数据:

// myPlugin.js
const myPlugin = {
  install(Vue, options = {}) {  // 第二个参数是一个对象,用于接收用户传递的配置参数
    // 1. 添加全局过滤器
    Vue.filter('myFilter', function(value) {
      return value.toUpperCase();
    });

    // 2. 添加全局指令
    Vue.directive('my-directive', {
      bind(el, binding, vnode) {
        el.style.color = binding.value;
      }
    });

    // 3. 配置全局混入
    Vue.mixin({
      created() {
        console.log('混入的 created 钩子');
      }
    });

    // 4. 添加实例方法
    Vue.prototype.$myMethod = function() {
      console.log('这是实例方法');
    };
    Vue.prototype.$myProperty = '这是实例属性';

    // 使用 options 参数
    console.log('插件的选项:', options);
    if (options.someOption) {
      // 根据传递的选项参数执行某些操作
      console.log('插件选项 someOption 为 true');
    }
  }
};

export default myPlugin;
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

# 在组件中使用插件提供的功能

组件示例:

<template>
  <div>
    <!-- 使用全局过滤器 -->
    <p>{{ 'hello' | myFilter }}</p>
    <!-- 使用全局指令 -->
    <div v-my-directive="'blue'">这是一个自定义指令</div>
    <!-- 使用实例方法和属性 -->
    <button @click="$myMethod">调用实例方法</button>
    <p>{{ $myProperty }}</p>
  </div>
</template>

<script>
export default {
  name: 'ExampleComponent',
  created() {
    console.log('这是组件自己的 created 钩子');
  }
};
</script>

<style>
/* 这里可以添加一些样式 */
</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

# 3. 原则和注意事项

  • 插件的定义:插件是一个包含 install 方法的对象。
  • 插件的使用:使用 Vue.use() 方法安装插件,会调用插件的 install 方法。
  • 插件的功能:可以在插件中添加全局过滤器、全局指令、全局混入和实例方法。
  • 插件的参数:install 方法的第一个参数是 Vue,后续参数是插件使用者传递的数据。
  • 用户配置选项:原则上插件上暴露出的 options 配置项是供用户进行配置用的。插件内部已经提前写好的代码,通过暴露这些可选配置项,供用户根据需求进行配置,以激活或调整插件的内部行为。这样做的目的是为了提供灵活性,让用户可以根据具体的使用场景来定制插件的功能。

# 4. 插件在 <template> 中的使用

在 Vue 组件的 <template> 中使用通过插件注册的功能时,不需要使用 this 关键字。例如:

<template>
  <div>
    <!-- 使用全局过滤器 -->
    <p>{{ 'hello' | myFilter }}</p>
    <!-- 使用全局指令 -->
    <div v-my-directive="'blue'">这是一个自定义指令</div>
    <!-- 使用实例方法和属性 -->
    <button @click="$myMethod">调用实例方法</button>
    <p>{{ $myProperty }}</p>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11

在 <template> 中,直接使用插件注册的过滤器、指令、实例方法和属性即可,不需要通过 this 访问。

# 5. 直接挂载插件到 Vue 原型

通过将插件(例如 axios)直接挂载到 Vue 原型上,可以在所有 Vue 组件中使用该插件实例。

将 axios 实例挂载到 Vue 原型上

通过 Vue.prototype.$axios = axios,可以在任何组件中通过 this.$axios 访问 axios 实例。

import Vue from 'vue';
import App from './App.vue';
import axios from 'axios';

// 将 axios 实例挂载到 Vue 原型上
Vue.prototype.$axios = axios;

new Vue({
  render: h => h(App),
}).$mount('#app');
1
2
3
4
5
6
7
8
9
10

优点

  • 简单易用:直接挂载插件到 Vue 原型,方便在所有组件中使用插件实例。例如,通过 Vue.prototype.$axios = axios,可以在任何组件中通过 this.$axios 访问 axios 实例。
  • 快速实现:这种方法不需要定义插件的 install 方法,适合快速开发和小型项目。

缺点

  • 无法使用插件选项:无法通过插件暴露的 options 参数进行集中配置管理。例如,无法在插件安装时统一设置 baseURL、默认 headers 或者添加 interceptors。
  • 分散配置:手动配置可能导致代码分散,不如集中配置管理更加清晰。

# 手动配置 插件 (axios)

尽管无法通过插件暴露的 options 参数进行集中配置管理,但是我们也可以手动配置 axios 的默认参数和拦截器。

通过 axios 的 API 方法,你可以在挂载之前手动设置 axios 的默认参数和拦截器。

import axios from "axios";
import { Message } from "element-ui";

// 创建新的axios实例
const service = axios.create({
  // 公共接口
  baseURL: process.env.BASE_API || 'https://api.example.com', 
  // 超时时间 单位是ms
  timeout: 3000,
});

// 请求拦截器
service.interceptors.request.use(
  config => {
    const token = getToken(); // 获取 token
    if (token) {
      config.headers.token = token; // 将 token 添加到请求头
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  response => {
    return response.data;
  },
  error => {
    if (error && error.response) {
      switch (error.response.status) {
        case 400: error.message = "错误请求"; break;
        case 401: error.message = "未授权,请重新登录"; window.location.href = "/login"; break;
        case 403: error.message = "拒绝访问"; break;
        case 404: error.message = "请求错误,未找到该资源"; window.location.href = "/NotFound"; break;
        case 500: error.message = "服务器端出错"; break;
        default: error.message = `连接错误${error.response.status}`;
      }
    } else {
      if (JSON.stringify(error).includes("timeout")) {
        Message.error("服务器响应超时,请刷新当前页");
      }
      error.message = "连接服务器失败";
    }
    Message.error(error.message);
    return Promise.reject(error.response);
  }
);

// 将 axios 实例挂载到 Vue 原型上
Vue.prototype.$axios = service;
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

提示

注意如果我们不挂载在 Vue 原型上,而是直接导出配置好的 axios 实例对象,也能在各个组件中使用。通过这种方式,你可以直接在需要的地方导入并使用 axios 实例。

# 在组件中使用 (axios)

在组件中,你可以通过 this.$axios 访问 axios 实例,并调用其方法。

<template>
  <div>
    <button @click="fetchData">Fetch Data</button>
  </div>
</template>

<script>
export default {
  name: 'ExampleComponent',
  methods: {
    fetchData() {
      this.$axios.get('/data') // 由于 baseURL 已经设置,这里只需要提供相对路径
        .then(response => {
          console.log(response);
        })
        .catch(error => {
          console.error(error);
        });
    }
  }
};
</script>

<style>
/* 这里可以添加一些样式 */
</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

# 6. 第三方插件实现示例

# 插件内部实现

下面是一个的 VueAxios 插件的内部实现示例,用于展示如何将 axios 挂载到 Vue 原型上,并且支持用户传递配置选项。

// vue-axios.js
const VueAxios = {
  installed: false, // 防止重复安装

  install(Vue, axiosInstance, options = {}) { // 第二个参数是 axios 实例,第三个参数是配置选项对象
    if (this.installed) {
      return; // 如果已经安装,则直接返回,防止重复安装
    }
    this.installed = true;

    // 检查 axios 实例是否传入
    if (!axiosInstance) {
      console.error('You have to install axios'); // 如果没有传入 axios 实例,则输出错误信息
      return;
    }

    // 设置 axios 的基础配置(可选参数)
    if (options.baseURL) {
      axiosInstance.defaults.baseURL = options.baseURL; // 设置基础 URL
    }
    if (options.headers) {
      axiosInstance.defaults.headers = options.headers; // 设置请求头
    }

    // 挂载到 Vue 原型上,使得在所有组件中都可以通过 this.$http 或 this.$axios 访问 axios 实例
    Vue.prototype.$http = axiosInstance;
    Vue.prototype.$axios = axiosInstance;

    // 自定义逻辑,例如设置拦截器(可选参数)
    if (options.interceptors) {
      options.interceptors.forEach(interceptor => {
        if (interceptor.request) {
          axiosInstance.interceptors.request.use(interceptor.request); // 设置请求拦截器
        }
        if (interceptor.response) {
          axiosInstance.interceptors.response.use(interceptor.response); // 设置响应拦截器
        }
      });
    }
  }
};

export default VueAxios;
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

# 使用插件示例

在 main.js 中引入并使用这个插件:

// main.js
import Vue from 'vue';
import App from './App.vue';
import axios from 'axios';
import VueAxios from './vue-axios';

// 使用插件并传递选项参数
Vue.use(VueAxios, axios, {
  baseURL: 'https://api.example.com', // 可选参数:设置 axios 的基础 URL
  headers: { // 可选参数:设置 axios 的请求头
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  interceptors: [ // 可选参数:设置 axios 的请求和响应拦截器
    {
      request: config => {
        console.log('Request Interceptor:', config);
        return config;
      },
      response: response => {
        console.log('Response Interceptor:', response);
        return response;
      }
    }
  ]
});

new Vue({
  render: h => h(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
23
24
25
26
27
28
29

# 插件内部实现解析

  1. 安装检查:使用 this.installed 属性来检查是否已经安装过插件,如果已经安装则直接返回,避免重复安装。

  2. 检查 axios 实例:确保在安装插件时传入了 axios 实例,如果没有传入,则输出错误信息并返回。这是必传参数。

  3. 设置 axios 的基础配置:根据传入的 options 参数,设置 axios 的基础 URL 和请求头信息。这些是可选参数。

  4. 挂载到 Vue 原型:使用 Vue.prototype.$http 和 Vue.prototype.$axios 将 axios 实例挂载到 Vue 原型上,使得在所有 Vue 组件中都可以通过 this.$http 或 this.$axios 访问 axios 实例。

  5. 自定义逻辑:例如设置请求和响应拦截器,可以通过传入的 options 参数来配置。这些是可选参数。

# 可选参数和必传参数

  • 必传参数:

    • axiosInstance:需要传入一个 axios 实例,以便插件将其挂载到 Vue 原型上。
  • 可选参数:

    • baseURL:设置 axios 实例的基础 URL。
    • headers:设置 axios 实例的默认请求头。
    • interceptors:配置 axios 的请求和响应拦截器。
编辑此页 (opens new window)
上次更新: 2025/01/30, 23:55:43
自定义指令 (directives)
初识Vue-router

← 自定义指令 (directives) 初识Vue-router→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式