Nowadays, mobile web apps are becoming more and more popular, and many companies are beginning to try to use MVVM frameworks such as angular, react, and vue to develop single-page architecture web apps. However, when developing a web app, if you want the page navigation experience to be close to native apps, you will generally encounter these two problems:
- Identify forward and backward behavior
- Restore the previous page when backing
The author has developed a navigation library based on vue and vue-routervue-navigation, to help developers solve these problems. The following are the solutions to the problem.
Identify forward and backward
Let’s talk about the first question first. Unlike native apps, there are mainly these restrictions in the browser:
- No forward and backward events are provided
- Developers are not allowed to read browsing history
- Users can manually enter the address, or use the forward and backward provided by the browser to change the URL
The solution is to maintain a browsing record yourself. Each time the url changes, compare it with the recorded browsing record to judge the forward and backward behavior:
- The url exists in the browsing history and is backward
- The url does not exist in the browsing history means forward
- The url is refreshed at the end of the browsing record
In addition, the same route may be allowed to occur multiple times in the applied route path (for example, A->B->A), so add a key value to each route to distinguish different instances of the same route.
This browsing record needs to be stored in sessionStorage, so that the browsing record can also be restored after the user refreshes.
Restore the previous page when backing
After recognizing the backward behavior, the next step is to restore the previous page as natively.
One solution is that the page continues to be stored in the DOM and adds the style display: none to tell the browser not to render the element, but if there are too many cached pages, it will become very large, which will affect the performance of the page. This article will not discuss this solution.
Another solution is to cache the data into memory. The developer needs to store the page's data and restore the page based on the data when it is returned to the page. However, in this way, the data stored on each page is not accessible, and additional encoding is generally required. If there is a more underlying solution that can solve this problem and is transparent to the developer, it would be best, so I tried and developed vue-navigation.
In the vue-navigation version, the vuekeep-aliveTo cache the page, but keep-alive determines the cache based on the component's name or tag, so it brings many restrictions.
By reading the source code of keep-alive and learning about its caching mechanism, I implemented a component that manages cache to flexibly cache subcomponents. The implementation idea is as follows:
- Each time render, first get the vnode of the child component (vue's virtual dom)
- Calculate the key of vnode, assign the key value to vnode to avoid vue-routerMultiplexing component instance
- Judging whether the node has been cached based on the key value
- Cachedated: Assign the cached instance to componentInstance, so vue will restore components based on this instance
- Uncachedated: Store vnode in memory, and can be restored from memory the next time you return to this page
In addition, it is necessary to add a logic to clear the cache. When the browsing record you maintain changes, the unwanted cache will be cleared according to the browsing record (for example, the current route is: A->B->C, the user returns directly from C to A, so both B and C need to be deleted from the cache).
at last
Although it is developed based on vue, the idea remains unchanged, and the same can be done with other frameworks.
I'd better recommend itvueandvue-navigation. After using the plug-in, put router-view under navigation and there will be a cache function.
import Vue from 'vue' import router from './router' // vue-router instanceimport Navigation from 'vue-navigation' (Navigation, {router}) // Launch your application...
<template> <navigation> <router-view></router-view> </navigation> </template>
Finally, everyone is welcome to discuss or provide better solutions.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.