如何在 Vue.js 中使用第三方js库
在诸多Vue.js应用中,Lodash,Moment,Axios,Async等都是一些非常有用的JavaScript库.但随着项目越来越复杂,可能会采取组件化和模块化的方式来组织代码,还可能要使应用支持不同环境下的服务端渲染.除非你找到了一个简单而又健壮的方式来引入这些库供不同的组件和模块使用,不然,这些第三方库的管理会给你带来一些麻烦.
本文将介绍一些在Vue.js中使用第三方库的方式.
全局变量
在项目中添加第三方库的最简单方式是讲其作为一个全局变量,挂载到window对象上:
entry.js
window._=require('lodash');
MyComponent.vue
exportdefault{ created(){ console.log(_.isEmpty()?'Lodasheverywhere!':'Uhoh..'); } }
这种方式不适合于服务端渲染,因为服务端没有window对象,是undefined,当试图去访问属性时会报错.
在每个文件中引入
另一个简单的方式是在每一个需要该库的文件中导入:
MyComponent.vue
import_from'lodash'; exportdefault{ created(){ console.log(_.isEmpty()?'Lodashisavailablehere!':'Uhoh..'); } }
这种方式是允许的,但是比较繁琐,并且带来的问题是:你必须记住在哪些文件引用了该库,如果项目不再依赖这个库时,得去找到每一个引用该库的文件并删除该库的引用.如果构建工具没设置正确,可能导致该库的多份拷贝被引用.
优雅的方式
在Vuejs项目中使用JavaScript库的一个优雅方式是讲其代理到Vue的原型对象上去.按照这种方式,我们引入Moment库:
entry.js
importmomentfrom'moment'; Object.definePrototype(Vue.prototype,'$moment',{value:moment});
由于所有的组件都会从Vue的原型对象上继承它们的方法,因此在所有组件/实例中都可以通过this.$moment:的方式访问Moment而不需要定义全局变量或者手动的引入.
MyNewComponent.vue
exportdefault{ created(){ console.log('Thetimeis'.this.$moment().format("HH:mm")); } }
接下来就了解下这种方式的工作原理.
Object.defineProperty
一般而言,可以按照下面的方式来给对象设置属性:
Vue.prototype.$moment=moment;
可以这样做,但是Object.defineProperty允许我们通过一个descriptor来定义属性.Descriptor运行我们去设置对象属性的一些底层(low-level)细节,如是否允许属性可写?是否允许属性在for循环中被遍历.
通常,我们不会为此感到困扰,因为大部分时候,对于属性赋值,我们不需要考虑这样的细节.但这有一个明显的优点:通过descriptor创建的属性默认是只读的.
这就意味着,一些处于迷糊状态的(coffee-deprived)开发者不能在组件内去做一些很愚蠢的事情,就像这样:
this.$http='Assignsomerandomthingtotheinstancemethod'; this.$http.get('/');//TypeError:this.$http.getisnotafunction
此外,试图给只读实例的方法重新赋值会得到TypeError:Cannotassigntoreadonlyproperty的错误.
$
你可能会注意到,代理第三库的属性会有一个$前缀,也可能看到其它类似$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 //Onlyworksinafatarrowcallback. } });
插件
如果你想在多个项目中使用同一个库,或者想将其分享给其他人,可以将其写成一个插件:
importMyLibraryPluginfrom'my-library-plugin'; Vue.use(MyLibraryPlugin);
在应用的入口引入插件之后,就可以在任何一个组件内像使用VueRouter,Vuex一样使用你定义的库了.
写一个插件
首先,创建一个文件用于编写自己的插件.在示例中,我会将Axios作为插件添加到项目中,因而我给文件起名为axios.js.其次,插件要对外暴露一个install方法,该方法的第一个参数是Vue的构造函数:
axios.js
exportdefault{ install:function(Vue){ //Dostuff } }
可以使用先前将库添加到原型对象上的方法:
axios.js
importaxiosfrom'axios'; exportdefault{ install:function(Vue,){ Object.defineProperty(Vue.prototype,'$http',{value:axios}); } }
最后,利用Vue的实例方法use将插件添加到项目中:
entry.js
importAxiosPluginfrom'./axios.js'; Vue.use(AxiosPlugin); newVue({ created(){ console.log(this.$http?'Axiosworks!':'Uhoh..'); } })
彩蛋:插件的可选参数
插件的install方法可以接受可选参数.一些开发可能不喜欢将Axios实例命名为$http,因为这是VueResource提供的一个通用名字.因而可以提供一个可选的参数允许他们随意命名:
axions.js
importaxiosfrom'axios'; exportdefault{ install:function(Vue,name='$http'){ Object.defineProperty(Vue.prototype,name,{value:axios}); } } entry.js importAxiosPluginfrom'./axios.js'; Vue.use(AxiosPlugin,'$axios'); newVue({ created(){ console.log(this.$axios?'Axiosworks!':'Uhoh..'); } })
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。