2019.05.24 17:53

使用任何Javascript库与Vue.js

Lodash,Moment,Axios,Async ......这些是你想要在许多Vue.js应用程序中使用的有用的Javascript库。

但随着项目的增长,您将把代码分成单个文件组件和模块文件。您还可能希望在不同的环境中运行应用程序以允许服务器呈现。

除非您找到一种简单而强大的方法在您的组件和模块文件中包含这些Javascript库,否则它们将会非常麻烦!

如何不在 Vue.js项目中包含库

全局变量

向项目添加库的简单方法是通过将其附加到window对象来使其成为全局变量:

entry.js

window._ = require('lodash');

MyComponent.vue

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

对窗口变量的情况很长,但是,特别是对于这个讨论,它们不适用于服务器渲染。当应用程序在服务器上运行时,window对象将是未定义的,因此尝试访问属性将以错误结束。

导入每个文件

另一种二流方法是将库导入每个文件:

MyComponent.vue

import _ from 'lodash';

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

这可行,但它不是很干,它基本上只是一个痛苦:你必须记住将它导入每个文件,如果你停止在该文件中使用它,再次删除它。如果您没有正确设置构建工具,您最终可能会在构建中使用同一个库的多个副本。

一个更好的方法

在Vue项目中使用Javascript库的最干净,最健壮的方法是将其代理到Vue原型对象的属性。让我们这样做,将Moment日期和时间库添加到我们的项目中:

entry.js

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

由于所有组件都从Vue原型对象继承其方法,因此这将使Moment在任何和所有组件中自动可用,没有全局变量或任何手动导入。它可以在任何实例/组件中从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我们可以用描述符定义我们的属性。描述符允许我们设置一些低级细节,例如我们的属性是否可写,以及它是否在for循环枚举期间显示等等。

在我们的日常Javascript中,我们通常不会为此烦恼,因为99%的时间我们不需要具有属性赋值的详细程度。但是在这里它给了我们一个明显的优势:默认情况下,使用描述符创建的属性是只读的

这意味着一些缺乏咖啡的开发人员(可能是你)将无法在组件中做出像这样愚蠢的事情并打破一切:

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

相反,我们的只读实例方法保护我们的库,如果您尝试覆盖它,您将得到“TypeError:无法分配给只读属性”。


$

您会注意到我们将库代理为前缀为美元符号“$”的属性名称。你可能也看到了其他属性等方法$refs$on$mount等它有这个前缀了。

虽然不是必需的,但是前缀被添加到属性中以提醒缺乏咖啡的开发人员(您再次),这是一个您可以使用的公共API属性或方法,不像实例的其他属性可能仅适用于Vue的内部使用。

作为基于原型的语言,Javascript中没有(真正的)类,因此它没有“私有”和“公共”变量或“静态”方法。这个惯例是一个温和的替代品,我认为值得遵循。

这个

您还会注意到使用您使用的库this.libraryName可能并不令人惊讶,因为它现在是一个实例方法。

但是,这样做的一个结果是,与全局变量不同,您必须确保在使用库时处于正确的范围内。在内部回调方法中,您无法访问this您的库所驻留的内容。

胖箭头回调是一个很好的解决方案,以确保您保持在正确的范围:

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 Router,Vuex和其他使用的插件一样Vue.use

写一个插件

首先,为您的插件创建一个文件。在这个例子中,我将创建一个插件,将Axios添加到您的所有Vue实例和组件中,因此我将调用文件axios.js

要理解的主要内容是插件必须公开一个install方法,该方法将Vue构造函数作为第一个参数:

axios.js

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

现在我们可以使用我们的previos方法将库添加到原型对象:

axios.js

import axios from 'axios';

export default {
  install: function(Vue,) {
    Object.defineProperty(Vue.prototype, '$http', { value: axios });
  }
}

use我们现在需要将实例方法添加到项目中。例如,我们现在可以像这样轻松地添加Axios库:

entry.js

import AxiosPlugin from './axios.js';
Vue.use(AxiosPlugin);

new Vue({
  created() {
    console.log(this.$http ? 'Axios works!' : 'Uh oh..');
  }
})

额外:插件可选参数

您的插件安装方法可以使用可选参数。一些开发人员可能不喜欢调用他们的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..');
  }
})


DIY表情

(添加http或https协议)

提交评论

留言区 1