在诸多 Vue.js 应用中, Lodash, Moment, Axios, Async等都是一些非常有用的 JavaScript 库. 但随着项目越来越复杂, 可能会采取组件化和模块化的方式来组织代码, 还可能要使应用支持不同环境下的服务端渲染. 除非你找到了一个简单而又健壮的方式来引入这些库供不同的组件和模块使用, 不然, 这些第三方库的管理会给你带来一些麻烦.
本文将介绍一些在 Vue.js 中使用第三方库的方式.
全局变量
在项目中添加第三方库的最简单方式是讲其作为一个全局变量, 挂载到 window 对象上:
entry.js
window._ = require('lodash');
MyComponent.vue
export default { created() { console.log(_.isEmpty() ? 'Lodash everywhere!' : 'Uh oh..'); } }
这种方式不适合于服务端渲染, 因为服务端没有 window 对象, 是 undefined , 当试图去访问属性时会报错.
在每个文件中引入
另一个简单的方式是在每一个需要该库的文件中导入:
MyComponent.vue
import _ from 'lodash'; export default { created() { console.log(_.isEmpty() ? 'Lodash is available here!' : 'Uh oh..'); } }
这种方式是允许的, 但是比较繁琐, 并且带来的问题是: 你必须记住在哪些文件引用了该库, 如果项目不再依赖这个库时, 得去找到每一个引用该库的文件并删除该库的引用. 如果构建工具没设置正确, 可能导致该库的多份拷贝被引用.
优雅的方式
在 Vuejs 项目中使用 JavaScript 库的一个优雅方式是讲其代理到 Vue 的原型对象上去. 按照这种方式, 我们引入 Moment 库:
entry.js
import moment from 'moment'; Object.definePrototype(Vue.prototype, '$moment', { value: moment });
由于所有的组件都会从 Vue 的原型对象上继承它们的方法, 因此在所有组件/实例中都可以通过 this.$moment: 的方式访问 Moment 而不需要定义全局变量或者手动的引入.
MyNewComponent.vue
export default { created() { console.log('The time is ' . this.$moment().format("HH:mm")); } }
接下来就了解下这种方式的工作原理.
Object.defineProperty
一般而言, 可以按照下面的方式来给对象设置属性:
Vue.prototype.$moment = moment;
可以这样做, 但是 Object.defineProperty 允许我们通过一个 descriptor 来定义属性. Descriptor 运行我们去设置对象属性的一些底层(low-level)细节, 如是否允许属性可写? 是否允许属性在 for 循环中被遍历.
通常, 我们不会为此感到困扰, 因为大部分时候, 对于属性赋值, 我们不需要考虑这样的细节. 但这有一个明显的优点: 通过 descriptor 创建的属性默认是只读的 .
这就意味着, 一些处于迷糊状态的(coffee-deprived)开发者不能在组件内去做一些很愚蠢的事情, 就像这样:
this.$http = 'Assign some random thing to the instance method'; this.$http.get('/'); // TypeError: this.$http.get is not a function
此外, 试图给只读实例的方法重新赋值会得到 TypeError: Cannot assign to read only property 的错误.
$
你可能会注意到, 代理第三库的属性会有一个 $ 前缀, 也可能看到其它类似 $refs, $on, $mount 的属性和方式, 它们也有这个前缀.
这个不是强制要求, 给属性添加 $ 前缀是提供那些处于迷糊状态(coffee-deprived)的开发者这是一个公开的 API, 和 Vuejs 的一些内部属性和方法区分开来.
this
你还可能注意到, 在组件内是通过 this.libraryName 的方式来使用第三方库的, 当你知道它是一个实例方法时就不会感到意外了. 但与全局变量不同, 通过 this 来使用第三方库时, 必须确保 this 处于正确的作用域. 在回调方法中 this 的作用域会有不同, 但箭头式回调风格能保证 this 的作用域是正确的:
this.$http.get('/').then(res => { if (res.status !== 200) { this.$http.get('/') // etc // Only works in a fat arrow callback. } });
插件
如果你想在多个项目中使用同一个库, 或者想将其分享给其他人, 可以将其写成一个插件:
import MyLibraryPlugin from 'my-library-plugin'; Vue.use(MyLibraryPlugin);
在应用的入口引入插件之后, 就可以在任何一个组件内像使用 Vue Router , Vuex 一样使用你定义的库了.
写一个插件
首先, 创建一个文件用于编写自己的插件. 在示例中, 我会将 Axios 作为插件添加到项目中, 因而我给文件起名为 axios.js . 其次, 插件要对外暴露一个 install 方法, 该方法的第一个参数是 Vue 的构造函数:
axios.js
export default { install: function(Vue) { // Do stuff } }
可以使用先前将库添加到原型对象上的方法:
axios.js
import axios from 'axios'; export default { install: function(Vue,) { Object.defineProperty(Vue.prototype, '$http', { value: axios }); } }
最后, 利用 Vue 的实例方法 use 将插件添加到项目中:
entry.js
import AxiosPlugin from './axios.js'; Vue.use(AxiosPlugin); new Vue({ created() { console.log(this.$http ? 'Axios works!' : 'Uh oh..'); } })
彩蛋: 插件的可选参数
插件的 install 方法可以接受可选参数. 一些开发可能不喜欢将 Axios 实例命名为 $http , 因为这是 Vue Resource 提供的一个通用名字. 因而可以提供一个可选的参数允许他们随意命名:
axions.js
import axios from 'axios'; export default { install: function(Vue, name = '$http') { Object.defineProperty(Vue.prototype, name, { value: axios }); } } entry.js import AxiosPlugin from './axios.js'; Vue.use(AxiosPlugin, '$axios'); new Vue({ created() { console.log(this.$axios ? 'Axios works!' : 'Uh oh..'); } })
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
我已经下载了代数鸟,我想使用这个库在Scala解释器中试用一些东西。我如何实现这一点?
我从其他团队收到了一个jar文件,需要在AEM中使用。我不能在AEM中直接使用jar,所以我在链接的帮助下将jar转换为捆绑包。”https://helpx.adobe.com/experience-manager/kb/ConvertAJarIntoOsgiBundle.html“,现在我的bundle已经准备好,并通过felix控制台上传到AEM中。bundle处于活动状态。现在我需要使用bu
问题内容: 我有一些使用第三方库的java9模块,它不是Java9模块,只是一个简单的实用jar。 但是,编译器抱怨它无法从我的实用程序中找到软件包。 我应该怎么做才能使用我的第三方库? 问题答案: 您可以将您的库用作 自动模块 。自动模块是没有模块描述符(即)的模块。 但是,您需要指定什么名称来引用自动模块?自动模块的名称是从JAR名称派生的(除非此JAR包含属性)。完整的规则很长(请参阅Jav
我有一些使用第三方库的java9模块,它不是java9模块,只是一个简单的实用程序jar。 但是,编译器抱怨它找不到来自我的实用程序的包。 我应该做什么在启用使用我的第三方库?
本文向大家介绍angular2中使用第三方js库的实例,包括了angular2中使用第三方js库的实例的使用技巧和注意事项,需要的朋友参考一下 本文以jquery 为例 第一种:有对应的声明文件的 1、用命令安装jQuery的声明文件。(声明文件是为了ide完美智能提示) 2、引入jquery 3、使用 第二种:没有声明文件,自定义的js库 1、 index.html中引入 js 文件 在ts文件
问题内容: 我想使用jQuery和其他不是React本身的第三方库。如何在我的React项目中使用它们?我读到的是调用第三方库的好地方。 不幸的是,即使我已经正确地将脚本标记链接到index.html文件中的那些库,但由于不断收到“未定义”错误,所以我无法使用这些库。 问题答案: 您有两个选择,均由一个人为设计的示例演示,其中我使用jQuery淡出了无序列表。两种方法都各有利弊,我先强调两种方法,