UNPKG

cyra

Version:

single page application view engine

319 lines (194 loc) 11.1 kB
# Cyra ## 1. 如何开始 ```js // 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 设计三个简单的概念 **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 周期图说明 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,如若更改该行为请参见的如何控制重新加载。 5. 当一个页面开始执行 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. 视图切换动画 视图间切换动画需要按照如下步骤: 1.`Cyra.initApp`中设置`animation``true` 2. 可添加以下可选参数进行动画配置,动画基于`CSS Animation` * `switchDuration: number`:指示动画切换持续时间,单位`ms`,默认`320` * `animationPrefix: string`:自定义动画`keyframes`前缀,默认`''` * `animationFunc: string`:自定义动画`timing-function`,默认为`''` 3. 在页面中添加以下4个 CSS keyframes: * `left-move-in`:视图从屏幕左侧进入并显示的动画 * `left-move-out`:视图向屏幕左侧滑出并隐藏的动画 * `right-move-in`:视图从屏幕右侧进入并显示的动画 * `right-move-out`:视图向屏幕右侧滑出并隐藏的动画 4. 为了方便,给出一个示例: ```html <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 资源并正确路由。具体配置如下: ```nginx # 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`属性对应。