ExtReact 产品的文档与其他 Sencha 产品的文档有所不同。以下部分描述了除另有说明为 ExtReact
特有的所有产品的文档。
许多类在使用配置对象创建(实例化)类时都有快捷名称。快捷名称称为 别名
(如果类扩展了 Ext.Component,则称为 xtype
)。别名/xtype 列在适用类的类名旁边,以供快速参考。
ExtReact 组件类在 API 类文档的顶部显著位置列出可配置的名称,后跟完全限定的类名。
框架类或其成员可以指定为 private
或 protected
。否则,类/成员为 public
。Public
、protected
和 private
是访问描述符,用于传达类或类成员应如何以及何时使用。
Public 类和类成员可供任何其他类或应用程序代码使用,并且在主要产品版本中可以作为稳定和持久的依赖项。公共类和成员可以通过子类安全地扩展。
Protected 类成员是稳定的 public
成员,旨在由所有者类或其子类使用。受保护的成员可以通过子类安全地扩展。
Private 类和类成员在框架内部使用,不 предназначен для 应用开发者使用。私有类和成员可能会在任何时候更改或从框架中省略,恕不另行通知,并且不应在应用程序逻辑中依赖它们。
ExtReact 组件类将配置选项显示为 props
ExtReact 组件类不将属性列为专用成员类型,而是列为 read only
props
static
标签。*请参阅下面的静态。下面是一个示例类成员,我们可以对其进行剖析,以显示类成员的语法(在本例中为从 Ext.button.Button 类查看的 lookupComponent 方法)。
让我们看一下成员行的每个部分
lookupComponent
)( item )
)Ext.Component
)。对于不返回除 undefined
之外的任何内容的方法,可以省略此项,或者可以显示为由正斜杠 /
分隔的多个可能值,表示返回的内容可能取决于方法调用的结果(即,如果 get 方法调用成功,方法可能返回 Component,如果失败,则返回 false
,这将显示为 Ext.Component/Boolean
)。PROTECTED
- 请参阅下面的标志部分)Ext.container.Container
)。如果成员源自当前类,则源类将显示为蓝色链接;如果成员从祖先类或混合类继承,则显示为灰色链接。view source
)item : Object
)。undefined
之外的值,“返回值”部分将注释返回的类或对象类型以及描述(示例中为 Ext.Component
)Available since 3.4.0
- 未在示例中描述),就在成员描述之后Defaults to: false
)API 文档使用许多标志来进一步沟通类成员的功能和意图。标签可以用文本标签、缩写或图标表示。
所有 ExtReact props 都是 bindable
,除非被装饰为 immutable
不可变的 ExtReact props 在实例化组件时不能用作可配置的 prop
classInstance.method1().method2().etc();
false
,则标记为可阻止的事件将不会触发- 表示框架类
- Singleton 框架类。*有关更多信息,请参阅 singleton 标志
- 组件类型的框架类(Ext JS 框架中扩展 Ext.Component 的任何类)
- 表示类、成员或指南在当前查看的版本中是新的
- 表示类型为 config
的类成员
或者在 ExtReact 组件类的情况下,这表示类型为 prop
的成员
- 表示类型为 property
的类成员
- 表示类型为 method
的类成员
- 表示类型为 event
的类成员
- 表示类型为 theme variable
的类成员
- 表示类型为 theme mixin
的类成员
- 表示类、成员或指南在当前查看的版本中是新的
在 API 文档页面上的类名正下方是一行按钮,对应于当前类拥有的成员类型。每个按钮显示按类型划分的成员计数(此计数在应用过滤器后会更新)。单击按钮将导航到该成员部分。将鼠标悬停在成员类型按钮上将显示该类型的所有成员的弹出菜单,以进行快速导航。
与类配置选项相关的 Getter 和 Setter 方法将显示在方法部分以及 API 文档和成员类型菜单的配置部分中,就在它们所使用的配置下方。Getter 和 Setter 方法文档将在配置行中找到,以便于参考。
ExtReact 组件类不会将 Getter/Setter 方法提升到 prop 中。所有方法都将在 Methods
部分中描述
您的页面历史记录保存在本地存储中,并显示在顶部标题栏正下方(使用可用的实际空间)。默认情况下,显示的唯一搜索结果是与您当前查看的产品/版本匹配的页面。您可以通过单击历史记录栏右侧的 按钮并选择“全部”单选选项来扩展显示的内容。这将显示所有产品/版本的所有最近页面历史记录栏中。
在历史记录配置菜单中,您还将看到最近页面访问的列表。结果按“当前产品/版本”和“全部”单选选项过滤。单击 按钮将清除历史记录栏以及本地存储中保存的历史记录。
如果在历史记录配置菜单中选择“全部”,则将启用“在历史记录栏中显示产品详细信息”复选框选项。选中后,每个历史页面的产品/版本将与历史记录栏中的页面名称一起显示。将光标悬停在历史记录栏中的页面名称上也会将产品/版本显示为工具提示。
可以使用页面顶部的搜索字段搜索 API 文档和指南。
在 API 文档页面上,还有一个过滤器输入字段,该字段使用过滤器字符串过滤成员行。除了按字符串过滤外,您还可以按访问级别、继承和只读过滤类成员。这是通过使用页面顶部的复选框完成的。
API 类导航树底部的复选框过滤类列表以包含或排除私有类。
单击空的搜索字段将显示您最近 10 次搜索,以便快速导航。
每个 API 文档页面(Javascript 原始页面除外)都有一个菜单视图,其中包含与该类相关的元数据。此元数据视图将具有以下一项或多项
Ext.button.Button
类具有 Ext.Button
的备用类名)。备用类名通常是为了向后兼容性而维护的。可运行的示例 (Fiddles) 默认在页面上展开。您可以使用代码块左上角的箭头单独折叠和展开示例代码块。您还可以使用页面右上角的切换按钮切换所有示例的折叠状态。切换所有状态将在页面加载之间记住。
类成员默认在页面上折叠。您可以使用成员行左侧的箭头图标或全局使用右上角的展开/折叠所有切换按钮来展开和折叠成员。
在较窄的屏幕或浏览器上查看文档将导致针对较小外形尺寸优化的视图。桌面视图和“移动”视图之间的主要区别在于
可以通过单击 API 文档页面顶部的类名来查看类源代码。可以通过单击成员行右侧的“查看源代码”链接来查看类成员的源代码。
本指南记录了将 Ext JS 组件添加到 React 应用程序所需的步骤。
* Java 要求仅适用于 Linux。如果未安装 Java,Java 会自动与 Windows 和 Mac OS 上的 ExtReact Webpack 插件捆绑在一起)
如果您从头开始,我们建议克隆 ext-react monorepo 并复制其中一个样板以创建一个新的应用程序
例如,要使用现代样板
git clone https://github.com/sencha/ext-react.git
cp -r ext-react/packages/ext-react-modern-boilerplate /path/to/new/app
要使用经典样板,请将最后一行替换为
cp -r ext-react/packages/ext-react-classic-boilerplate /path/to/new/app
然后,按照样板的 README.md 中的说明设置和运行您的新应用程序。
如果您需要将 Ext JS 组件添加到现有的 React 应用程序,请按照以下步骤操作
Sencha 提供了一组软件包,可帮助将 Ext JS 集成到 React 中。通过从 npm 安装它们,将它们添加到您的 React 应用程序中
npm install --save @sencha/ext-react
npm install --save @sencha/ext @sencha/ext-modern @sencha/ext-modern-theme-material
npm install --save-dev @sencha/ext-react-webpack-plugin @sencha/ext-react-babel-plugin html-webpack-plugin
ExtReact 需要一个 webpack 插件来捆绑和优化您在应用程序中使用的 ExtReact 组件。按如下所示将其添加到您的 webpack 配置中
// import the plugins
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtReactWebpackPlugin = require('@sencha/ext-react-webpack-plugin');
...
// then, in your webpack config options:
return {
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
hash: true
}),
new ExtWebpackPlugin({
framework: 'react',
port: port,
emit: true,
browser: browserprofile,
genProdData,
watch: watchprofile,
profile: buildprofile,
environment: buildenvironment,
verbose: buildverbose,
theme: 'theme-material',
packages: []
}),
]
}
注意:如果您使用 html-webpack-plugin
,请确保它在插件数组中位于 ExtReactWebpackPlugin
之前,以便 ext.js 和 ext.css 的标签包含在生成的 index.html 中。
如果使用 webpack-dev-server,请确保构建目录位于 contentBase
配置中。
contentBase: "./build"
如果 contentBase
设置为另一个目录,您可以将值更改为数组并添加“build”
contentBase: ["static", "./build"]
有关配置 ExtReactWebpackPlugin 的更多信息,请参阅 使用 Webpack 构建。
您还可以使用 ExtReact Modern Boilerplate 中的 webpack 配置文件 进行参考
为了构建您的应用程序,@sencha/ext-react-babel-plugin
必须包含在您的 babel 配置中,并且必须关闭 ES6 模块转译。这是一个 .babelrc 示例
{
"presets": [
[
"@babel/preset-env",
{
"modules": false
}
],
"@babel/preset-react"
],
"plugins": [
"react-hot-loader/babel",
"@sencha/ext-react-babel-plugin",
"@babel/plugin-transform-runtime",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-json-strings",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions"
],
"ignore": [
"build"
],
"env": {
"test": {
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-json-strings",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions"
]
}
}
}
注意:在 babel 中禁用 ES6 模块转译不会阻止您使用 import
语句。它只是将这些语句的处理推迟到 Webpack,这启用了 tree-shaking,并将有助于减少应用程序捆绑包的大小。
如果您使用 html-webpack-plugin
,则 ExtReactWebpackPlugin
生成的 JavaScript 和 CSS 资源将在构建时自动添加到您的 index.html 文件中。如果不是,您需要手动添加它们
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link href="ext-react/ext.css" rel="stylesheet">
...
</head>
<body>
...
<script type="text/javascript" src="ext-react/ext.js"></script>
...
</body>
ExtReact 组件需要 HTML5 doctype 声明才能正确显示。请确保此声明存在于您的 HTML 文档的顶部
<!doctype html>
ExtReact 需要 viewport meta 标签。这应添加到您的 index.html 中的 <head>
元素中。
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
@sencha/ext-react
软件包提供了一个 launch
函数,用于代替 ReactDOM.render()
launch(React.Element/Function)
要启动您的应用程序,请将以下内容添加到您的 index.js 文件(您的 webpack 入口点):当与 React v16 及更高版本一起使用时,开发人员需要在使用 Ext JS 组件之前在根目录添加一个名为 ExtReact 的新组件。最好的方法是在应用程序的入口点或启动方法中添加它,然后 ExtJS 组件可以在整个应用程序中的任何位置使用。
import { launch } from '@sencha/ext-react';
import { ExtReact } from '@sencha/ext-react'
import App from './App';
launch(<ExtReact><App/><ExtReact>);
launch 函数将指定的组件渲染到文档正文中。它还接受一个回调函数,该函数返回要渲染的组件
launch(() => {
// do some initialization before initial render
// ...
// return the component to be rendered
return <App/>;
})
launch
函数有两个用途
使用 launch
时,您不需要在 index.html
文件中单独的目标 <div id="root"/>
。如果您有一个,则应将其删除。上面的代码替换了启动 React 应用程序的典型代码,该代码通常类似于
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App/>, document.getElementById('root'));
如果您不需要创建全屏组件(例如,如果您将 ExtReact 组件与其他布局系统一起使用),您可以将 renderWhenReady
高阶组件应用于包含 ExtReact 元素的顶层组件,省略 launch 函数,并像 React 的惯例一样渲染到目标元素。如果您要构建基于 ExtReact 的组件库,并且不希望要求使用您的库的应用程序调用 launch
,则这尤其有用。
// App.js
import React, { Component } from 'react'
import { Panel } from '@sencha/ext-modern'
import { renderWhenReady } from '@sencha/ext-react'
import { ExtReact } from '@sencha/ext-react'
class App extends Component {
render() {
return (
<ExtReact>
<Panel title="ExtReact">Hello World!</Panel>
</ExtReact>
)
}
}
export default renderWhenReady(App);
// index.js
import ReactDOM from 'react-dom'
import App from './App'
import { render } from '@sencha/ext-react'
render(<App/>, document.getElementById('root'))
这是一个示例,该示例使用 launch 函数的回调参数来启用 react-hot-loader。回调传递一个 DOM 元素,该元素可以在调用 ReactDOM.render
时用作目标。
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import { launch } from '@sencha/ext-react';
import { ExtReact } from '@sencha/ext-react'
import App from './App'
let viewport;
const render = (Component, target) => {
ReactDOM.render(
<ExtReact>
<AppContainer>
<Component/>
</AppContainer>
</ExtReact>,
target
)
}
launch(target => render(App, viewport = target));
if (module.hot) {
module.hot.accept('./App', () => render(App, viewport));
}
fullscreen
配置大多数使用 ExtReact 的应用程序都是占据浏览器窗口完整高度和宽度的单页应用程序。为了实现这一点,您的应用程序中的根 ExtReact 组件应配置为将 fullscreen
prop 设置为 true
。例如
import { Container } from '@sencha/ext-modern';
export default function App() {
return (
<Container fullscreen>
...
</Container>
)
}
如果您使用 ESLint,请添加 Ext
作为允许的全局变量
"globals": {
"Ext": true
}
@sencha/ext-react
软件包使所有具有 xtype 的 Ext JS 类都可用作 React 组件。组件名称派生自 xtype 的大写驼峰形式。例如,Ext.grid.Grid
的 xtype 为 grid
,可以按如下方式导入
import { Grid } from '@sencha/ext-modern';
如果使用经典工具包,请从 @encha/ext-classic
导入。
import { Grid } from '@encha/ext-classic';
xtype 中的破折号将转换为下划线。例如,可以使用以下方式导入 "d3-heatmap" xtype
import { D3_HeatMap } from '@encha/ext-D3';
React props 将转换为 Ext JS configs。这是 Ext.grid.Grid
的典型用法
import React, { Component } from 'react';
import { Grid, Column } from '@encha/ext-modern';
export default class UsersGrid extends Component {
store = Ext.create('Ext.data.Store', {
fields: ['name', 'email'],
data: [
{ name: 'Tim Smith', email: '[email protected]' },
{ name: 'Jill Lindsey', email: '[email protected]' }
]
})
render() {
return (
<Grid title="Users" store={this.store}>
<Column text="Name" dataIndex="name"/>
<Column text="Email" dataIndex="email"/>
</Grid>
)
}
}
在上面的示例中,我们使用 props 设置 Grid 的 title
和 store
configs。我们使用 Column
子元素而不是使用 columns
prop 来设置 columns
config。两种形式都是可以接受的,但我们认为对于 React 开发人员来说,使用子元素更直观,因此这是您将在我们所有示例中看到的形式。ExtReact 自动知道将某些子元素(如 Column
)映射到父组件上的 configs。另一个例子是 Menu
<Button text="Options">
<Menu>
<MenuItem text="Options 1"/>
<MenuItem text="Options 2"/>
<MenuItem text="Options 3"/>
</Menu>
</Button>
也可以写成
<Button
text="Options"
menu={[
{ text: 'Option 1' },
{ text: 'Option 2' },
{ text: 'Option 3' }
]}
/>
任何以 "on" 开头后跟大写字母的 prop 都会自动转换为 Ext JS 事件监听器。由于 Ext JS 事件都是小写的,因此不会保留大小写。您可以随意使用驼峰式大小写,这在 React 中很常见。
import React, { Component } from 'react';
import { SliderField } from '@encha/ext-modern';
export default function MyComponent() {
return (
<SliderField
minValue={0}
maxValue={100}
onChange={(slider, value) => console.log(`Value set to ${value}`)}
/>
)
}
事件处理程序 props 也可以采用带有附加选项的对象
<Button
onPaint={{
single: true, // handler will only be called once
fn: () => {...}
}}
/>
您也可以使用 listeners 对象,这在传统的 Ext JS 中很常见
import React, { Component } from 'react';
import { SliderField } from '@encha/ext-modern';
export default function MyComponent() {
return (
<SliderField
minValue={0}
maxValue={100}
listeners={{
change: (slider, value) => console.log(`Value set to ${value}`)
}}
/>
)
}
rel
任何采用 Ext.Widget
子类的 prop 都可以替换为子元素。要使用子元素替换 prop,请将子元素的 rel
prop 设置为要替换的 prop 的名称。例如,Button 上的 menu
prop 可以替换为子 <Menu>
元素
<Button text="Theme">
<Menu rel="menu">
<MenuItem text="Triton"/>
<MenuItem text="iOS"/>
<MenuItem text="Material"/>
</Menu>
</Button>
defaults
使用 defaults prop 将一组 props 应用于所有子项。例如,对容器中的所有项目使用 flex: 1
<Container layout="vbox" defaults={{ flex: 1 }}>
<Container>Item</Container>
</Container>
ref
PropRefs 指向 Ext JS 组件实例
import React, { Component } from 'react';
import { SliderField } from '@encha/ext-modern';
export default class MyComponent {
render() {
return (
<SliderField
ref={ slider => this.slider = slider }
minValue={0}
maxValue={100}
onChange={() => this.onChange()}
/>
)
}
onChange() {
console.log('Slider value', this.slider.cmp.getValue()); // this.slider is an Ext.field.Slider
}
}
当 HTML 元素出现在 ExtReact 组件中时,它们会被包装在 Ext.Component
实例中。这允许 ExtReact 布局正确放置非 ExtReact 组件。例如...
<Panel layout="hbox">
<div>left</div>
<div>right</div>
</Panel>
... 将导致两个并排的 div。创建的组件结构等效于
Ext.create({
xtype: 'panel',
layout: 'hbox'
items: [{
xtype: 'component',
html: '<div>left</div>'
}, {
xtype: 'component',
html: '<div>right</div>'
}]
});
您可以使用 Ext.define 创建自己的 Ext JS 组件,就像在传统的 Ext JS 代码中一样。使用来自 @extjs/reactor
的 reactify
函数将您的 Ext JS 组件转换为 React 组件。例如
import { reactify } from '@sencha/ext-react';
const MyGrid = Ext.define('MyPackage.view.MyGrid', {
extend: 'Ext.grid.Grid',
...
})
export default reactify(MyGrid);