视图 / 路由器

视图 (<div class="view">) - 是应用程序中独立的视觉部分,具有自己的设置、导航和历史记录。 因此,它类似于应用程序中的应用程序。 此类功能使您可以轻松操作应用程序的每个部分。

视图布局

让我们看一下视图的 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 类。 为什么我们需要主视图? 默认情况下,所有链接(不在任何已初始化视图中)都将在主视图中加载页面。 此外,如果您使用 browserHistory 哈希导航,则它仅适用于主视图的导航。

多视图布局

如果我们的应用程序在应用程序根目录中具有多个视图,即所谓的“选项卡式视图”应用程序,则我们必须使用额外的 <div class="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>

视图应用程序方法

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

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

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

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

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

可能会出现我们需要获取当前活动视图的情况,因为除了主应用程序视图之外,我们还可能在打开的弹出窗口、弹出框、打开的面板、选项卡等中拥有视图。此方法允许获取当前活动/可见/“最顶层”视图的视图实例。

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

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

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

视图参数

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

参数类型默认描述
name字符串视图名称。 如果使用名称创建了视图,则可以通过 app.views.[name] 访问它
main布尔值false指定此视图是否为主视图。 如果未传递,则将根据其元素是否具有 view-main 类来确定
router布尔值true设置为 false 以禁用视图路由器
initRouterOnTabShow布尔值false如果启用并且视图是选项卡,则在视图选项卡变为可见之前,它不会初始化路由器和加载初始页面
url字符串默认(初始)视图的 URL。 如果未指定,则等于文档 URL
loadInitialPage布尔值true启用后,如果 View 中没有子页面,它将加载与初始 URL 匹配的初始页面。
linksView字符串
对象
另一个视图或对象的 CSS 选择器,其中包含初始化的 View 实例。默认情况下,初始化的(仅限)视图中的所有链接都将加载此视图中的页面。这告诉链接在其他视图中加载页面。
allowDuplicateUrls布尔值false您可以启用此参数以允许加载与 View 中当前“活动”页面具有相同 URL 的新页面。
animate布尔值true启用页面之间的过渡。
preloadPreviousPage布尔值true在导航深入时启用/禁用预加载上一页。应启用此选项才能正确使用“向后滑动页面”功能。
reloadPages布尔值false启用后,View 将始终重新加载当前活动页面,而不会加载新页面。
restoreScrollTopOnBack布尔值true启用后,当您返回此页面时,它将恢复页面滚动顶部。
iosPageLoadDelay数字0在新页面加载并插入到 DOM 之后以及它进行转换之前延迟(以毫秒为单位)。可以稍微增加以提高性能。仅在 iOS 主题下生效。
mdPageLoadDelay数字0在新页面加载并插入到 DOM 之后以及它进行转换之前延迟(以毫秒为单位)。可以稍微增加以提高性能。仅在 MD 主题下生效。
passRouteQueryToRequest布尔值true启用后,路由器会将路由 url 查询传递给请求 url 查询(对于 urlcomponentUrl 路由属性)。

如果您有以下路由

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

并且您将点击带有 /somepage/?foo=bar url 的链接,则它将从 http://myserver/page/?foo=bar url 加载页面。

passRouteParamsToRequest布尔值false启用后,路由器会将当前路由参数传递给请求 url 查询(对于 urlcomponentUrl 路由属性)。

如果您有以下路由

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

并且您将点击带有 /user/11/posts/12/ url 的链接,则它将从 http://myserver/userpost/?userId=11&postId=12 url 加载页面。

主从视图
masterDetailBreakpoint数字0启用主路由(带有 master: true 参数的路由)的主从视图所需的最小应用程序宽度。
masterDetailResizable布尔值false

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

要指定主从视图的可调整大小的最小/最大宽度,需要在 page-master 的样式中设置,例如

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

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

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

routesBeforeLeavefunction(context)

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

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

元素移除
removeElements布尔值true在页面转换期间,路由器可以从 DOM 中移除未使用的页面和导航栏元素。如果您想手动或使用其他库(例如 Vue 或 React)处理元素移除,则禁用此选项很有用
removeElementsWithTimeout布尔值false启用后,路由器将在超时后移除元素
removeElementsTimeout数字0移除元素的超时时间(以毫秒为单位)(如果 removeElementsWithTimeout: true
unloadTabContent布尔值true当可路由选项卡变得可见时,卸载其内容(移除选项卡内部内容)。仅适用于可路由选项卡
组件缓存
componentCache布尔值true启用后,路由器将缓存通过 componentUrl 指定的组件
XHR 缓存
xhrCache布尔值true由于路由器可以使用 Ajax 加载页面的 HTML 内容,因此最好使用缓存,尤其是在这些页面中的内容不经常更新的情况下。
xhrCacheIgnore数组[]不应缓存的 URL 数组(字符串)
xhrCacheIgnoreGetParameters布尔值false如果为“true”,则像“about.html?id=2”和“about.html?id=3”这样的 URL 将被视为单个“about.html”页面并进行缓存
xhrCacheDuration数字1000 * 60 * 10应用程序使用缓存而不是使用另一个 Ajax 请求加载页面的持续时间(以毫秒为单位)。默认情况下为 10 分钟。
iOS 动态导航栏
iosDynamicNavbar布尔值true为 iOS 主题启用动态导航栏
iosAnimateNavbarBackIcon布尔值true启用此选项后,动态导航栏左侧后退链接图标动画将具有更自然的观感。仅当您将动态导航栏与左侧的默认后退链接图标设置为“滑动”一起使用时,此选项才有效。
滑动返回
iosSwipeBack布尔值true启用/禁用从屏幕左边缘滑动返回以返回上一页的功能。适用于 iOS 主题
iosSwipeBackThreshold数字0以像素为单位的值。如果“触摸距离”大于此值,则将开始滑动返回操作。适用于 iOS 主题
iosSwipeBackActiveArea数字30以像素为单位的值。触发滑动返回操作的屏幕左侧不可见边缘的宽度。适用于 iOS 主题
iosSwipeBackAnimateShadow布尔值true在滑动返回操作期间启用/禁用阴影动画。您可以禁用它以提高性能。适用于 iOS 主题
iosSwipeBackAnimateOpacity布尔值true在滑动返回操作期间启用/禁用不透明度动画。您可以禁用它以提高性能。适用于 iOS 主题
mdSwipeBack布尔值false启用/禁用从屏幕左边缘滑动返回以返回上一页的功能。适用于 MD 主题
mdSwipeBackThreshold数字0以像素为单位的值。如果“触摸距离”超过此值,则将开始滑动返回操作。适用于 MD 主题
mdSwipeBackActiveArea数字30以像素为单位的值。触发滑动返回操作的屏幕不可见左边缘的宽度。适用于 MD 主题
mdSwipeBackAnimateShadow布尔值true在滑动返回操作期间启用/禁用阴影动画。您可以禁用它以提高性能。适用于 MD 主题
mdSwipeBackAnimateOpacity布尔值false在滑动返回操作期间启用/禁用不透明度动画。您可以禁用它以提高性能。适用于 MD 主题
浏览器历史记录
browserHistory布尔值false如果您开发的是 Web 应用程序(不是 Cordova/Capacitor 或主屏幕 Web 应用程序),则启用哈希导航非常有用(浏览器网址将类似于“http://my-webapp.com/#!/about.html”)。用户还可以使用浏览器的默认后退和前进按钮在应用程序的历史记录中导航。
browserHistoryRoot字符串浏览器历史记录根 URL 分隔符,例如“http://my-app.com/”。仅当您使用空字符串 ("") 作为 browserHistorySeparator 时才有用
browserHistoryAnimate布尔值true启用/禁用浏览器历史记录更改时的页面转换
browserHistoryAnimateOnLoad布尔值false在应用程序加载时启用/禁用浏览器历史记录页面转换
browserHistorySeparator字符串#!浏览器历史记录 URL 分隔符,可以更改为类似“#page/”的内容,然后您的浏览器历史记录网址将类似于“http://myapp.com/#page/about.html”
browserHistoryOnLoad布尔值true禁用以忽略解析浏览器历史记录 URL 并在应用程序加载时加载页面
browserHistoryInitialMatch布尔值false当您的服务器配置为响应与请求的 URL 匹配的内容时(例如,与服务器端渲染框架(如 Nuxt.js、Next.js 等)一起使用),请设置为 true。在 Framework7-React/Vue/Svelte 中使用时也必须启用。默认情况下禁用
browserHistoryStoreHistory布尔值true启用后(默认情况下),它会将路由器历史记录存储在 localStorage 中,并在下次访问 Web 应用程序时尝试恢复它
browserHistoryTabs字符串replace可以是 replacepush。当为“replace”(默认)时,它将在可路由选项卡更改时替换状态,否则(如果为“push”),它会将每个可路由选项卡更改添加到历史记录中,因此可以使用浏览器后退按钮在选项卡之间来回切换
事件处理程序
on对象

包含事件处理程序的对象。例如

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

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

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

视图方法和属性

所以要创建视图,我们必须调用

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

之后,我们将获得其初始化实例(例如上面示例中的 view 变量),其中包含有用的方法和属性

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

视图事件

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

视图 DOM 事件

事件目标描述
view:init视图元素<div class="view">将在视图初始化时触发事件
view:resize视图元素<div class="view">将在主从调整大小时触发事件(启用 masterDetailResizable 时)

视图实例事件

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

事件目标参数描述
initview(view)将在视图初始化时触发事件
viewInitapp
resizeview(view, 宽度)将在主从调整大小时触发事件(启用 masterDetailResizable 时)
viewResizeapp

路由器 API / 方法和属性

视图的主要目的是在页面之间导航/路由。我们可以通过 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 - 字符串 - 要导航到的 URL
  • options - 具有附加导航属性的 对象(可选)
    • reloadCurrent (布尔值) - 用来自路由的新页面替换当前页面,在这种情况下没有动画
    • reloadPrevious (布尔值) - 用来自路由的新页面替换历史记录中的上一页
    • reloadAll (布尔值) - 加载新页面并从历史记录和 DOM 中删除所有先前页面
    • clearPreviousHistory (布尔值) - 在重新加载/导航到指定路由后,将清除以前的页面历史记录
    • animate (布尔值) - 页面是否应具有动画效果(覆盖默认路由器设置)
    • history (布尔值) - 页面是否应保存在路由器历史记录中
    • browserHistory (布尔值) - 页面是否应保存在浏览器状态中。如果您使用的是 browserHistory,则可以在此处传递 false 以防止路由进入浏览器历史记录
    • ignoreCache (布尔值) - 如果设置为 true,则它将忽略缓存中的此类 URL,并使用 XHR 再次加载它
    • props (对象) - 将作为页面组件属性传递的属性
    • transition (字符串) - 路由 自定义页面过渡名称
    • openIn (字符串) - 允许以模态或面板的形式打开页面路由。因此,它可以是以下之一:popuppopoverloginScreensheetpanel
router.navigate(parameters, options)按参数导航到(加载)新页面。此方法允许通过其 name 导航到路由。
  • parameters - 对象 - 包含要导航到的路由 namequeryparams 的对象。
  • options - 具有附加导航属性的 对象(可选)。与上一个示例相同。

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

{
  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 - 字符串 - 要导航到的 URL(可选)。
    • 如果未指定,则返回历史记录中的上一页。
    • 如果指定了 URL 并且历史记录中有上一页,则将忽略上一页。
    • 如果指定了 URL 并且存在 force: true 选项,则将从 DOM 中删除上一页并导航回指定的页面 URL
  • options - 具有附加导航属性的 对象(可选)
    • animate (布尔值) - 页面是否应具有动画效果(覆盖默认路由器设置)
    • browserHistory (布尔值) - 页面是否应保存在浏览器状态中。如果您使用的是 browserHistory,则可以在此处传递 false 以防止路由进入浏览器历史记录
    • ignoreCache (布尔值) - 如果设置为 true,则它将忽略缓存中的此类 URL,并使用 XHR 再次加载它
    • force (布尔值) - 如果设置为 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(事件, 处理程序)添加事件处理程序
router.once(事件, 处理程序)添加事件处理程序,该处理程序在触发后将被删除
router.off(事件, 处理程序)移除事件处理程序
router.off(事件)移除指定事件的所有处理程序
router.emit(事件, ...args)在实例上触发事件

页面和视图之间的链接

一直使用路由器方法在页面之间导航可能不太方便。在许多情况下,我们可以使用 链接 在页面之间导航。我们可以使用 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 选择器

<!-- left view -->
<div class="view view-init view-left" data-name="left">
  ...
  <!-- will load "some-page" to main view -->
  <a href="/some-page/" data-view=".view-main">Some Page</a>
  ...
</div>
<!-- main view -->
<div class="view view-init view-main">
  ...
  <!-- will load "another-page" to left view -->
  <a href="/another-page/" data-view=".view-left">Another Page</a>
  ...
</div>

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

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

如果我们需要阻止路由器处理特定链接,我们可以向此类链接添加 prevent-router

<!-- This link will be ignored by router -->
<a href="/some-page/" class="prevent-router">Some Page</a>

路由器事件

路由器有很多有用的事件。

路由器 DOM 事件

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

事件目标描述
swipeback:move视图元素<div class="view">在滑动手势返回期间将触发此事件
swipeback:beforechange视图元素<div class="view">当您释放时,将在向后滑动动画到上一页之前立即触发事件
swipeback:afterchange视图元素<div class="view">当您释放时,将在向后滑动动画到上一页之后触发事件
swipeback:beforereset视图元素<div class="view">当您释放时,将在向后滑动动画到当前页之前立即触发事件
swipeback:afterreset视图元素<div class="view">当您释放时,将在向后滑动动画到当前页之后触发事件

路由器实例事件

路由器事件冒泡到视图实例和应用程序实例,因此在路由器实例上发出的事件在视图和应用程序实例上也可用

事件参数描述
routeChange(newRoute,previousRoute,router)事件将在当前路由更改时触发
routeChanged(newRoute,previousRoute,router)事件将在当前路由更改和页面转换后触发
routeUrlUpdate(newRoute,router)调用 router.updateCurrentUrl 方法时将触发事件
XHR 事件
routerAjaxStart(xhr,选项)路由器 XHR 打开后和 XHR 发送前将触发事件。 可用于在发送 XHR 对象之前对其进行修改。 使用此回调设置自定义标头等。 作为参数接收 XHR 对象和导航 options 对象
routerAjaxSuccess(xhr,选项)请求成功时将触发事件。 作为参数接收 XHR 对象和导航 options 对象
routerAjaxError(xhr,选项)如果请求失败,将触发事件。 作为参数接收 XHR 对象和导航 options 对象
routerAjaxComplete(xhr,选项)请求完成后将触发事件。 作为参数接收 XHR 对象和导航 options 对象
滑动返回事件
swipebackMove(数据)在滑动返回移动期间将触发事件。 data 包含具有以下属性的对象: percentagecurrentPageElpreviousPageElcurrentNavbarElpreviousNavbarEl
swipebackBeforeChange(数据)当您释放时,将在向后滑动动画到上一页之前立即触发事件。 data 包含具有以下属性的对象: currentPageElpreviousPageElcurrentNavbarElpreviousNavbarEl
swipebackAfterChange(数据)当您释放时,将在向后滑动动画到上一页之后触发事件。 data 包含具有以下属性的对象: currentPageElpreviousPageElcurrentNavbarElpreviousNavbarEl
swipebackBeforeReset(数据)当您释放时,将在向后滑动动画到当前页之前立即触发事件。 data 包含具有以下属性的对象: currentPageElpreviousPageElcurrentNavbarElpreviousNavbarEl
swipebackAfterReset(数据)当您释放时,将在向后滑动动画到当前页之后触发事件。 data 包含具有以下属性的对象: currentPageElpreviousPageElcurrentNavbarElpreviousNavbarEl
页面事件
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 API 并且您的 View 在应用程序初始化时就在 DOM 中,那么您可以通过添加 view-init 类来自动初始化它。

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

但是 View 参数怎么办呢?在这种情况下,我们可以将它们传递给 data- 属性。

例如 browserHistory 这样的驼峰式命名法的参数,在 data- 属性中应使用烤肉串式命名法,例如 data-browser-history

<!-- view parameters in data- attributes -->
<div class="view view-init" data-url="/" data-name="home" data-browser-history="true">
  ...
</div>

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

<!-- 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;

初始页面路由

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

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

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

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

当我们初始化 View 时,我们需要指定它是默认 URL。

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

就是这样,现在在应用程序加载时,主页内容将从“home.html”文件加载。

主从视图

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

折叠时(在窄屏幕上),此类页面之间的导航将表现为通常的路由。

主从视图之间的导航无需过渡。

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

要启用主从模式:

启用主从模式后,您可以使用以下附加类进行自定义样式设置:

例如:

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',
        },
      ]
    },
  ]
});

我们应该得到如下结果:

自定义页面过渡

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

以下是一些内置的附加自定义页面过渡:

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

要在特定路由上使用此类过渡,我们需要在路由选项中指定它

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;
  }
}