本文详细解析在Vue项目中引入第三方JS库的常见误区与最佳实践。通过对比全局变量挂载和局部引入的缺陷,重点介绍了利用Vue原型对象及插件机制(install方法)实现全局可用的正确方式,并演示了如何配置自定义属性名以解决命名冲突问题。
本文主要介绍在Vue框架中如何正确引入JS库,分享相关实践供参考学习。
常见错误引入方式
错误示范
全局变量法
最不靠谱的方式是将导入的库挂载到全局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库引入:
import moment from 'moment';
Object.definePrototype(Vue.prototype, '$moment', { value: moment });
Object.definePrototype 语法参见 MDN
由于所有组件都会继承Vue原型对象上的方法,因此这些方法在任何组件文件中都能通过this.$moment访问到:
// MyNewComponent.vue
export default {
created() {
console.log('The time is ' . this.$moment().format("HH:mm"));
}
}
使用 Object.defineProperty 定义对象属性,如果不在属性描述器中额外说明,则该属性默认为只读,从而保护引入的库不被重新赋值。
Vue插件化封装实践
写成插件
如果你在项目的多处使用某个库,或者希望其全局可用,可以构建自己的Vue插件。
插件能化繁为简,让你像下面这样简单地引入想要的库:
import MyLibraryPlugin from 'my-library-plugin';
Vue.use(MyLibraryPlugin);
就像Vue Route、Vuex等插件一样,我们的库仅需两行代码,即可在任何地方使用。
如何写插件
首先,创建一个文件。本例中,我将引入一个Axios库的插件,将该文件命名为axios.js。
最关键的地方在于,我们需要暴露一个install方法,将Vue构造器作为第一个参数。
// 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方法中引入多个需要的库。
总结
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对本站的支持