As mobile Web apps become more and more popular, many companies are trying to use MVVM frameworks such as Angular, React and Vue to develop single-page web apps. However, when developing a Web app, if you want the navigation experience of a page to be similar to that of a native app, there are two common problems:

  • Identify forward and backward behavior
  • Restore the previous page when you step back

The author developed a vue-Navigation library based on VUE and VUe-Router to help developers solve these problems. The following are the solutions to these problems.

Identify forward and backward

Let’s start with the first question. Unlike native apps, there are several major limitations in browsers:

  • No forward or backward events are provided
  • Developers are not allowed to read the browser history
  • Users can manually enter the address or change the URL using the browser-provided forward and backward Settings

The solution is to maintain a browsing history of your own, and compare it with the recorded browsing history every time the URL changes to determine the forward and backward behavior:

  • A URL that exists in the browsing history is a back step
  • The URL does not exist in the browsing history to advance
  • The URL is refreshed at the end of the browsing history

In addition, the application routing path may allow the same route to appear more than once (for example, A->B->A), so add A key value to each route to distinguish between different instances of the same route.

The browsing record needs to be stored in sessionStorage so that the browsing record can be restored after the user refreshes.

Restore the previous page when you step back

Once the backward behavior has been identified, the next step is to restore the previous page as if it were native.

One option is to continue to store the page in the DOM and add a style display: None to tell the browser not to render the element, but caching more DOM can become too large and affect page performance. This option is not discussed in this article.

Another option is to cache the data in memory, where the developer needs to store the data for the page and then restore the page based on the data when it is returned to the page. However, the data stored in each page is different, which generally requires extra coding. If there is a lower-level solution that can solve this problem and be transparent to developers, it would be better. Therefore, VUe-Navigation was tried and developed.

In vue navigation 0.x, we use Vue keep-alive to cache pages, but keep-alive determines the cache based on the name or tag of the component, so there are many limitations.

After reading the source code of Keep-Alive and knowing its cache mechanism, we implemented a component to manage cache by ourselves to cache sub-components flexibly. The implementation idea is as follows:

  • Every timerenderIs first retrieved from the child componentvnode(Virtual DOM of vue)
  • To calculate thevnodeKey, and assign the key value tovnodeAvoid vue – the routerReuse component instances
  • Check whether the node is cached based on the key value

    • Cached: Assigns a cached instance tocomponentInstanceSo that VUE will restore the component based on this instance
    • No cache: willvnodeIt is stored in memory and can be recovered from memory the next time you return to the page

In addition, you need to add A logic to clear the cache. When the self-maintained browsing history changes, you need to clear the cache that is not needed according to the browsing history. For example, if the current route is A->B->C and the user directly returns to A from C, both B and C need to be deleted from the cache.

The last

Although developed based on VUE, the idea remains the same and the same can be done with other frameworks.

Vue and VUE-Navigation. After using the plugin, put the router-view under navigation and you will have the caching function.

main.js



import Vue from 'vue'
import router from './router' / / the vue instance - the router
import Navigation from 'vue-navigation'
Vue.use(Navigation, {router})
// Start your app...Copy the code

App.vue



<template>
  <navigation>
    <router-view></router-view>
  </navigation>
</template>Copy the code

Finally, you are welcome to discuss or provide better solutions.