node package manager

cyra

Cyra

1. 如何开始

// main.js 
 
import { Cyra } from 'cyra';
 
import home from './view/home';
 
Cyra.initApp({
    root: 'body',    // 项目跟容器 
    default: 'home'  // 默认视图 
    routes: {        // 视图路由设置 
        home: home
    }
});
 
 
// home.js 
 
import { Page } from 'cyra';
 
class HomePage extends Page {
 
    // 定义了该函数后可以在进入视图时候改变页面title 
    title () {
        return 'HOME-TITLE';
    }
 
    // 以下函数如若未做任何事,可以省略不写 
    initialize (next) {
        next();
    }
 
    willAppear (next) {
        this.container.innerHTML = 'Hello World';
        next();
    }
 
    didAppear (next) {
        next();
    }
 
    willDisappear (next) {
        next();
    }
}
 
export default HomePage;

2. 基础思想

Cyra 设计三个简单的概念 PageRouteAppStorage 来帮助开发者处理复杂的视图切换逻辑、数据传递及视图生命周期管理。

在移动端 SPA 架构中,有以下几个重要的模块:

2.2 视图导航

所有导航动作被封装成在 Page.switchRoute 中,你可以在该方法中传递参数。

使用 Cyra 的单页应用可以在任何情况下刷新,Cyra 的框架设计会帮助你处理任何复杂的产品逻辑。

2.3 视图管理及内容布局

Cyra 会管理所有视图的生命周期,你可以轻松获悉每一个视图的执行阶段,并针对阶段进行操作。

Cyra 为每一个视图提供一个容器,用户可以在这个容器内自由发挥。

2.4 视图之间数据交互

数据传递在使用 Cyra 后会变得无比简单,我们提供 URL 传递及弱数据传递, 我们会在后面详细介绍。

2.5 服务器数据交互

关于服务器数据交互我们什么都不会做,完全由用户自由发挥。

2.6 兼容性

在 Cyra 的设计中,我们考虑了最大的兼容性,您可以通过配置使用 History API + 多页降级 作为路由方式,也可以使用 Hash 作为路由方式。

3. 视图生命周期

3.1 周期图说明

  1. 橙色的 entering,leaving 代表视图两大过程, 进入和离开。

  2. 最左边的 disappeared,appeared 代表两大状态,显示和隐藏。

  3. 其中 initialize, willAppear, didAppear, willDisappear 是用户可以自定义的钩子函数。

  4. appearing,disappearing是系统内部的函数过程,主要控制视图的隐藏和展现。如果想要在视图展现和隐藏时添加动画,可改写这两个方法的默认控制,请参见的转场动画。

3.2 生命周期

  1. 当 url 的 view 部分值(默认路径为 initApp 中传入的 default)匹配到相关的route,其对应的视图开始执行 entering 过程。

  2. 视图第一次执行 entering 过程时,依次执行 initialize, willAppear, (appearing), didAppear,若未定义则跳过,若在这其中某一步未调用 next() 也会中断执行。

  3. 当视图第二次执行 entering 过程,默认不再执行 initialize, willAppear,如若更改该行为请参见的如何控制重新加载。

  4. 当一个页面开始执行 entering 过程,则上一个页面开始执行 leaving 过程,即 willDisappear(disappearing)。

4. 使用指导

  • 提倡组件层面抽象,减少视图抽象。

  • 将视图渲染、数据获取等操作放到视图中最合适的阶段中。

  • 强数据传递尽量传递查询参数以保持视图独立,并保证 URL 不会太长。

  • 弱数据传递需要做好足够的判断,以保证逻辑的健壮。

API 文档

1. Cyra

Cyra.initApp (obj: InitAppObject): void

初始化 Cyra 环境,参数配置如下。

index: string (required) 指定默认路由

root: string (required) 容器 DOM id

routes: RouteData (required) 路由信息

mode: string (optional) 路由模式,默认为'history'(会自动降级为'multipage'),可选'hash'

appRoot: string (optional) 配合 History API 方式设置的项目虚拟目录,如'/resource/wa/oneyuan/'

paramPrefix: string (optional) 强数据在 URL 中的前缀,默认为''

alwaysReload: boolean (optional) 强制每次进入视图刷新,默认为false

dataSplit: (optional) 'hash' 模式下强数据传参格式

copyIndex: string (optional) copyIndex 在 URL 中的前缀,默认为cpx

animation: boolean (optional) 是否开启视图切换动画,默认为false

animationPrefix: string (optional) 视图切换动画所加载 CSS class 的前缀,默认为''

animationFunc: string (optional) 视图切换动画的timing-function,默认为''

switchDuration: number (optional) 视图切换动画持续时间,默认320毫秒

router: Router

获取 Cyra 上的 router 实例

2. Page

和 Page 相关的主要是一个视图的生命周期函数,以及一些简单的 helper 用来设置页面环境。

2.1 钩子函数

initialize (next: Function): void

视图所属容器显示之前(display: none)调用,需要执行next()进入下一个生命周期。

willAppear (next: Function): void

功能同initialize,遗留问题,建议视图展示之前的业务逻辑都写在willAppear中,和业务相关的独立逻辑建议拆分成 Page 的实例方法,而不要分散在initializewillAppear中。

didAppear (next: Function): void

视图所属容器显示之后(display: block)调用。

beforeEntering (next: Function): void

initializewillAppear在 Page 的shouldReload()返回false时不会再次执行,也就是第二次进入相同视图时不会重复执行,如果需要在页面展示前,无论shouldReload()返回结果如何都要执行,可以将代码写在下面的钩子函数中:

2.2 helper 函数

title (): string

用来设置视图的 title

shouldReload (previousPath: string): boolean

用来指定视图第二次之后进入时,是否执行initializewillAppear两个钩子函数。

switchRoute (path: string, data?: any, copyIndex?: number): void

指向Cyra.router.switchRoute,具体用法见对应词条。

popAndSwitchRoute (popValue: number, path: string, data?: any, copyIndex?: number): void

指向Cyra.router.popAndSwitchRoute,具体用法见对应词条。

reload (): void

重新加载当前视图,并且会执行initializewillAppear两个钩子函数。

prepareForSwitch (next: Function, toPath: string, destinationPagePerform: Function): void

在视图执行switchRoute()跳转前执行,弱数据实现方式,可以通过destinationPagePerform执行目标视图中的方法,toPath指示下一个视图的path。执行next()来完成跳转,否则停留在当前视图。

beforeLeaving (next: Function, cancel: Function, toPath: string): void

离开视图时执行,toPath指示即将进入的视图,执行next()进入下一视图,执行cancel()取消此次跳转。

2.3 helper 属性

context: ContextType

指向Cyra.router.context,详见对应词条。

3. Router

Router 主要负责页面间的跳转,初始化 Cyra 后,可以通过 Cyra.router 来完成视图见跳转相关操作。

switchRoute (path: string, data?: any, copyIndex?: number, isShadow: boolean = false): void

执行视图跳转,path为即将进入的视图的pathdata为传递的强数据,copyIndex指示 Mix 页的索引。为了方便,在 Page 中添加同名 helper,这样在视图中,只要执行this.switchRoute即可完成跳转,在非视图代码中,还是可以通过Cyra.router.switchRoute进行跳转。isShadow表示此次跳转是否使用replace模式,也就是用新的视图提前当前视图,从而将当前视图从 WebView 中清除(new in v2.1.2)。

注意:isShadow参数作用和popAndSwitchRoute作用类似,都是从 WebView 历史中清除1项或若干项,然后执行跳转;但popAndSwitchRoute不适用于项目第1个视图的此类跳转,因为先返回会使得退出当前项目,所以需要使用replace(对应 History API 中的replaceState和多页/Hash 中的window.location.replace)来替换当前历史。但isShadow无法清除多条历史记录,而后者可以。

popAndSwitchRoute (popValue: number, path: string, data?: any, copyIndex?: number): void

功能类似switchRoute,但会在跳转前先后退popValue个页面。

context: ContextType

当前程序中的环境变量信息。

  • rootContainer: HTMLElement:Cyra 根容器 DOM id;
  • useSwitch: boolean:指示当前一次跳转是否为执行switchRoute跳转;
  • currentRoute: Route:当前视图对应的Route对象;
  • currentPage: Page:当前视图所属的Page对象;
  • currentContainer: HTMLElement:当前展示视图的 DOM 容器;
  • previousPage: Page:上一视图所属的Page对象。

4. 视图切换动画

视图间切换动画需要按照如下步骤:

  1. Cyra.initApp中设置animationtrue
  2. 可添加以下可选参数进行动画配置,动画基于CSS Animation
  • switchDuration: number:指示动画切换持续时间,单位ms,默认320
  • animationPrefix: string:自定义动画keyframes前缀,默认''
  • animationFunc: string:自定义动画timing-function,默认为''
  1. 在页面中添加以下4个 CSS keyframes:
  • left-move-in:视图从屏幕左侧进入并显示的动画
  • left-move-out:视图向屏幕左侧滑出并隐藏的动画
  • right-move-in:视图从屏幕右侧进入并显示的动画
  • right-move-out:视图向屏幕右侧滑出并隐藏的动画
  1. 为了方便,给出一个示例:
<style>
@keyframes left-move-in {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
  }
}
 
@keyframes left-move-out {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-100%);
  }
}
 
@keyframes right-move-in {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0);
  }
}
 
@keyframes right-move-out {
  from {
    transform: translateX(0);
  }
  99% {
    transform: translateX(100%);
  }
  to {
    transform: translateX(-100%);
  }
}
</style> 

注意:right-move-out比较重要,视图向右侧滑出时,需要在动画完成之前全部滑出,并在最后将视图重新置在屏幕可视区域左侧隐藏。

5. Nginx 配置

当采用History API路由模式时,也就是mode设置为'history'''时,Nginx 需要做相应的配置,以保证直接访问视图的 URL 时可以正常找到 HTML 资源并正确路由。具体配置如下:

# match img resource
location ~* ^/resource/wa/([\w-.]+)/([\w-.]+)(/.*)?$ {
 root /resource_static/;
 try_files /resource/$1/$2/$3 /resource/$1/$2 /resource/$1/$3 /resource/$1/$2.html =404;
}

其中/resource/wa/Cyra.initApp中传入的appRoot属性对应。