视图 / 路由

View(<div class="view">)- 是一个拥有自己的设置、导航和历史记录的独立视觉部分。因此,它是应用程序中的应用程序。这种功能允许您轻松地操作应用程序的每个部分。

View Layout

让我们来看一下视图的HTML结构:

<body>
  <!-- app root -->
  <div id="app">
    <!-- view inside of panel -->
    <div class="panel panel-left panel-cover">
      <div class="view panel-view"> ... </div>
    </div>
    <!-- Your main view -->
    <div class="view view-main">
      <!-- View related pages -->
      ...
    </div>
    <div class="popup">
      <div class="view popup-view"> ... </div>
    </div>
  </div>
</body>

正如你所见,View 可以出现在你的应用的任何部分。

Main View

你的主视图应该有额外的view-main类。为什么我们需要主视图呢?默认情况下,所有不在任何已初始化视图中的链接将在主视图中加载页面。另外,如果你使用browserHistory哈希导航,那么它只对主视图的导航起作用。

Multiple Views Layout

如果我们的应用根目录中有多个视图的应用,即所谓的“标签视图”应用程序,我们必须使用额外的<div class="views">元素包装我们的视图。

只允许有一个"Views"元素!

<body>
  <!-- app root -->
  <div id="app">
    <!-- view inside of panel -->
    <div class="panel panel-left panel-cover">
      <div class="view panel-view"> ... </div>
    </div>
    <!-- Views container -->
    <div class="views tabs">
      <!-- Your main view -->
      <div class="view view-main tab tab-active" id="view-1">
        <!-- View related pages -->
        ...
      </div>
      <!-- Another view -->
      <div class="view tab" id="view-2">
        <!-- View related pages -->
        ...
      </div>
      ...
    </div>
    <div class="popup">
      <div class="view popup-view"> ... </div>
    </div>
  </div>
</body>

View App Methods

当我们在HTML中已经有了所需的视图,并且我们的应用程序已经初始化初始化,现在我们需要初始化我们的视图。让我们看一下可用的应用程序方法来处理视图:

app.views.create(viewEl, parameters) - 初始化视图

  • viewEl - stringHTMLElement。如果是字符串,则为视图元素的CSS选择器
  • parameters - object。具有视图参数的对象
  • 方法返回刚创建的视图实例的对象。

app.views.get(viewEl) - 通过HTML元素获取视图实例

  • viewEl - stringHTMLElement。如果是字符串,则为视图元素的CSS选择器
  • 方法返回刚创建的视图实例的对象。

有时候我们需要获取当前活动的视图,因为除了主应用视图外,我们可能还有打开的弹出窗口、气泡窗口、打开的面板、选项卡等视图。该方法允许获取当前活动/可见/“最顶层”的视图实例。

例如,如果您在面板中初始化了视图,并且面板当前处于打开状态,那么该方法将返回面板的视图。或者,如果您使用具有选项卡栏布局的应用程序,其中每个选项卡都是一个视图,那么该方法将返回当前活动/可见的选项卡视图。

app.views.current - 获取当前活动/可见的视图实例。

  • 方法返回刚创建的视图实例的对象。

View Parameters

现在让我们来看一下创建视图所需的可用参数列表:

参数类型默认描述
namestring视图名称。如果视图使用名称创建,则可以通过 app.views.[name] 访问。
mainbooleanfalse指定此视图是否为主视图。如果未传递,则将根据其元素是否具有 view-main 类来确定
routerbooleantrue设置为 false 以禁用视图路由器
initRouterOnTabShowbooleanfalse如果启用,并且视图是一个选项卡,则不会初始化路由器并加载初始页面,直到视图选项卡变为可见
urlstring默认(初始)视图的 URL。如果未指定,则等于文档的 URL
loadInitialPagebooleantrue当启用时,并且视图内没有子页面时,它将加载与初始 URL 匹配的初始页面
linksViewstring
object
另一个视图或已初始化视图实例的对象的CSS选择器。默认情况下,初始化的(仅)视图中的所有链接将在此视图中加载页面。这告诉链接在其他视图中加载页面。
allowDuplicateUrlsbooleanfalse您可以启用此参数,以允许加载与当前“活动”页面具有相同URL的新页面。
animatebooleantrue启用页面之间的过渡效果
preloadPreviousPagebooleantrue在导航深入时启用/禁用预加载上一页。对于“滑动返回页面”功能的正确工作,应启用此选项。
reloadPagesbooleanfalse启用后,视图将始终重新加载当前活动页面,而不加载新页面
restoreScrollTopOnBackbooleantrue启用后,返回到此页面时将恢复页面滚动到顶部
iosPageLoadDelaynumber0在新页面加载并插入到DOM之前,以及在进行过渡之前的延迟时间(以毫秒为单位)。可以稍微增加一些以提高性能。仅在iOS主题下生效
mdPageLoadDelaynumber0在新页面加载并插入到DOM之前,以及在进行过渡之前的延迟时间(以毫秒为单位)。可以稍微增加一些以提高性能。仅在MD主题下生效
passRouteQueryToRequestbooleantrue启用后,路由器将将路由URL查询传递给请求URL查询(对于url和componentUrl路由属性

如果您有以下路由:

{ path: '/somepage/', url: 'http://myserver/page/' }

并且您单击具有/somepage/?foo=bar URL的链接,则将从http://myserver/page/?foo=bar URL加载页面

passRouteParamsToRequestbooleanfalse启用后,路由器将将当前路由参数传递给请求URL查询(对于url和componentUrl路由属性

如果您有以下路由:

{ path: '/user/:userId/posts/:postId/', url: 'http://myserver/userpost/' }

并且您单击具有/user/11/posts/12/ URL的链接,则将从http://myserver/userpost/?userId=11&postId=12 URL加载页面

主从视图
masterDetailBreakpointnumber0启用主从视图的最小应用程序宽度(具有master: true参数的路由)
masterDetailResizablebooleanfalse

启用可调整大小的主从布局

要指定主从可调整大小的最小/最大宽度,需要在样式中设置页面主从,例如:

.view-master-detail .page-master {
  min-width: 200px;
  max-width: 80vw;
}
reloadDetailbooleanfalse启用后,每次导航时都会重新加载每个详细页面
路由
routesarray当前视图的带有路由的数组。如果指定,则将覆盖全局应用程序路由,并且只有在此处指定的路由将可用于当前视图
routesAddarray包含其他路由的数组,将扩展全局应用程序路由。这些附加路由仅适用于当前视图
routesBeforeEnterfunction(context)

array
每个路由加载/进入之前执行的函数(或函数数组)。要继续路由加载,必须调用resolve。如果是array,则必须解析数组中的每个函数才能继续。

路由beforeEnter相同,但适用于每个路由

routesBeforeLeavefunction(context)

array
每个路由卸载/离开之前执行的函数(或函数数组)。要继续导航,必须调用resolve。如果是array,则必须解析数组中的每个函数才能继续。

路由beforeLeave相同,但适用于每个路由

元素移除
removeElementsbooleantrue在页面过渡期间,路由器可能会从DOM中删除未使用的页面和导航栏元素。如果您想手动处理元素的删除或使用其他库(例如Vue或React),则可以禁用此选项
removeElementsWithTimeoutbooleanfalse启用后,路由器将在超时后删除元素
removeElementsTimeoutnumber0删除元素的超时时间(在removeElementsWithTimeout: true的情况下)
unloadTabContentbooleantrue当选项卡可路由时,卸载可路由选项卡内容(删除选项卡内部内容)当选项卡变为可见时。仅适用于可路由选项卡
组件缓存
componentCachebooleantrue启用后,路由器将缓存通过componentUrl指定的组件
XHR缓存
xhrCachebooleantrue由于路由器可以使用Ajax加载页面的HTML内容,因此最好使用缓存,特别是如果这些页面中的内容更新不太频繁。
xhrCacheIgnorearray[]不应缓存的URL(字符串)的数组
xhrCacheIgnoreGetParametersbooleanfalse如果为"true",则像"about.html?id=2"和"about.html?id=3"这样的URL将被视为单个"about.html"页面并进行缓存
xhrCacheDurationnumber1000 * 60 * 10在毫秒(milliseconds)内,应用程序将使用缓存而不是通过另一个Ajax请求加载页面的持续时间。默认情况下为10分钟。
iOS动态导航栏
iosDynamicNavbarbooleantrue启用iOS主题的动态导航栏
iosAnimateNavbarBackIconbooleantrue启用此选项(当启用时)可以为动态导航栏左侧的默认返回链接图标提供更本地的外观动画效果。仅在将动态导航栏与"sliding"设置为左侧的默认返回链接图标一起使用时有用。
滑动返回
iosSwipeBackbooleantrue启用/禁用从屏幕左边缘向右滑动以返回上一页的功能。适用于iOS主题
iosSwipeBackThresholdnumber0像素值。如果"触摸距离"大于此值,则会触发滑动返回操作。适用于iOS主题
iosSwipeBackActiveAreanumber30像素值。触发滑动返回操作的屏幕左侧不可见边缘的宽度。适用于iOS主题
iosSwipeBackAnimateShadowbooleantrue启用/禁用滑动返回操作期间的box-shadow动画。您可以禁用它以提高性能。适用于iOS主题
iosSwipeBackAnimateOpacitybooleantrue启用/禁用滑动返回操作期间的不透明度动画。您可以禁用它以提高性能。适用于iOS主题
mdSwipeBackbooleanfalse启用/禁用从屏幕左边缘向右滑动以返回上一页的功能。适用于MD主题
mdSwipeBackThresholdnumber0像素值。如果"触摸距离"大于此值,则会触发滑动返回操作。适用于MD主题
mdSwipeBackActiveAreanumber30像素值。触发滑动返回操作的屏幕左侧不可见边缘的宽度。适用于MD主题
mdSwipeBackAnimateShadowbooleantrue启用/禁用滑动返回操作期间的box-shadow动画。您可以禁用它以提高性能。适用于MD主题
mdSwipeBackAnimateOpacitybooleanfalse启用/禁用滑动返回操作期间的不透明度动画。您可以禁用它以提高性能。适用于MD主题
浏览器历史记录
browserHistorybooleanfalse如果您开发的是Web应用程序(而不是Cordova/Capacitor或主屏幕Web应用程序),启用哈希导航(浏览器URL将显示为"http://my-webapp.com/#!/about.html")非常有用。用户还可以使用浏览器的默认后退和前进按钮导航到应用程序的历史记录。
browserHistoryRootstring浏览器历史记录的根URL分隔符,例如"http://my-app.com/"。仅在使用空("")的browserHistorySeparator时有用
browserHistoryAnimatebooleantrue启用/禁用浏览器历史记录更改时的页面过渡效果
browserHistoryAnimateOnLoadbooleanfalse启用/禁用应用程序加载时的浏览器历史记录页面过渡效果
browserHistorySeparatorstring#!浏览器历史记录的URL分隔符,可以更改为类似于'#page/'的内容,然后您的浏览器历史记录URL将显示为"http://myapp.com/#page/about.html"
browserHistoryOnLoadbooleantrue禁用以忽略解析浏览器历史记录URL并在应用程序加载时加载页面
browserHistoryInitialMatchbooleanfalse当您的服务器配置为响应与请求的URL匹配的内容时(例如使用服务器端渲染框架如Nuxt.js、Next.js等),将其设置为true。在使用Framework7-React/Vue/Svelte时也必须启用。默认情况下禁用
browserHistoryStoreHistorybooleantrue启用时(默认情况下),它将在localStorage中存储路由器历史记录,并尝试在下次访问Web应用程序时恢复它
browserHistoryTabsstringreplace可以是replacepush。当为"replace"(默认情况下)时,它将在可路由选项卡更改时替换状态,否则(如果为"push"),它将在每个可路由选项卡更改时添加到历史记录中,因此可以使用浏览器的后退按钮在选项卡之间切换
事件处理程序
onobject

Object 带有事件处理程序的对象。例如:

var view = app.views.create('.view-main', {
  on: {
    pageInit: function () {
      console.log('page init')
    }
  }
})

请注意,所有以下参数都可以在全局应用程序参数中使用view属性设置为所有视图的默认值。例如:

var app = new Framework7({
  view: {
    iosDynamicNavbar: false,
    xhrCache: false,
  }
});

View Methods & Properties

因此,要创建视图,我们必须调用:

var view = app.views.create({ /* parameters */ })

然后我们有其初始化的实例(如上面示例中的view变量),具有有用的方法和属性:

属性
view.app全局应用程序实例的链接
view.el视图的HTML元素
view.$el带有视图HTML元素的Dom7实例
view.name传递的视图名称
view.main表示是否为主视图的布尔属性
view.routes可用路由器路由的数组
view.history视图历史记录的数组
view.params视图初始化参数的对象
view.router视图的初始化路由器实例
方法
view.destroy()销毁视图实例
view.on(event, handler)添加事件处理程序
view.once(event, handler)添加在触发后将被删除的事件处理程序
view.off(event, handler)删除事件处理程序
view.off(event)移除指定事件的全部处理函数
view.emit(event, ...args)出发实例绑定的事件d

View Events

查看将在视图元素上触发以下DOM事件,并在应用程序和视图实例上触发事件:

View Dom Events

事件target对象描述
view:init视图元素
在视图初始化时触发的事件
view:resize视图元素
在主细节调整大小时触发的事件(当masterDetailResizable启用时)

View Instance Events

视图实例在自身实例和应用程序实例上发出事件。应用程序实例事件具有相同的名称,前缀为view。

事件目标参数描述
initview(view)在视图初始化时触发的事件
viewInitapp
resizeview(view, width)在主细节调整大小时触发的事件(当masterDetailResizable启用时)
viewResizeapp

Router API / Methods & Properties

视图的主要目的是在页面之间进行导航/路由。我们可以通过view.router访问其路由器实例。它具有许多有用的方法和属性,以控制路由和导航:

路由属性
router.app链接到全局应用程序实例
router.view链接到相关的视图实例
router.params具有路由器初始化参数的对象
router.el路由器的视图HTML元素
router.$el具有路由器视图HTML元素的Dom7实例
router.currentPageEl当前页面的HTML元素
router.routes具有可用路由器路由的数组
router.history具有路由器视图历史记录的数组
router.cache具有路由器/视图缓存数据的对象
router.currentRoute具有当前路由数据的对象。它具有以下属性
  • url - 路由URL
  • path - 路由路径
  • query - 带有路由查询的对象。如果URL是/page/?id=5&foo=bar,则它将包含以下对象{id: '5', foo: 'bar'}
  • params - 路由参数。如果我们有与/page/user/:userId/post/:postId/路径匹配的路由,并且页面的URL是/page/user/55/post/12/,那么它将是以下对象{userId: '55', postId: '12'}
  • name - 路由名称
  • hash - 路由URL哈希
  • route - 与可用路由匹配的对象
  • context - 传递给路由的上下文
router.previousRoute具有先前活动路由数据的对象。与currentRoute具有相同的对象格式
router.allowPageChange布尔属性,指示是否允许更改页面/导航
路由器方法
router.navigate(url, options)导航到(加载)新页面
  • url - string - 要导航到的URL
  • options - object 具有附加的导航属性(可选):
    • reloadCurrent (boolean) - 用路由中的新页面替换当前页面,在这种情况下没有动画
    • reloadPrevious (boolean) - 用路由中的新页面替换历史记录中的上一个页面
    • reloadAll (boolean) - 加载新页面并从历史记录和DOM中删除所有先前页面
    • clearPreviousHistory (boolean) - 重新加载/导航到指定路由后,将清除先前页面的历史记录
    • animate (boolean) - 页面是否应该有动画效果(覆盖默认的路由器设置)
    • history (boolean) - 页面是否应该保存在路由器历史记录中
    • browserHistory (boolean) - 页面是否应该保存在浏览器状态中。如果使用browserHistory,则可以传递false以防止路由进入浏览器历史记录
    • ignoreCache (boolean) - 如果设置为true,则会忽略缓存中是否存在此URL,并使用XHR重新加载它
    • props (object) - 将作为页面组件props传递的props
    • transition (string) - 路由自定义页面过渡名称
    • openIn (string) - 允许将页面路由作为模态框或面板打开。因此,它可以是以下之一:popup,popover,loginScreen,sheet,panel
router.navigate(parameters, options)通过参数导航(加载)到新页面。该方法允许通过“名称”导航到路由。
  • parameters - object - 包含要导航到的路由的name、query、params的对象。
  • options - object 包含其他导航属性的对象(可选)。与前面的示例相同。

例如,如果我们有以下路由:

{
  name: 'about',
  path: '/about/',
  ...
}

我们可以通过调用以下代码进行导航:

router.navigate({ name: 'about' });

如果有更复杂的带参数的路由:

{
  name: 'post',
  path: '/block/:userId/:postId',
  ...
}

然后必须传递参数:

router.navigate({
  name: 'post',
  params: { userId: 1, postId: 2 },
});
router.back(url, options)返回上一页,通过查看历史记录返回。
  • url - string -url - 字符串类型,要导航到的URL(可选)。
    • 如果未指定,则将返回到历史记录中的上一页。
    • 如果指定了并且历史记录中有上一页,则将被忽略。
    • 如果指定了并且存在 force: true 选项,则将从DOM中删除上一页并导航回指定的页面URL。
  • options - object 包含其他导航属性的对象(可选)
    • animate (boolean) - (布尔类型)- 页面是否应该进行动画显示(覆盖默认的路由设置)
    • browserHistory (boolean) - (布尔类型)- 页面是否应该保存在浏览器状态中。如果您使用 browserHistory,则可以在此处传递 false 来防止路由进入浏览器历史记录
    • ignoreCache (boolean) -(布尔类型)- 如果设置为 true,则会忽略缓存中的URL,并使用XHR重新加载
    • force (boolean) - (布尔类型)- 如果设置为 true,则会忽略历史记录中的上一页,并加载指定的页面
router.refreshPage()刷新/重新加载当前页面。实际上与以下代码相同:
router.navigate(router.currentRoute.url, {
  reloadCurrent: true,
  ignoreCache: true,
});
router.clearPreviousHistory()清除路由器的先前页面历史记录,并从DOM中删除所有先前的页面
router.updateCurrentUrl(url)根据传递的URL更新当前路由URL,并更新router.currentRoute属性(查询、参数、哈希等)。此方法不加载或重新加载任何内容,只是更改当前路由URL。
router.generateUrl({name, query, params})

根据给定的路由名称生成路由URL。例如,如果我们有以下路由:

{
  name: 'blogPost',
  path: '/blog/post/:postId',
  ...
}

那么我们可以这样获取路由的URL:

const url = router.generateUrl({
  name: 'blogPost',
  // only for route with required params
  params: { postId: 1234 },
  // optional query
  query: { foo: 'bar' }
});
console.log(url); /* /blog/post/1234?foo=bar */
router.on(event, handler)添加事件处理程序
router.once(event, handler)添加一次性事件处理程序,将在触发后被移除
router.off(event, handler)移除事件处理程序
router.off(event)移除指定事件的所有处理程序
router.emit(event, ...args)触发实例事件

Linking Between Pages & Views

在导航页面之间使用路由方法可能不太方便。在许多情况下,我们可以使用链接在页面之间导航。我们还可以使用data-属性传递附加的导航参数。

<!-- same as router.navigate('/somepage/'); -->
<a href="/somepage/">Some Page</a>

<!-- same as router.navigate('/somepage/', {reloadCurrent: true, animate: false}); -->
<a href="/somepage/" data-animate="false" data-reload-current="true">Some Page</a>

<!-- same as router.back(); -->
<a href="#" class="back">Go back</a>

<!-- same as router.back('/home/', {force: true, ignoreCache: true}); -->
<a href="/home/" data-force="true" data-ignore-cache="true" class="back">Go back</a>

链接的默认行为:

但是,如果我们需要在另一个视图中加载页面,我们可以在链接的 data-view 属性中指定该视图的 CSS 选择器

<!-- 左侧视图 -->
<div class="view view-init view-left" data-name="left">
  ...
  <!-- 将 "some-page" 加载到主视图  -->
  <a href="/some-page/" data-view=".view-main">Some Page</a>
  ...
</div>
<!-- 主视图 -->
<div class="view view-init view-main">
  ...
 <!-- 将 "another-page" 加载到左侧视图 -->
  <a href="/another-page/" data-view=".view-left">Another Page</a>
  ...
</div>

如果我们需要在“当前”视图(当前活动/可见的视图实例)中加载页面,我们需要设置 data-

<!-- will load "another-page" in current view -->
<a href="/another-page/" data-view="current">Another Page</a>

如果我们需要阻止路由处理特定的链接,我们可以给这些链接添加 prevent-router 类:

<!-- 路由将忽略此链接 -->
<a href="/some-page/" class="prevent-router">Some Page</a>

Router Events

路由有很多有用的事件。

Router Dom Events

路由器将为滑动返回页面触发以下 DOM 事件:

事件对象Target描述
swipeback:move视图元素<div class="view">在滑动返回移动期间触发的事件
swipeback:beforechange视图元素<div class="view">在释放时向前滑动动画返回到上一页之前触发的事件
swipeback:afterchangeView Element<div class="view">在释放时向前滑动动画返回到上一页之后触发的事件
swipeback:beforeresetView Element<div class="view">在释放时向当前页面滑动动画返回之前触发的事件
swipeback:afterresetView Element<div class="view">在释放时向当前页面滑动动画返回之后触发的事件

Router Instance Events

路由事件会冒泡到视图实例和应用实例,因此在路由实例上触发的事件也可以在视图和应用实例上使用:

事件参数描述
routeChange(newRoute, previousRoute, router)在当前路由更改时触发的事件
routeChanged(newRoute, previousRoute, router)在当前路由更改后和页面过渡之后触发的事件
routeUrlUpdate(newRoute, router)在调用router.updateCurrentUrl方法时触发的事件
XHR 事件
routerAjaxStart(xhr, options)在路由XHR 打开并发送之前触发的事件,可以在发送之前修改XHR对象。可以使用此回调函数设置自定义标头等。作为参数接收XHR对象和导航options对象
routerAjaxSuccess(xhr, options)在请求成功时触发的事件。作为参数接收XHR对象和导航options对象
routerAjaxError(xhr, options)在请求失败时触发的事件。作为参数接收XHR对象和导航options对象
routerAjaxComplete(xhr, options)在请求完成时触发的事件。作为参数接收XHR对象和导航options对象
滑动返回事件
swipebackMove(data)在滑动返回移动期间触发的事件。data包含以下属性:percentage,currentPageEl,previousPageEl,currentNavbarEl,previousNavbarEl
swipebackBeforeChange(data)在释放时向前滑动动画返回到上一页之前触发的事件。data包含以下属性:currentPageEl,previousPageEl,currentNavbarEl,previousNavbarEl
swipebackAfterChange(data)在释放时向前滑动动画返回到上一页之后触发的事件。data包含以下属性:currentPageEl,previousPageEl,currentNavbarEl,previousNavbarEl
swipebackBeforeReset(data)在释放时向当前页面滑动动画返回之前触发的事件。data包含以下属性:currentPageEl,previousPageEl,currentNavbarEl,previousNavbarEl
swipebackAfterReset(data)在释放时向当前页面滑动动画返回之后触发的事件。data包含以下属性:currentPageEl,previousPageEl,currentNavbarEl,previousNavbarEl
Page Events
pageMounted(pageData)在新页面刚插入到DOM中时触发的事件。或者在具有keepAlive路由的页面被挂载/附加到DOM时触发。作为参数接收事件的页面数据
pageInit(pageData)在路由器初始化所需页面的组件和导航栏之后触发的事件。作为参数接收事件的页面数据
pageReinit(pageData)在导航到已经初始化的页面时触发的事件。作为参数接收事件的页面数据
pageBeforeIn(pageData)在一切都初始化完成并且页面准备好转换到视图(到活动/当前位置)时触发的事件。作为参数接收事件的页面数据
pageAfterIn(pageData)在页面转换到视图后触发的事件。作为参数接收事件的页面数据
pageBeforeOut(pageData)在页面即将转换出视图之前触发的事件。作为参数接收事件的页面数据
pageAfterOut(pageData)在页面转换出视图后触发的事件。作为参数接收事件的页面数据
pageBeforeUnmount(pageData)在具有keepAlive路由的页面即将被卸载/从DOM中分离时触发的事件。作为参数接收事件的页面数据
pageBeforeRemove(pageData)在页面将从DOM中移除之前触发的事件。如果需要释放一些事件/销毁一些插件以释放内存,此事件非常有用。作为参数接收事件的页面数据。对于keepAlive路由,不会触发此事件。
可路由选项卡事件
tabInit
tabMounted
(newTabEl, tabRoute)在可路由选项卡内容加载后立即触发的事件。作为参数接收以下内容的事件处理程序:
  • newTabEl - 刚刚加载了路由内容的选项卡HTML元素(新选项卡)
  • tabRoute - 新选项卡路由
tabBeforeRemove(oldTabEl, newTabEl, tabRoute)在可路由选项卡内容加载后立即触发的事件。作为参数接收以下内容的事件处理程序:
  • oldTabEl - 刚刚移除路由内容的选项卡HTML元素(旧选项卡)
  • newTabEl - 刚刚加载路由内容的选项卡HTML元素(新选项卡)
  • tabRoute - 新选项卡路由
可路由模态框事件
modalInit
modalMounted
(modalEl, modalRoute, modal)在可路由模态框内容加载并添加到DOM后,将触发此事件。事件处理程序接收以下参数:
  • modalEl - 加载的模态框HTML元素
  • modalRoute -模态框路由
  • modal - 创建的模态框实例
modalBeforeRemove(modalEl, modalRoute, modal)在可路由模态框从DOM中移除并销毁之前,将触发此事件。事件处理程序接收以下参数:
  • modalEl - 模态框HTML元素
  • modalRoute - 模态框路由
  • modal - 模态框实例

View Auto Initialization

如果您不需要使用视图API,并且您的视图在应用程序初始化时已经存在于DOM中,则可以通过添加额外的view-init类来自动初始化视图。

<!-- Add view-init class -->
<div class="view view-init">
  ...
</div>

但是对于视图参数,我们可以将它们传递给data-属性。

在data-属性中使用驼峰命名的参数,例如browserHistory,应该使用短横线命名,如data-browser-history。

<!-- 视图参数在data-属性中-->
<div class="view view-init" data-url="/" data-name="home" data-browser-history="true">
  ...
</div>

在这种情况下,如果您需要访问创建的视图实例,可以使用以下方式:

<!-- main view -->
<div class="view view-main view-init">
  ...
</div>

<!-- another view -->
<div class="view view-init" data-name="home">
  ...
</div>
var mainView = app.views.main;
var homeView = app.views.home;

Initial Page Route

使用路由也可以正确加载初始页面。在应用程序布局中,我们必须将视图保留为空白。

<body>
  <div id="app">
    <div class="view view-main"></div>
  </div>
</body>

在路由中,我们可以指定"home"路由,例如:

routes: [
  {
    path: '/',
    url: './home.html'
  },
  ...
]

当我们初始化视图时,需要指定它是默认URL:

app.views.create('.view-main', {
  url: '/'
})

这样,现在在应用加载时,主页内容将从"home.html"文件加载。

Master Detail

主从模式通常在足够宽的屏幕和平板电脑上使用,由两个视图组成:

当折叠时(在窄屏幕上),在这些页面之间的导航行为将像常规路由一样。

主从视图之间的导航发生时没有过渡效果。

当加载主页面时,所有其他页面将作为从页面加载。要从主从视图中"导航离开",建议使用reloadAll导航参数。

要启用主从视图,您需要:

当启用主-详细视图时,您可以使用以下附加类进行自定义样式:

For example:

const mainView = app.views.create('.view-main', {
  // enable master detail
  masterDetailBreakpoint: 800,
  routes: [
    {
      path: '/',
      url: './pages/master.html',
      // specify home route as master route
      master: true,
      // detail routes
      detailRoutes: [
        {
          path: '/detail/:id/',
          url: './pages/detail.html',
        },
      ]
    },
  ]
});

我们应该有以下内容:

Custom Page Transitions

除了默认的主题特定页面过渡效果外,还可以创建自定义页面过渡效果或使用其他附加过渡效果。

内置了以下附加的自定义页面过渡效果:

  • f7-circle
  • f7-cover
  • f7-cover-v
  • f7-dive
  • f7-fade
  • f7-flip
  • f7-parallax
  • f7-push

要在特定路线上使用这样的过渡效果,我们需要在route options中指定:

routes = [
  ...
  {
    path: '/some-page/',
    url: '...',
    options: {
      transition: 'f7-circle',
    },
  },
  ...
]

要使用自定义过渡效果加载现有路线,我们需要在router.navigate()方法中传递它:

// load /some-page/ with "f7-cover" transition
router.navigate('/some-page/', { transition: 'f7-cover' })

或者我们可以直接通过data-transition属性在链接中指定它(就像其他路线选项一样):

<!-- load /some-page/ with "f7-cover" transition -->
<a href="/some-page/" data-transition="f7-cover">...</a>

除了内置的过渡效果,我们还可以创建自定义的过渡效果。可以使用CSS动画来实现。

当我们指定自定义页面过渡效果时,路由器会将以下类添加到其元素(<div class="view">)中:

  • router-transition-[name]-forward - 当导航到新页面时
  • router-transition-[name]-backward - 当导航到上一页时(返回)

在向前导航时,它会等待page-next上的animationend事件,而在返回时则等待page-current上的animationend事件。

因此,如果我们将自定义过渡效果命名为my-transition,则可以按以下方式指定它:

.router-transition-my-transition-forward,
.router-transition-my-transition-backward {
  /* Apply some styles for view element when custom transition is running */
}
.router-transition-my-transition-forward .page-current {
  /* Animation when current page transforms to previous page */
  animation: my-transition-current-to-prev 400ms;
}
.router-transition-my-transition-forward .page-next {
  /* Animation when next page transforms to current page (new page comes into view) */
  animation: my-transition-next-to-current 400ms;
}
.router-transition-my-transition-backward .page-current {
  /* Animation when current page transforms to next page (going back) */
  animation: my-transition-current-to-next 400ms;
}
.router-transition-my-transition-backward .page-previous {
  /* Animation when previous page transforms to current page (previous page comes into view) */
  animation: my-transition-prev-to-current 400ms;
}

/* Specify animations */
@keyframes my-transition-current-to-prev {
  /* ... */
}
@keyframes my-transition-next-to-current {
  /* ... */
}
@keyframes my-transition-current-to-next {
  /* ... */
}
@keyframes my-transition-prev-to-current {
  /* ... */
}

这是一个例子,内置的 f7-cover 过渡效果的指定方式如下:

.router-transition-f7-cover-forward,
.router-transition-f7-cover-backward {
  background: #000;
  perspective: 1200px;
}
.router-transition-f7-cover-forward .page-next {
  animation: f7-cover-next-to-current 450ms forwards;
}
.router-transition-f7-cover-forward .page-current {
  animation: f7-cover-current-to-prev 450ms forwards;
}
.router-transition-f7-cover-backward .page-current {
  animation: f7-cover-current-to-next 450ms forwards;
}
.router-transition-f7-cover-backward .page-previous {
  animation: f7-cover-prev-to-current 450ms forwards;
}
@keyframes f7-cover-next-to-current {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0%);
  }
}
@keyframes f7-cover-current-to-next {
  from {
    transform: translateX(0%);
  }
  to {
    transform: translateX(100%);
  }
}
@keyframes f7-cover-current-to-prev {
  from {
    transform: translateZ(0);
    opacity: 1;
  }
  to {
    transform: translateZ(-300px);
    opacity: 0.5;
  }
}
@keyframes f7-cover-prev-to-current {
  from {
    transform: translateZ(-300px);
    opacity: 0.5;
  }
  to {
    transform: translateZ(0);
    opacity: 1;
  }
}