如何在React应用程序中初始化Bootstrap 4 popover



我不知道如何让popovers工作,如下所示:https://getbootstrap.com/docs/4.0/components/popovers/.

文档谈到popover支持是一个插件,也需要工具提示插件,所以我修改了webpack.config.js添加了这两个,现在看起来是这样的:

...
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default'],
Popover: 'exports-loader?Popover!bootstrap/js/dist/popover',
Tooltip: "exports-loader?Tooltip!bootstrap/js/dist/tooltip",
}),
...

我还没有找到任何关于Bootstrap插件概念的文档,所以上面两行PopoverTooltip来自搜索,不确定它们是否正确。

文件说明:

Popover是出于性能原因而选择加入的,因此您必须自己初始化它们。

但我不知道该怎么做。

文档显示了以下用于初始化popover的代码:

$(function () {
$('.example-popover').popover({
container: 'body'
})
})

但我不明白这应该做什么——我的元素上没有popover()函数可以调用——这是怎么回事?

以下是我的代码中尝试使用popover的一个示例:

render(){
...
<span>
Summary info
<button 
type="button" className="btn btn-sm" 
data-toggle="popover" title="Popover title" 
data-content="The popover Content"
>
Show popover
</button>        
</span>
...
}

如何使Bootstrap V4 popover功能在React应用程序的上下文中工作?具体来说,我如何"初始化"popover?


我使用的是Typescript 2.3、React 16、Bootstrap 4(没有React引导程序风格的库)。

注意,react bootstrap只支持bootstrap V3,reactstrap太不稳定,我不想使用它

当我最初试图让Bootstrap弹出窗口工作时,我(无疑仍然)有很多上下文理解缺失。

第一件事是:Bootstrap"Popover"插件实际上是一个JQuery插件。我想所有的引导插件都是这样工作的,但我找不到任何关于这方面的引导入门文档。这就解释了popover()方法及其来源。

下面,我概述了在React/Typescript/Webpack堆栈的上下文中使popover工作所需的内容。

在下文中,我假设您已经根据Bootstrap文档配置了Webpack。

你不需要原始问题中的"Popover"one_answers"Tooltip"行,假设你是webpack.config.js,这是根据Bootstrap文档,并且你的代码库中有import 'bootstrap';


您需要添加JQuery类型,如果还没有,这样您就可以导入$并拥有正确的类型:

"devDependencies": {
"@types/jquery": "3.2.15",
...
}
"dependencies": {
"bootstrap": "4.0.0-beta",
"jquery": "3.2.1",
"popper.js": "1.11.0",
...
}

根据Netanel Basal的这篇博客文章,您必须扩展JQuery的类型定义,以便它了解Popover插件。在typings.d.ts中(或在项目中有意义的地方),添加以下内容:

// support for JQuery popover plugin from Bootstrap 4
interface JQuery {
popover() : any;
}

请注意,定义是让popover以静态类型的方式从代码中工作所需的最低限度。它需要扩展以支持传递参数,以便您可以自定义popover行为。或者,您可以使用data属性来传递这些参数,如doco中的Live示例所示。

在React组件本身中,声明问题的popover的JSX似乎工作得很好。

要"初始化"popover,根据问题,您需要导入JQuery标识符,然后调用popover方法:

...
const $ = require('jquery'); 
...
componentDidMount(): void{
$('[data-toggle="popover"]').popover();
}
...

"导入表单"对我不起作用,所以我不得不require()它。

该代码在整个HTML页面中搜索具有data-toggle="popover"的元素,并返回一个JQuery对象,该对象具有可以调用的popover()方法(这是整个JQuery插件部分)。

一旦在具有popover属性的元素上调用了popover(),单击该元素时将自动显示popover(无需管理特定于popover的React状态)。


编辑

如上所示,在整个HTML页面上搜索所有弹出窗口不是一个好主意。在多个React组件中有多个弹出窗口的复杂页面中,每个组件最终都会覆盖彼此的popover()选项。

这是我目前针对可重复使用的React引导程序Popover组件的解决方案。

扩展Typescript打字以了解更多popover选项:

// support for JQuery popover plugin from Bootstrap 4
interface JQuery {
popover(options?: PopoverOptions) : any;
}
interface PopoverOptions {
container?: string | Element | boolean;
content?: string | Element | Function;
placement?: "auto" | "top" | "bottom" | "left" | "right" | Function;
title?: string | Element | Function;
...
}

创建类似Popover.tsx的:

export interface PopoverProps {
popoverTitle: string | Element | Function;
popoverContent: string | Element | Function;
}
export class Popover
extends PureComponent<PopoverProps, object> {
selfRef: HTMLSpanElement;
componentDidMount(): void{
$(this.selfRef).popover({
container: this.selfRef,
placement: "auto",
title: this.props.popoverTitle,
content: this.props.popoverContent,
});
}
render(){
return <span
ref={(ref)=>{if(ref) this.selfRef = ref}} 
data-toggle="popover"
>
{this.props.children}
</span>;
}
}

然后使用弹出窗口,如:

<Popover 
popoverTitle="The popover title"
popoverContent="The popover content"
>
<span>
Click this to show popover.
</span>
</Popover>

注意与动态内容的Popover定位相关的问题:Bootstrap 4-自动Popover重新定位是如何工作的?

文档试图说的是,仅仅拥有一个datatoggle="popover"的元素不会创建popover的实例。您需要使用javascript调用来显式初始化它。

在非反应环境中,您可以将其添加到文档准备功能中,例如这个

$(document).ready(function () {
$('.myPopoverItem').popover({
html: true
, trigger: 'focus'
, content: $.proxy(this.getContent, this)
});
}

不过,在React中,您需要将其添加到对象的构造函数代码中,以便在render()之后调用它(元素必须在页面上)。

我发现了这个潜在的答案:React"渲染后";密码它建议使用componentDidMount函数,您可以在其中调用popover初始化。

所以在你的React对象中,你会有一个函数

componentDidMount() {
$('.myPopoverItem').popover({
html: true
, trigger: 'focus'
, content: $.proxy(this.getContent, this)
});
}

最新更新