将ES6插件扩展到jQuery原型上

11

由于我不懂如何将我的经典jQuery(v2)插件转换成带有模块和类的ES6格式,因此我需要一些帮助。

在ECMAScript 5中,我们可以像这样将jQuery插件附加到jQuery原型中:

app.js - 通过HTML <script> 标签加载了jQuery

$.fn.myPlugin = function() {};
$('div').myPlugin();

它有效!在ES6中,我会这样写:

myPlugin.es6:

import $ from 'jquery';

export default class myPlugin extends $ {
 // Could i use constructor() method ???
}

app.es6 :

import $ from 'jquery';
import myPlugin from 'myPlugin.es6';

$('div').myPlugin();

最后,它不起作用了...
我进行了搜索,没有人提出过这个问题。
我使用Babel将ES6转译为ES5。


1
"extends $" 没有意义。你认为它的意思和 "$.extend({…})" 一样吗? - Bergi
1
如果你正在寻找新的Javascript功能,那么你可能不需要jQuery。有很多独立的UI库不需要jQuery。此外,还有一个特殊的网站http://youmightnotneedjquery.com/,它解释了如何从jQuery切换到本地功能。 - just-boris
2个回答

15

$.fn只是一个对象,将新属性添加到$的原型中并没有任何魔法。因此,代码$.fn.myPlugin = function() {}等同于$.prototype.myPlugin = function() {}

$.fn === $.prototype; // true

要以标准方式在$对象上调用函数($('div').func()),需要将该函数添加到$对象中。

在您的ES6代码中没有添加它。

因此,

import $ from 'jquery';

export default class myPlugin extends $ {
 // Could i use constructor() method ???
}

意思是(几乎)

var myPlugin = function() {};

myPlugin.prototype = Object.create($.prototype);

return { default: myPlugin };
我不确定你是否应该扩展$.fn,但也许你需要它。And with

import $ from 'jquery';
import myPlugin from 'myPlugin.es6';

它的意思是

var $ = require('jquery');
var myPlugin = require('myPlugin'); // a reference to the 'export.default' object from 'myPlugin.es6'
因此,$.fn 对象和 myPlugin 函数之间没有联系。
您应该在某个地方创建连接。它可以在一个特殊的模块中,比如plugins,您将会把所有所需的插件注入到 $.fn 对象中:
import $ from 'jquery';
import plugin1 from 'plugin1.es6'; // should contain 'name'
import plugin2 from 'plugin2.es6';
...
import plugin10 from 'plugin10.es6';

[plugin1, plugin2, ..., plugin10].forEach(plugin => $.fn[plugin.name] = plugin);

或者你可以在'myPlugin.es6'中向导出的对象添加一个'initialize'方法,并在第一次使用之前调用它:init($) { $.fn.myPlugin = myPlugin; }

等等。


如果一个函数不是匿名的,它就有一个名称属性。所以你的解决方案看起来非常好!我在 Rollup 沙盒 上试用了一下。 - just-boris
最终我在我的代码中做了几乎相同的事情。按名称导出:export const myexport = { init: function ($) { /* code here */ } } 然后 import { myexport } from './myexport.es6'; myexport.init($). - Neil Monroe

7
在ES6中,您像以前一样在jQuery原型上安装新方法。这对于它们没有改变。您不会对jQuery进行子类化,因此使用或没有意义。
// myPlugin.es6:
import $ from 'jquery';

$.fn.myPlugin = function() {
    …
};

// app.es6:
import $ from 'jquery';
import 'myPlugin.es6';

$('div').myPlugin();

用这种方法,你必须在插件(myPlugin.es6)的package.json文件中将jquery依赖项标记为“peer dependency”吗?否则,你如何确保你和你的插件使用者都导入相同的jQuery $对象呢? - tonix
@tonix 是的,如果它是一个独立的库,那就有道理了。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接