插件 (Plugins)
# 插件 (Plugins)
插件是用于增强 Vue 的功能,通过 install
方法给 Vue 或 Vue 实例添加方法,定义全局指令等。
功能
- 增强 Vue 的功能
- 通过
install
方法给 Vue 或 Vue 实例添加方法,定义全局指令等
本质
插件本质上是一个包含 install
方法的对象。
install
方法的第一个参数是Vue
。- 第二个及后续参数是插件使用者传递的数据(通常是一个对象)。
注意事项
在 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;
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');
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;
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>
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>
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');
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;
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>
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;
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');
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
# 插件内部实现解析
安装检查:使用
this.installed
属性来检查是否已经安装过插件,如果已经安装则直接返回,避免重复安装。检查
axios
实例:确保在安装插件时传入了axios
实例,如果没有传入,则输出错误信息并返回。这是必传参数。设置
axios
的基础配置:根据传入的options
参数,设置axios
的基础 URL 和请求头信息。这些是可选参数。挂载到 Vue 原型:使用
Vue.prototype.$http
和Vue.prototype.$axios
将axios
实例挂载到 Vue 原型上,使得在所有 Vue 组件中都可以通过this.$http
或this.$axios
访问axios
实例。自定义逻辑:例如设置请求和响应拦截器,可以通过传入的
options
参数来配置。这些是可选参数。
# 可选参数和必传参数
必传参数:
axiosInstance
:需要传入一个axios
实例,以便插件将其挂载到 Vue 原型上。
可选参数:
baseURL
:设置axios
实例的基础 URL。headers
:设置axios
实例的默认请求头。interceptors
:配置axios
的请求和响应拦截器。