在Vue.js应用中,可能需要引入Lodash,Moment,Axios,Async等非常好用的JavaScript库。当项目变得复杂庞大,通常会将代码进行模块化拆分。可能还需要跑在不同的环境下,比如浏览器,服务端。

如何在各个模块和组件文件中引入需要的库呢? 找到一种简单靠谱的方式,可以省去很多的麻烦。

错误示范

全局变量法

最不靠谱的方式就是将导入的库挂在全部变量window对象下:

entry.js

window._ = require('lodash');

MyComponent.vue

export default {
created() {
console.log(_.isEmpty() ? 'Lodash everywhere!' : 'Uh oh..');
}
}

这种方式的缺点有很多,我们只说其中一个关键的点:不支持服务端渲染。当应用跑在服务端时,window对象不存在,当然试图去访问window下的属性会抛出错误。

处处引入法

另外一个不太优雅的方式就是在需要的每个文件中都引入对应的库:

MyComponent.vue

import _ from 'lodash';

export default {
created() {
console.log(_.isEmpty() ? 'Lodash is available here!' : 'Uh oh..');
}
}

虽然这方法是可行的,但是太不简洁。你必须在每个文件中都记得引入, 而且如果不需要了,又得重新删除。另外,如果打包策略不够明智的话,可能会打包出多份重复的代码。

正确引入方式

最简单靠谱的方式是用库变成Vue的原型对象的属性。下面,我来演示如何将Moment库引入:

entry.js

import moment from 'moment';
Object.defineProperty(Vue.prototype, '$moment', { value: moment });

由于所有的组件都会继承Vue原型对象上的方法,因此这些方法在任何组件文件中都能通过this.$moment访问到:

MyNewComponent.vue

export default {
created() {
console.log('The time is ' . this.$moment().format("HH:mm"));
}
}

我们来仔细看一下其中的原理。

Object.defineProperty

通常我们会如下设置对象属性:

Vue.prototype.$moment = moment;

你也可以这么做,但是Object.defineProperty允许我们用属性描述器来定义我们的属性。我们可以定义该属性是否可写,可枚举,可配置。

一般情况下,我们不需要用那么复杂的方式来赋值属性。但这里用它有个好处:用属性描述器定义的属性是默认只读的。

这能防止那些脑子不清醒的开发者(很可能是你哦~~)犯下一些低级错误:

this.$http = 'Assign some random thing to the instance method';
this.$http.get('/'); // TypeError: this.$http.get is not a function

Object.defineProperty能保护引入的库不被重新赋值,如果你尝试重写,程序会抛出“TypeError: Cannot assign to read only property”的错误。

$

可能你注意到,我们用“$”开头的属性来存放引入的库。当然,你应该记得还有其他的一些属性也是这样的,比如$refs, $on, $mount。

这种做法不是强制的,这个前缀就是为了提醒某些昏昏沉沉的开发者(怎么又是你?!),这些属性是公有的,你可以在任何地方使用。反之,某些属性只能在Vue内部使用。

作为一门以原型为基本的语言,JavaScript中并没有真正的类,所以也就没有所谓的公有,私有变量,或者静态方法。上面这种约定,我觉得是种不错的选择。

this

现在你能用this.$libraryName的方式来访问你需要的库了。但,你得保证this的指向。如果你在回调函数中使用this,通常这个this不再指向Vue实例。

箭头函数是解决这个问题的好方法。

this.$http.get('/').then(res => {
if (res.status !== 200) {
this.$http.get('/') // etc
// Only works in a fat arrow callback.
}
});

写成插件

如果你在项目的很多地方都用了某个库,或者你希望全局可用,你可以构建自己的Vue插件。

插件能化繁为简,能让你像下面这样很简单地引入自己想要的库:

import MyLibraryPlugin from 'my-library-plugin';
Vue.use(MyLibraryPlugin);

就像Vue Route,Vuex等插件一样,我们的库仅仅需要两行,就能在任何地方使用了。

如何写插件

首先,创建一个文件。本例中,我将引入一个Axios库的插件。我们就把这个文件命名为axios.js吧。

最关键的地方在于,我们需要暴露一个将Vue构造器作为第一个参数的install方法。

axios.js

export default {
install: function(Vue) {
// Do stuff
}
}

  

然后我们可以用之前的方式将库添加到Vue的原型对象上:

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插件的方法名也是这个。然后,让我们利用第二个参数来修改它。

axios.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..');
}
})

当然上面,我们可以直接在Object.defineProperty的中将name属性写死成$axios。也可以在install方法中引入多个需要的库。

转载:https://blog.csdn.net/fen747042796/article/details/70660419

必备技能六、Vue框架引入JS库的正确姿势的更多相关文章

  1. Vue框架引入JS库的正确姿势

    参考自:https://mp.weixin.qq.com/s?src=3&timestamp=1527154113&ver=1&signature=tWGeTa86gyK*RL ...

  2. 050——VUE中使用js库控制vue过渡动作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 在Vue将第三方JS库封装为组件使用

    第三方JS库地址:https://github.com/inorganik/CountUp.js 使用NPM进行安装: npm install --save countup 根据官方回答,CountU ...

  4. uni-app 引入本地iconfont的正确姿势以及阿里图标引入

    1.引入本地iconfont iconfont文件里面包含 iconfont.ttf.iconfont.css, 将 iconfont.tt64文件转位 base64.推荐转换工具地址:https:/ ...

  5. 必备技能六、Vue中实现全局方法

    现实背景:很多时候我们会在全局调用一些方法. 实现方式两种:官网的实现use方法,然后你也可以用野路子直接在Vue.prototype上面定义. 先说野路子,因为其实野路子就是最根本的实现方式,官方的 ...

  6. vue中引入js,然后new js里的方法

    阿里云Web播放器Web端使用SDK说明:https://help.aliyun.com/document_detail/51991.html?spm=5176.11065259.1996646101 ...

  7. vue项目 引入js文件

    例如我想将laydate.js引到vue项目中 将用到的js文件放到static文件夹内,在项目的根目录下的index.html内引入 <script src="static/js/l ...

  8. Vue全局引入JS的方法

    两种情况: 1. js为ES5的写法时,如下(自定义的my.js): function fun(){ console.log('hello'); } Vue中的全局引入方式为,在index.html中 ...

  9. composer安装第三方的库packagist.org(laravel框架引入第三方库)

    建立composer.json composer require phpoffice/phpexcel //安装一个excel扩展库 composer require gregwar/captcha ...

随机推荐

  1. [LC] 159. Longest Substring with At Most Two Distinct Characters

    Given a string s , find the length of the longest substring t  that contains at most 2 distinct char ...

  2. 用户增删改查 django生命周期 数据库操作

    一 django生命周期 1 浏览器输入一个请求(get/post)2 响应到django程序中3 执行到url,url通过请求的地址匹配到不同的视图函数4 执行对应的视图函数,此过程可以查询数据库, ...

  3. 1022 D进制的A+B (20 分)

    题目:1022 D进制的A+B (20 分) 思路: 首先根据A.B的取值范围,可知A+B不过2^31,所以转换成进制数时的最长长度为31. 转换成进制的数存进数组,然后反向输出. 要注意和为0的情况 ...

  4. git获取公钥和私钥以及常用的命令

    Git简单生成公钥和私钥的方法 Git安装完之后,需做最后一步配置.打开git bash,分别执行以下两句命令 git config --global user.name “用户名” git conf ...

  5. Skipping MapperFactoryBean with name 'sysUserMapper' and 'com.buding.system.mapper.SysUserMapper' mapperInterface. Bean already defined with the same name!

    前几天整体看了一下SpringBoot的简介,觉得看不如自己动手做,于是动手做一个简单的用户管理.启动的时候遇到了Skipping MapperFactoryBean with name 'sysUs ...

  6. 使用zxing生成和解析二维码

    二维码: 是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的: 在代码编制上巧妙的利用构成计算机内部逻辑基础的0和1比特流的概念,使用若干个与二进制相对应的几何 ...

  7. 吴裕雄--天生自然 R语言开发学习:广义线性模型

    #----------------------------------------------# # R in Action (2nd ed): Chapter 13 # # Generalized ...

  8. 配置Maven本地仓库

    以本机为例: 系统:Windows 开发工具:IDEA 如果想在dos窗口输mvn命令,需配置环境变量. 1. 在D盘新建repository文件夹,该目录用作maven的本地库. 2. 打开D:\P ...

  9. bzoj1432_[ZJOI2009]Function

    题目描述 有n 个连续函数fi (x),其中1 ≤ i ≤ n.对于任何两个函数fi (x) 和fj (x),(i != j),恰好存在一个x 使得fi (x) = fj (x),并且存在无穷多的x ...

  10. 奇葩念头:微信能取代WP应用吗

         墙倒众人推,原本是再平常不过的事,但每次发生都显得特别凄凉--就和楼市买房买涨不买跌一样,在互联网行业,用户数量越多的产品或服务,就会越受到行业和大众青睐.而越是小众的产品或服务,虽然是要走 ...