$ cnpm install @uyun/core
集成了 widget
常用方法
部件中定时任务
import { createReactWidget } from '@uyun/core'
function Demo () {
return (
<TimerProvider delay={100} immediately={} fn={() => {}} >
demo
</TimerProvider>
)
}
创建一个 Widget React 组件
export default createReactWidget({
baseRouterPath: props => `uyun-widget-template-demo-${props.url}`,
routes: [],
globalProviders: [],
providers: [],
rootComponent: Demo
})
部件路由上下文第一段 (产品名称-组件名称-自定义名称)
/** createReactWidgetConfig 中 baseRouterPath */
type baseRouterPath: string | () => string
import { createReactWidget } from '@uyun/core'
export default createReactWidget({
baseRouterPath: 'cmdb-demo-list',
rootComponent: Demo
})
class Demo extends React.Component {
render () {
// 获取 baseRouterPath
console.log(this.props.baseRouterPath)
return <div>demo</div>
}
}
路由配置, 配置对象与react-router 中 Route 参数一样
interface RouteProps {
location?: H.Location;
component?: React.ComponentType<RouteComponentProps<any>> | React.ComponentType<any>;
render?: ((props: RouteComponentProps<any>) => React.ReactNode);
children?: ((props: RouteChildrenProps<any>) => React.ReactNode) | React.ReactNode;
path?: string | string[];
exact?: boolean;
sensitive?: boolean;
strict?: boolean;
routes: Array<RouteProps>
}
/** createReactWidgetConfig 中 routes */
type routes: Array<RouteProps>
配置路由
import { createReactWidget } from '@uyun/core'
export default createReactWidget({
baseRouterPath: 'cmdb-demo-list',
routes: [
{
path: 'list',
component: List,
routes: [
{
path: 'details',
component: Details
}
]
}
],
rootComponent: Demo
})
访问 List 组件, 打开浏览器 http://localhost:8080/cmdb-demo-list/list
class Demo extends React.Component {
render () {
// 获取 baseRouterPath
return (
<div>
<h1>demo</h1>
{ this.props.renderRoutes(data) /* List 组件显示的位置 ***/ }
</div>
)
}
}
访问 Details 组件, 打开浏览器 http://localhost:8080/cmdb-demo-list/list/details
注意, 如果
path: 'details'
修改成path: '/details'
地址就变成绝对路径,http://localhost:8080/cmdb-demo-list/details
class List extends React.Component {
render () {
// 获取 baseRouterPath
return (
<div>
<h1>List</h1>
{ this.props.renderRoutes(data) /* Details 组件显示的位置 ***/ }
</div>
)
}
}
function Details () {
return <h1>Details</h1>
}
providers是一个可以使用React的上下文机制将存储(或其他东西)传递给子组件的组件。如果您不希望明确地传递多个组件层,那么这非常有用
inject 用来去最近的上下文取对象。它是等于 useContext(InjecterContextType).injecter.get(provide) | this.context.injecter.get(provide)
globalProviders 是在应用助理屏根组件上注册的 react Context 上下文
, 所有widget中的组件和store,都可以通过inject(provide)
相互访问
providers 是在widget自身根组件上注册的 react Context 上下文
, 只能在自身widget中的组件和store,去通过inject(provide)
相互访问
最近的
商店如果没有就一直 往上找
注意 globalProviders 中对象 provide (产品名称-组件名称-注册名字-自定义名称)
interface Providers = {
provide: any,
useClass?: Class,
useValue?: any,
useFactory?: Function,
des: Array<provide>
}
const globalProviders: Array<Providers>
const providers: Array<Providers>
配置 providers
import { createReactWidget, inject } from '@uyun/core'
class Store {
// 在组件中获取
@inject('theme') theme
}
const theme = { color: 'red' }
export default createReactWidget ({
baseRouterPath: 'cmdb-demo-list',
globalProviders: [
{
provide: 'cmdb-demo-list-data',
useValue: { data: 'hello 我是cmdb部件数据' }
},
],
providers: [
Store, /** Store 与 { provide: Store, useClass: Store } 同样的效果 */
{ provide: 'theme', useValue: theme },
{
provide: 'newStore',
useFactory: (store, theme) => new Store(theme),
des: [Store, 'theme']
}
],
rootComponent: List
})
在组件中使用
import { inject, useInject } from '@uyun/core'
class List extends React.Component {
@inject(Store) store
@inject('theme') theme
render () {
console.log(this.store)
return <Message />
}
}
function Message () {
const newStore = useInject('newStore')
console.log(newStore)
return <h1>Message</h1>
}
在Store中获取
import { inject } from '@uyun/core'
class Store {
// 在组件中获取
@inject('theme') theme
}
Notes:
createReactWidget
上下文中只会实例化一次,是在第一次 @inject(provide)
实例化的,然后每次都返回第一次实例化的对象createReactWidget
上下文中只会执行一次,是在第一次 @inject(provide)
执行的,然后每次都返回第一次函数执行的返回结果@inject(provide)
直接返回./locale.json
[
["key", "en_US", "zh_CN"],
["i18n-demo", "i18n", "国际化{age}"]
]
import { createReactWidget, I18n } from '@uyun/core'
import locale from './locale.json'
export const DemoWidget = createReactWidget({
globalProviders: [],
providers: [
// 配置私有store
I18n(locale, 'i18n', { /*http://npm.uyundev.cn/package/@uyun/everest-i18n**/ }),
],
rootComponent: Demo
})
使用
import { I18n } from '@uyun/core'
class Demo extends React.Component {
render () {
return (
<div>
<I18n.Text name="i18n-demo" age={111} />
{
/** 或者 **/
// @inject('i18n') i18n
// return <div>{ this.i18n("i18n-demo", {age: 1111}) }</div>
}
<Message />
</div>
)
}
}
function Message {
return <I18n.Text name="i18n-demo" age={111} />
/** 或者 **/
// const i18n = useInject('i18n')
// return <div>{ i18n("i18n-demo", {age: 1111}) }</div>
}
部件widget根组件
import { createReactWidget } from '@uyun/core'
class Demo extends React.Component {}
export default createReactWidget({
rootComponent: Demo
})
createModule 与 createVueWidget 功能与配置是一样的, createVueWidget 是继承与 createModule, 唯一的区别是 createModule 是没有 globalProviders
提供商的
作用: 你可以用它来封装一个业务模块去给他人使用
import { createModule } from '@uyun/core'
export default createModule({
baseRouterPath: `uyun-widget-template-demo-${props.url}`,
routes: [],
providers: [],
rootComponent: Demo
})
或者
import { Module } from '@uyun/core'
@Module({
baseRouterPath: `uyun-widget-template-demo-${props.url}`,
routes: [],
providers: []
})
export default class Demo extends React.Component {
}
Providers 是基于 React.createContext
实现的
Providers 组件是一个可以使用React的上下文机制将存储(或其他东西)传递给子组件的组件。如果您不希望明确地传递多个组件层,那么这非常有用
inject 用来去最近的上下文取对象。它是等于 useContext(InjecterContextType).injecter.get(provide) | this.context.injecter.get(provide)
(
<Providers
value={/* 等于 `createReactWidget createModule` 参数对象中的 `providers` **/}
>
// etc
</Providers>
)
import { Provider } from '@uyun/core'
import { observable } from 'mobx'
import { observer } from 'mobx-react'
class Store {
@observable num = 0
onSum = () => {
this.num ++
}
}
export default class Demo extends React.Component {
render () {
<Providers
value={[
{ provide: 'store', useClass: Store },
{ provide: 'theme', useValue: 'blue' }
]}
>
<Message />
<List />
</Providers>
}
}
在 组件
中获取 Providers
提供的对象
@observer
class List extends React.Component {
@inject('store') store
render () {
return <h1 onClick={this.store.onSum}>+</h1>
}
}
function Message {
const store = useInject('store')
return <div>{ store.num }</div>
}
或者使用 context 获取
import { InjecterContextType, InjecterContextTypes } from '@uyun/core'
@observer
class List extends React.Component {
static contextType = InjecterContextType
// static contextTypes = InjecterContextTypes 老的方式
render () {
const store = this.context.injecter.get('store')
return <h1 onClick={store.onSum}>+</h1>
}
}
在 Store
中获取 Providers
提供的对象
class Store {
@inject('theme') theme // 在store 获取商店的东西
@observable num = 0
onSum = () => {
console.log(this.theme)
this.num ++
}
}
Notes:
createReactWidget
上下文中只会实例化一次,是在第一次 @inject(provide)
实例化的,然后每次都返回第一次实例化的对象createReactWidget
上下文中只会执行一次,是在第一次 @inject(provide)
执行的,然后每次都返回第一次函数执行的返回结果@inject(provide)
直接返回创建一个vue 部件
export default createVueWidget({
rootComponent: App
})
其他内容后续增加, 保证配置基本与createReactWidget 一样
创建数据模型
import { createRxSchema, types } from '@uyun/core'
export const basisSchema = createRxSchema('basisSchema', {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
if (['success', 'warning', 'danger'].indexOf(value) === -1) {
throw new Error(`必须匹配 'success', 'warning', 'danger' 字符串中的一个`)
}
}
},
// 别名
propG: {
type: Number,
alias: 'propGAlias'
},
// 自定义结构
propH: {
type: Number,
getValue (value) {
return value * 2
}
}
})
const schema = basisSchema.validate({
propA: 1111,
propB: 333,
propC: '123',
propF: 'warning',
propG: 123,
propH: 666
})
console.log('Test', schema.value)
const chema = createRxSchema('Test2', {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
basisSchema: basisSchema,
basisSchemaArray: arrayOf(basisSchema)
})
chema.validate({
propA: 1111,
propB: 333,
basisSchema: {
propC: '123',
propF: 'warning'
},
basisSchemaArray: [{
propA: 1111,
propB: 333,
propC: '123',
propF: 'warning',
propG: 123,
propH: 666
},
{
propA: 1111,
propB: 333,
propC: '123',
propF: 'warning',
propG: 123,
propH: 666
}]
})
console.log(chema.value)
const chema3 = createRxSchema('Test3', {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
chema: arrayOf(chema)
})
chema3.validate({
chema: [{
propA: '1111',
propB: 333,
basisSchemaArray: [{
propA: 1111,
propB: 333,
propC: '123',
propF: 'warning',
propG: 123,
propH: 666
},
{
propA: 1111,
propB: 333,
propC: '123',
propF: 'warning',
propG: 123,
propH: 666
}]
}]
})
console.log('Test', chema3.value)
const basisSubjectSchema = basisSchema.createSubjectValidate()
basisSubjectSchema({
propA: 1111,
propB: 333,
propC: '123',
propF: 'warning',
propG: 123,
propH: 666
})
.subscribe(value => {
console.log('basisSubjectSchema', value)
})
basisSubjectSchema({
propA: 1111,
propB: 333,
propC: '123',
propF: 'warningx',
propG: 123,
propH: 666
})
const schema2 = createRxSchema('schema2', {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
})
const schema1 = createRxSchema('schema1', schema2, {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propC: Number,
// 多个可能的类型
propD: [String, Number],
})
// 验证
schema1.validator({
propA: 1111,
propB: 333,
propC: [],
propD: 333,
})
// 打印错误
schema1.logError()
console.log(schema1.value)
// @SkipSelf()
Copyright 2013 - present © cnpmjs.org