Cyra
1. 如何开始
// main.js ; ; Cyra; // home.js ; // 定义了该函数后可以在进入视图时候改变页面title { return 'HOME-TITLE'; } // 以下函数如若未做任何事,可以省略不写 { ; } { thiscontainerinnerHTML = 'Hello World'; ; } { ; } { ; } ;
2. 基础思想
Cyra 设计三个简单的概念 Page, Route 和 AppStorage 来帮助开发者处理复杂的视图切换逻辑、数据传递及视图生命周期管理。
在移动端 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 周期图说明
-
橙色的 entering,leaving 代表视图两大过程, 进入和离开。
-
最左边的 disappeared,appeared 代表两大状态,显示和隐藏。
-
其中 initialize, willAppear, didAppear, willDisappear 是用户可以自定义的钩子函数。
-
appearing,disappearing是系统内部的函数过程,主要控制视图的隐藏和展现。如果想要在视图展现和隐藏时添加动画,可改写这两个方法的默认控制,请参见的转场动画。
3.2 生命周期
-
当 url 的 view 部分值(默认路径为 initApp 中传入的 default)匹配到相关的route,其对应的视图开始执行 entering 过程。
-
视图第一次执行 entering 过程时,依次执行 initialize, willAppear, (appearing), didAppear,若未定义则跳过,若在这其中某一步未调用 next() 也会中断执行。
-
当视图第二次执行 entering 过程,默认不再执行 initialize, willAppear,如若更改该行为请参见的如何控制重新加载。
-
当一个页面开始执行 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 的实例方法,而不要分散在initialize
和willAppear
中。
didAppear (next: Function): void
视图所属容器显示之后(display: block
)调用。
beforeEntering (next: Function): void
initialize
和willAppear
在 Page 的shouldReload()
返回false
时不会再次执行,也就是第二次进入相同视图时不会重复执行,如果需要在页面展示前,无论shouldReload()
返回结果如何都要执行,可以将代码写在下面的钩子函数中:
2.2 helper 函数
title (): string
用来设置视图的 title
shouldReload (previousPath: string): boolean
用来指定视图第二次之后进入时,是否执行initialize
和willAppear
两个钩子函数。
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
重新加载当前视图,并且会执行initialize
和willAppear
两个钩子函数。
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
为即将进入的视图的path
,data
为传递的强数据,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. 视图切换动画
视图间切换动画需要按照如下步骤:
- 在
Cyra.initApp
中设置animation
为true
- 可添加以下可选参数进行动画配置,动画基于
CSS Animation
:
switchDuration: number
:指示动画切换持续时间,单位ms
,默认320
animationPrefix: string
:自定义动画keyframes
前缀,默认''
animationFunc: string
:自定义动画timing-function
,默认为''
- 在页面中添加以下4个 CSS keyframes:
left-move-in
:视图从屏幕左侧进入并显示的动画left-move-out
:视图向屏幕左侧滑出并隐藏的动画right-move-in
:视图从屏幕右侧进入并显示的动画right-move-out
:视图向屏幕右侧滑出并隐藏的动画
- 为了方便,给出一个示例:
注意:right-move-out
比较重要,视图向右侧滑出时,需要在动画完成之前全部滑出,并在最后将视图重新置在屏幕可视区域左侧隐藏。
5. Nginx 配置
当采用History API
路由模式时,也就是mode
设置为'history'
或''
时,Nginx 需要做相应的配置,以保证直接访问视图的 URL 时可以正常找到 HTML 资源并正确路由。具体配置如下:
# match img resourcelocation ~* ^/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
属性对应。