如何在 React、Riot 2.0 中使用 jQuery 插件

How to use jQuery plugins in React, Riot 2.0

我有一个 jQuery 繁重的应用程序,我在其中有很多 jQuery 插件,我想重组应用程序,所以我正在寻找不同的框架,比如 Angular、React、Riot 2.0 等

我喜欢 React 和 Riot,但我不知道如何将典型的 jQuery 应用程序(对 DOM 的不限流量访问)带入这个新的虚拟世界 DOM,等等

其中一些组件很复杂,我不想将它们全部重写到 "VDOM way" 中并造成另一个噩梦。

有人对此有答案吗?也许 jQuery 插件繁重的应用程序不适合,或者有没有办法 split/combine 和 UI 同时使用,或者 React/Riot 之类的框架可以很好地与 jQuery?

在 angular 中,可能有人已经重新创建了您想要的东西。您使用指令来实现可重用组件或包装现有组件。包装插件:

  • 在 link 中初始化(基于隔离范围)
  • 使用 scope.$watch(key, fn) 在发生变化时更新插件
  • 在插件回调中使用 scope.$apply() 告诉 angular 某些事情可能已经改变,更新任何相关的双向绑定,并调用任何相关的表达式绑定
  • 使用scope.$on('$destroy', fn)清理
  • 参见 ui-bootstrap 示例和 api 设计。

这同样适用于 React,但组件而不是指令。

  • 在 componentDidMount 中初始化(基于 props)
  • 更新componentDidUpdate中的插件(基于props)
  • 在插件回调中调用 this.props.onWhatever
  • 在 componentWillUnmount 中清理
  • 参见 react-bootstrap 示例和 api 设计。

而且我认为 Riot 与此无关。

这是用 React 组件包装 DOM 库的优秀指南:

https://github.com/rpflorence/react-training/blob/gh-pages/lessons/05-wrapping-dom-libs.md

Riot 2.0 仅在 4 天前发布,因此显然还没有任何扩展。

但是在 React 社区中使用自定义标签或 "components" 将基于 jQuery 的应用程序转换为 "modern world" 是一个很好的选择。

自定义标记可让您构建可重用的客户端代码片段,而无需 jQuery 选择器和操作方法。而 HTML 和 JS 在文件系统上的分布较少。

而 Riot 2.0 旨在与 jQuery 一起玩。您可以自由使用 jQuery 插件和自定义标签,这样您就可以迭代地转换您的应用程序 - 如果您愿意,可以一次转换一个标签。

要在 Riot 2.0 自定义标签中使用 jQuery 访问 DOM,您可以像这样使用 mount 事件和 this.root :

<my-custom-tag>
  <h3>Riot.JS Custom tag + jQuery plugin</h3>
  <p>My paragraph</p>
  <script>
    this.on('mount', function() {
      var $node = $(this.root);
      $node.find('p').html('updated by jQuery!');
    });
  </script>
</my-custom-tag>

我不确定它是 "best practice" 但它适用于 Riot 2.0.10(2015 年 2 月 19 日)。

如果自定义标签包含form或input元素,就更简单了,可以通过名字访问属性,不需要mount事件:

<my-custom-form>
  <input name="email" type="text">
  <script>
    $(this.email).val('mike@worldcompany.com');
  </script>
</my-custom-form>

我们遇到了同样的问题,即将一个相当大的基于全球 jquery 的管理前端转变为可嵌套的无冲突组件 - w.o 为我们的合作伙伴付出了大量培训 - 所以 riotjs 对我们来说是理想的选择.

我们同意以下解决方案(另请参阅 Michael Rambeau 的回答)并且到目前为止对此非常满意。

通过一个 mixin,我们给我们所有的 riot 组件标签这个函数:

var ComponentTagsMixin = {
  init: function () {
     //<other stuff needed in all tags>

     // jquery local to the vDom of this instance:
     $: function(selector) {
            // you could fail here if (!this.isMounted)                                        
            return $(this.root.querySelector(selector))           
     }          
}

```

因此,在标签中,您只需将 $ 变成 this.$。 例如,jquery 可嵌套:

$('#nestable').nestable(....)
$('.dd').nestable('expandAll');

进入

this.$('#nestable').nestable(....)
this.$('.dd').nestable('expandAll');

现在这允许在同一页面中包含许多这样的组件 w/o 冲突以及本地命名空间和数据。

正如已经指出的,这只有在安装标签后才能访问,所以 运行 你的东西在 this.on('mount'...) 块中。

这与遗留 jquery 库一起工作得非常好,因为它们通常允许用户重新定义他们的 Dom 选择器以实现页面内的双重 运行 能力。