Beatle ·
Beatle是一套轻量级前端框架,借助React、Redux实现应用界面构建流程。
特性
- 简单化Api,快速掌握开发技巧,只需掌握React框架。
- 轻量概念,React-like-Model 构建数据模型(state存储数据状态,setState变更数据状态)
- MVVM实现VM模块自动化,即自动化绑定数据和视图逻辑。
- 应用中间件,数据通信过程的设置中间件,方便应用接入外部扩展。
- 由简入繁,多应用嵌套构建复杂应用,方便管理应用之间的通用服务通信 以及 数据通信。
启动和打包
honeypack start
honeypack build -c webpack.build.js
Beatle-API
Class: Beatle
- Beatle支持多应用场景,每个应用都需要通过New Beatle来生成实例。
const app = new Beatle(options);
app.run(options);
以下出现的 app
皆为 Beatle
的实例, 在初始化传入的配置options
:
属性 | 描述 | 默认 |
---|
name String | 应用实例名 | N/A |
store Object | 应用数据中心的初始化数据 | {} |
middlewares Array | 应用数据处理中间件,通过中间件可以变更数据结果 | [] |
ajax Object | 应用接口请求对象初始化依赖的配置项 | {} |
root DOM | 应用唯一挂载的DOM树节点 | document.body |
base String | 应用启动,路由访问的根路径 | / |
query Object | 设置路由全局参数 | N/A |
autoLoadModel Boolean | 是否自动加载数据模型,如果开启则加载assets/auto_models.js 文件 | true |
autoLoadRoute Boolean | 是否自动加载路由,如果开启则加载assets/auto_routes.js 文件 | false |
models Object︱Function︱Context | 需要注册的数据模型 | N/A |
routes Object︱Function︱Context | 需要注册的路由 | N/A |
routeType Boolean | 路由处理器类型,主要分为hash还是原生 | browserHistory , 参考:browserHistory 和 hashHistory |
subApp Boolean | 是否为子应用 | false |
应用实例app
有相应的方法来完成应用构建,包括注册数据模型
, 注册路由
, 应用启动
等。
Beatle.getApp(appName)
- return <
Beatle
> 返回指定的Beatle实例
多应用场景下通过选择指定应用实例,从而完成单个应用的构建。
class Root extends React.Component{
render() {
return <h5>Hello Worlld {this.props.location.query.appName}!</h5>
}
}
const appA = new Beatle({
name: 'appA',
...
});
appA.route('/', Root, {query: {appName: 'A'}});
appA.run();
const appB = new Beatle({
name: 'appB',
...
});
appB.route('/', Root, {query: {appName: 'B'}});
appB.run();
Beatle.getApp('appA');
Beatle.createModel(model, resource)
在Beatle中数据模型Model
是指一类数据的集合,一个数据模型包含了数据基础结构
, 改变数据的行为方法
以及跨数据模型的监听
。
resource是接口调用的封装对象,一般来说,我们会愿意把接口单独定义到业务逻辑之外的对象中。
const model = {
displayName: 'test',
state: {
value: 1
},
actions: {
set: (nextState, payload) => {
nextState.value = payload.arguments[0];
return nextState;
}
}
}
const app = new Beatle({name: 'main'});
app.model(model);
const modelInst = app.model('test')
console.log('value :' + modelInst.state.value);
modelInst.set(2);
console.log('value :' + modelInst.state.value);
class Root extends React.Component{
render() {
return <span>component props value :{this.props.test.value}</span>
}
}
const ConnectRoot = Beatle.connect(['test'], Root);
app.route('/', ConnectRoot);
modelInst.set(3);
app.run();
class Model extends Beatle.BaseModel {
static displayName: 'test';
state = {
value: 1
}
set(v) {
return this.setState({
value: (nextState, payload) => {
return payload.argumens[0];
}
}, v);
}
}
const model = {
displayName: 'test',
state: {
value: 1
},
actions: {
set: {
exec: (v) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(v)
}, 100);
})
},
callback: (nextState, payload) => {
nextState.value = payload.data;
return nextState;
}
}
}
}
class Model extends Beatle.BaseModel {
static displayName: 'test';
state = {
value: 1
}
set(v) {
return this.setState({
value: {
exec: (v) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(v)
}, 100);
})
},
callback: (nextState, payload) => {
return payload.data;
}
}
}, v);
}
}
class Model extends Beatle.BaseModel {
static displayName: 'test';
state = {
value: 1
}
set(v) {
return this.setState({
value: {
exec: {
url: 'http://api.github.com',
method: 'get',
data: {id: v}
}
callback: (nextState, payload) => {
return payload.data;
}
}
}, v);
}
}
- 回到主题,createModel的目的就是抽象exec,独立维护在model之外
const resource = {
set: {
url: 'http://api.github.com',
method: 'get',
data: {id: v}
}
}
@Beatle.createMode(resource)
class Model extends Beatle.BaseModel {
static displayName: 'test';
state = {
value: 1
}
set(v) {
return this.setState({
value: {
exec: 'set'
callback: (nextState, payload) => {
return payload.data;
}
}
}, v);
}
}
这样下来,所有的接口都单独定义在resource对象下,对于大的应用会存在很多resource。对于resource我们可以在业务之外单独做调试,这样服务分层的管理,代码更加健壮和清晰。
Model的使用下面API有更详细介绍
Beatle的其他静态属性
属性 | 描述 |
---|
Ajax | 接口调用Ajax类,可单独初始化ajax实例 |
Poller | 轮询调用Poller类 |
Link | 封装了react-router 的Link, 带上全局base和query |
ReduxSeed | 数据驱动机制可单独使用,不依赖Beatle,包含完整的数据模型以及Redux处理一整套机制 |
下面我们来看下Beatle实例app
有哪些方法和对象可以使用。
app.ajax
app
是有new Beatle
初始化的实例,在初始化同时时,内部还会初始化2个实例:ajax
和 seed
, 分别为Ajax的实例 和 ReduxSeed的实例。
ajax可以设置实例级别的事件监听,分别通过以下方法来设置
方法 | 参数类型 | 描述 |
---|
setHeader(headers) | headers Object | 设置headers 配置 |
beforeRequest(fn) | fn Function | 请求之前beforeRequest 的处理,此时可以更改接口配置或者更多 |
beforeResponse(fn) | fn Function | 接口结果预处理beforeResponse , |
afterResponse(fn) | fn Function | 接口结果后处理afterResponse |
set(name[, value]) | name String , value any | 前4个方法都可以通过set方法来设置,简化操作 |
const app = new Beatle();
app.ajax.beforeRequest(
function (ajaxOptions) {
ajaxOptions.data = {};
return Promise.resolve({
})
}
);
app.ajax.beoreResponse(
function(response, ajaxOptions, request){
return response.json();
}
)
app.ajax.afterResponse(
function (result, ajaxOptions, request) {
if(result instanceof Error){
}else if(result.code !== 'SUCCESS'){
}else{
return result.data;
}
}
);
接口请求配置dataType用于声明如何解析接口数据
app.seed
seed实例是ReduxSeed实例,app.getStore()
实际上是通过seed实例中获取store对象。
app实例开放API
方法 | 参数类型 | 描述 |
---|
getStore() Object | N/A | 获取redux状态容器 |
getRoutes() Array | N/A | 获取react-router的路由配置 |
use(middleware) | middleware Function | 注册中间件,中间件是在处理处理过程中变更数据结构或者做一些必要的监控 |
getResolvePath(routeConfig) String | routeConfig Object | 根据路由配置获取真实的路径 |
route(path[, component]) | path String︱Array︱Object︱Context , component ReactComponent | 只有一个参数,此时为字符串则查找路由配置,否则是批量注册路由配置;2个参数未显示注册单个路由配置 |
routesFactory(routes, option) | routes Array︱Object︱Context , option Object | 批量注册路由,可以传入option做更多处理 |
model(Model) | Model Object | 注册数据模型 |
connect(bindings, component[, context, flattern]) | bindings String︱Object︱Array , component ReactComponent , context Object , flattern Boolean | 设置视图, binding指定注入数据模型或者根据数据模型注入数据和方法 |
service(providers, isGlobal) | providers `<Object | Function |
observer(obj) | obj `<Array | Promise |
view(Selector, component, providers) | Selector Object , component: ReactComponent , providers: `Array<Object | Function |
run([rootDom, basePath]) | rootDom Object , basePath String | 启动应用 |
当app为Beatle的主应用时,可以通过Beatle.xxx直接调用app对应的方法。
所有app实例的开放api都可以通过Beatle进行访问
const mainApp = new Beatle({});
const subApp = new Beatle({subApp: true});
在new Beatle的配置项options中有subApp属性来声明是否为子应用,否则就是主应用。
在Beatle支持多应用的场景下,主应用必须只为一个,其他均为子应用,否则将会出现预想不到的问题。
app.getStore()
在new Beatle产生实例app
时,应用内部会创建一个单一的数据共享对象,后面统一称之为状态容器store
, 如果你熟悉Redux
,当前store
也可以在Redux
技术体系下正常工作。
const app = new Beatle();
const store = app.getStore();
store.substribe(function () {
console.log('current state ==>', sotre.getState());
});
app.model(model)
应用中注入数据模型Model,注册功能后,数据模型的将交给store
进行托管。
app.connect('user', ReactComponent);
app.model({
displayName: 'user',
...
});
app.connect('user', ReactComponent);
app.connect(modelList, component, flattern)
- modelList <
String|Object|Array
> 指定需要绑定的数据模型实例名 - component <
ReactComponent
> 指定组件来绑定 - flattern <
boolean
> 是否平铺属性 - return <
ReactComponent
> 返回新的React组件
import React from 'react';
import Beatle from 'beatle';
const app = new Beatle();
const Model = {
displayName: 'user',
store: {
nickname: 'anonymous'
},
actions: {
login: {
callback: (nextStore, payload) => {
nextStore.nickname = payload.arguments[0];
}
}
}
}
class SayHello extends React.Component {
componentDidMount() {
this.props.user.login('Trump');
}
render() {
return 'hello ' + this.props.user.nickname;
}
};
app.model(Model);
const component = app.connect(['user'], SayHello);
app.route('/', component);
app.run();
app.service(providers, isGlobal)
- providers <
Function|Object|Array
> 注入的全局的服务JS类 - isGlobal <
Boolean
> 是否是全局的(跨所有应用)
const app = new Beatle({name: 'main'});
function A() {
return {
v: 1
}
};
const B = ['a', function(a) {
return {
v: a.v + 1
}
}];
class C{
static contextTypes: {
b: React.PropTypes.object.isRequired
}
get v() {
return this.context.b.v + 1;
}
}
function D(c) {
return c.v + 1;
}
D.$inject = ['c'];
A.displayName = 'a';
const a = app.service('a');
console.log(a.v);
app.service({
b: B,
c: C,
d: D
});
const b = app.service('b');
console.log(a.v);
const d = app.service('d');
console.log(d.v);
app.observer(obj)
- obj <
Array|Promise|Observable
> 指定需要转为序列的数据 - return <
Observable
> 返回可订阅序列
const stream = app.observer([1, 2, 3]);
stream.subscribe(v => {
console.log(v + ', ');
});
const stream = app.observer(Promise.resolve('123'));
stream.subscribe(v => {
console.log(v);
});
const promise = new Promise(resolve => {
setTimeout(() => {
resolve({name: 123});
}, 1000);
});
ReactDOM.render( => (<div>Hi, {app.observer(promise).render(d => d.name)}</div>), document.body);
Observable序列是rxjs中的概念,适用于把异步数据按时间轴转换为有顺序的序列数据,方便操作。
app.view(Selector, component, providers)
- Selector <
Object
> 指定需要绑定的数据选择器 - component <
ReactComponent
> 指定组件来绑定 - providers <
Array<Object|Function|Array>
> 注入其他的服务,使得组件通过this.context可以访问到。 - return <
ReactComponent
> 返回新的React组件
class UserModel extends Beatle.BaseModel {
state = {
profile: {
name: 'Guest'
}
}
login(name) {
return this.setState({
profile: {
exec: fetch('https://api.github.com/users/' + name),
callback: (nextProps, payload) => {
return payload.data;
}
}
})
}
}
class Selector extends Beatlep.BaseSelector{
get inputs() {
return (state, dispatch) => {
return {
profile: state.user.profile
}
}
}
initialize() {
this.getModel('user').login('baqian');
}
}
class Root extends React.Component{
static propTypes = {
profile: React.Proptypes.object
}
static contextTypes = {
test: React.Proptypes.object
}
render() {
return (<div>{this.context.test.title} {this.props.profile.login}!</div>)
}
}
Root = Beatlep.view(Selector, Root, {
test: function() {
return {
title: 'Hello'
}
}
});
数据选择器是一个新的概念,在复杂的场景,一个组件往往会调用多个model,通过数据选择器来统一管理model,提高代码可读性
这是action数据处理的模板,以上的UserModel通过crud重新处理如下:
class UserModel extends Beatle.BaseModel {
state = {
profile: {
name: 'Guest'
}
}
login(name) {
return this.setState({
profile: {
exec: fetch('https://api.github.com/users/' + name),
callback: Beatlep.crud.get
}
})
}
}
crud的全部接口
crud = {
item: {},
itemsEntry: {
data: [],
loading: false,
total: 0,
pageSize: 10,
page: 1
},
get,
create,
update,
query,
reset
}
举个例子,通过crud创建一个UserModel,能节省大量代码
class UserModel extends BaseModel {
static displayName = 'user';
state = {
user: crud.item,
usersEntry: crud.itemsEntry
}
id = 'id';
get(id) {
return this.setState({
user: {
exec,
callback: crud.get
}
}, {id: id});
}
delete(id) {
return this.setState({
usersEntry: {
exec,
callback: crud.delete
}
}, {id: id});
}
update(user) {
return this.setState({
usersEntry: {
exec,
callback: crud.update
}
}, user);
}
create(user) {
return this.setState({
usersEntry: {
exec,
callback: crud.create
}
}, user);
}
query(params) {
return this.setState({
usersEntry: {
exec,
callback: crud.query
}
}, params);
}
}
app.route([path, routes])
- path <
String
>, 当存在path时,则是配置单个路由,此时routes应该为React组件或者Beatle子应用。 - routes <
ReactComponent|Beatle|ReactRouter
>, 不存在path时基于ReactRouter的路由的配置.
app.routes([
{
path: '/',
component: RootComponent,
childRoues: [
{
path: 'profile',
component: ProfileComponent
}
]
}, {
path: '*',
component: 404Component
}
])
- app.route(path, component)
app.route('/', RootComponent);
RootComponent.routeOptions = {
childRoues: [
{
path: 'profile',
component: ProfileComponent
}
]
}
app.route('/', RootComponent);
- app.route(path, subApp)
把子应用挂在主父级应用下,子应用的路由会继承下来,但需要追加根路径来访问。
const subApp = new Beatle({subApp: true});
subApp.route('/', subAppRootComponent);
subApp.route('/profile', subAppProfileComponent);
app.route('/subApp', subApp);
app.run();
app.run([root, base])
- root <
DOM
>, app最终需要挂载到真实的DOM节点下. - base <
string
>, app访问的路由,统一加上跟路由路径.
const app = new Beatle();
app.route('/', RootComponent);
app.route('/profile', ProfileComponent);
app.run(document.body, '/beatle');
Model
Model数据模型是一类数据的集合,包含了数据的初始化结构,以及改变这些数据的行为方法。
描述一个Model对象,需要具备以下数据结构:
属性 | 描述 | 默认值 |
---|
displayName | 实例名 | N/A |
store | 数据基础结构 | {} |
actions | 改变数据的行为方法 | N/A |
subscriptions | 跨数据模型的行为监听 | N/A |
const propTypes = React.PropTypes;
const modelShape = {
displayName: propTypes.string,
store: propTypes.object.isRequired,
actions: propTypes.object,
subscriptions: propTypes.object
}
const action = {
exec: propTypes.oneOfType([propTypes.object, propTypes.func]),
callback: propTypes.oneOfType([propTypes.object, propTypes.func]),
}
const action = {
callback: propTypes.func,
}
const subscriptions = {
`${modelName}/${actionName}/${status}: (nextStore, playload) => {
}
}
符合以上数据结构的Model可以通过app.model(Model)
注册到应用中。
何时使用Beatle.createModel(model, resource)
, 当你异步的action中exec需要单独维护到model外部时,通过Bealte.createModel组合进来,生成最终的Model
Model行为action的配置
属性 | 参数类型 | 描述 |
---|
exec | Object/Function | 异步行为的触发条件,Beatle内部通过exec来识别异步行为,当exec为接口配置,会转为一个接口调用函数,如果是函数则不用做变动 |
callback | Object/Function | 行为触发成功后进入,在同步行为时,callback只能为函数,异步行为时callback一般来说是对象,有3个回调函数,start , success 和 error |
reducer | Object/Function | 同上callback |
subscriptions | Object | 跨数据模型监听行为,从而变更自身数据 |
externalReducers | Object | 同上subscriptions |
行为调用的处理逻辑
- 行为方法触发时传入的参数会放到payload.arguments中
- 判断行为是否存在
exec
属性,则会当做异步行为进行调用 - 触发行为时,会先执行
start
回调, - 判断exec为函数时,执行函数返回非promise值,会直接进入到
success
回调,否则在promise的接收值时进入到success
回调,在拒绝值时进入到error
回调 - 如果exec为接口配置,则通过应用内部的ajax实例来发起接口调用,在接口成功并接收值时进入到
success
回调,在拒绝值时进入到error
回调 - 同步行为时直接进入到callback回调
callback: function (nextStore, payload){
}
属性 | 描述 |
---|
type | 当前行为处理状态,不同行为状态会进入到不同的回调中 |
store | 当前model的基础数据 |
arguments | 行为调用时传入的参数 |
data | 异步行为调用后,接收的数据 |
message | 当异步行为调用失败后,会存在错误信息 |
- 基于异步action调用以及跨数据模型监听行为的实现举个例子:
const UserModel = {
displayName: 'user',
store: {
profile: {
pending: true,
nickname: 'anonymous'
}
},
actions: {
login: {
callback: {
start: (nextStore, payload) => {
nextStore.profile = payload.store;
},
success: (nextStore, payload) => {
nextStore.profile = {
pending: false,
nickname: payload.data.nickname
};
}
}
}
}
};
const UserResource = {
login: {
url: '/login',
method: 'GET'
}
}
const AccountModel = {
dispayName: 'account',
store: {
nickname: ''
},
subscriptions: {
'user.login.success': (nextStore, user_login_payload) => {
nextStore.nickname = user_login_payload.data.nickname;
}
}
}
app.model(Beatle.createModel(UserModel, UserResource));
app.model(AccountModel);
Resource
Resource是接口配置对象,结合Beatle.createModel来使用
Beatle.createModel(model, resource)
时其内部将做如下处理
- 遍历resource对象,拿到每个属性和值
- 在model.actions中找到对应属性的行为,把值赋给行为的exec对象,找不到行为则,则丢弃掉
const userModel = {
...
actions: {
login: {...}
}
};
const userResource = {
login: {
url: '/login',
method: 'GET',
params: {
username: 'default username'
}
},
getUserList: {
url: '/user/list',
method: 'GET',
params: {
pageSize: 10,
pageNo: 1
}
}
};
Beatle.createModel(userModel, userResource);
Class: ReduxSeed
import {ReduxSeed} from 'beatle';
const seed = new ReduxSeed({...});
- new ReduxSeed传入options配置项:
属性 | 描述 | 默认 |
---|
name String | ReduxSeed支持多实例,初始化一个seed实例需要指定实例名称 | main |
ajax Object | ajax实例 | N/A |
initialState Object | store的基础结构 | {} |
middlewares Array | 应用数据处理中间件,通过中间件可以变更数据结果 | [] |
Models Object | 注册多个数据模型 | {} |
ReduxSeed静态属性
名称 | 参数类型 | 描述 |
---|
createModel | model Object , resource Object | 组合resource到model中,等同于Beatle.createModel |
getRedux | name String | 获取指定的seed实例 |
seed实例方法
名称 | 参数类型 | 描述 |
---|
reducerBuilder | model Object , resource Object | 组合resource到model中,等同于Beatle.createModel |
register | model Object , resource Object | 注册一个model到seed实例 |
getActions | modelName String | 获取指定的seed实例下的model的行为,为空时获取所有行为 |
Class: Ajax
- 通过new Ajax产生ajax实例,传入的options配置项,设置实例级的全局配置:
名称 | 描述 |
---|
headers | 全局的Header配置, 默认取值window.ajaxHeader |
delimeter | 请求url默认支持插值替换,delimeter 是插值变量的语法 |
normalize | 请求url插值替换,是否都走data属性, 默认为false |
beforeRequest(ajaxOptions) | 请求之前的钩子函数 |
beforeResponse(response, ajaxOptions, xhr) | 请求成功后处理response对象的钩子函数 |
afterResponse(result, ajaxOptions, xhr) | 请求成功后处理接口结果数据的钩子函数 |
origin | 配置请求地址前缀 |
- Ajax的全局配置分为2种:全局(所有实例有效) 和 实例级,支持的值如上
import {Ajax} from 'Beatle';
Ajax.headers = {
csrfToken: '...'
}
Ajax.normalize = false;
const ajax = new Ajax({
normalize: true
});
ajax.get('...');
ajax.set('headers', {});
ajax.get('...')
实例级设置可以参考ajax实例设置实例级别的全局监听。
Ajax.request(ajaxOptions)
Ajax静态方法,其内部会初始化一个ajax实例,并调用ajax.request来执行
ajax实例方法
名称 | 参数类型 | 描述 |
---|
request | options Object | 接口请求调用,所有其他方式的请求最终都会走request来执行 |
get | path String , data Object/null , options Object/Function , dataType String/Function | get请求 |
post | path String , data Object/null , options Object/Function , dataType String/Function | post请求 |
put | path String , data Object/null , options Object/Function , dataType String/Function | put请求 |
delete | path String , data Object/null , options Object/Function , dataType String/Function | delete请求 |
patch | path String , data Object/null , options Object/Function , dataType String/Function | patch请求 |
ajax.request(options)
- options <
Object
> 接口请求配置 - return <
Promise|null
> 配置中有callback则不会返回内容,否则会返回调用的promise
属性 | 参数类型 | 描述 |
---|
url | String | 请求地址 |
method | String | 请求方法 |
headers | Object | 请求头部 |
mode | String | 请求模式,参考 cors , no-cors , same-origin , 默认no-cors |
credentials | String | 请求凭证, 参考omit , same-origin , include , 有凭证才带cookie,否则不带cookie |
cache | String | 缓存模式,参考 default , reload , no-cache , 默认default |
callback | Function | 回调处理函数,当存在callback时不会返回promise实例 |
dataType | String | 接口返回结果对数据解析处理基于dataType类型来决定,默认为json解析 |
取值 | 描述 |
---|
arrayBuffer | 解析为ArrayBuffer 的promise对象 |
blob | 解析为Blob 的promise对象, URL.createObjectURL(Blob) 转为base64 |
formData | 解析为FormData 的promise对象 |
json | 解析为Json 的promise对象 |
text | 解析为USVString 的promise对象 |
ajax.get(path[, data, options, dataType])
- path <
String
> 请求地址 - data <
Object|null
> 请求参数 - options <
Object|Function
> 当为函数式,则是callback回调,否则为请求配置信息 - dataType <
String|Function
> 请求数据进行数据解析类型,默认是json解析, 当dataType为函数时,则是callback回调,此时options必须为请求配置信息 - return <
Promise|null
> 配置中有callback则不会返回内容,否则会返回调用的promise
其他接口方法形式一致,包括post
、 delete
、put
和 patch
Class: Poller
通过new Poller产生poller实例,传入配置项options:
属性 | 描述 | 默认 |
---|
delay Number | 每次轮询需要等待是时长 | 5000 |
smart Boolean | 智能识别,当某个请求超过等待时长,会等待请求结束后才会轮询下个动作 | false |
action Function | 每个轮询动作触发时,调用action函数 | N/A |
catchError Function | 轮询中每个动作调用失败时都会进入到错误回调 | N/A |
import Beatle, {Poller} from 'beatle';
const poller = new Pooler({
action: () => {
return Beatle.Ajax.request({url: '', method: 'get'});
}
});
poller.subscribe((err, res) => {
});
poller实例方法
方法 | 参数类型 | 描述 |
---|
then | success Function , error Function | 注册回调队列,每次轮询产生结果时触发 |
subscribe | watcher Function | 开始订阅,同上注册回调队列,并且启动轮询 |
unsubscribe | N/A | 取消订阅,并关闭轮询 |
remove | N/A | 同上 |
start | N/A | 开始轮询 |
stop | N/A | 停止轮询 |
tick | N/A | 等当前产生结果后跳到下一个轮询 |
Class: Link
是React组件,封装了React Router中Link组件。用法同Link组件一致,所做的事情就是当app实例中设置了路由的统一前缀以及全局的query参数, 通过Link跳转时会自动带上。
const app = new Beatle({
base: '/example',
query: {debug: true}
});
app.route('/', (props) => {
return (<Link to="/">回到首页</Link>);
});
app.run();