1. keep-alive

  • Error: Some Android devices return incorrect cache page positions after using the keep-alive tag

  • Solution:

<div id="app">
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <router-view v-if=! "" $route.meta.keepAlive"></router-view>
</div>
Copy the code
const router = new Router({
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition && to.meta.keepAlive) {
      return savedPosition;
    }
    return { x: 0.y:0}; }});Copy the code

2. A blank screen is displayed

  • The problem
[Prerequisite] : iOS device [Procedure] : Page A is A long list --> Click the jump when sliding to the footer, go to page B-- > return to page A --> Blank mask layer will appear on the screen --> touch the screen gently and slide --> Mask layer disappearsCopy the code

Solution 1

This operation is performed after the callback operation following a successful interface request has completed, for example

FetchCourseList is a wrapped Promise request
fetchCourseList().then(({ data: courses }) = > {
  this.courses = courses;
}).then((a)= > {
    setTimeout((a)= > {
        window.scrollTo(0.1);
        window.scrollTo(0.0);
    });
});
Copy the code

The downside of this solution is that every page needs to do this and it is not recommended.

Solution 2 (Recommended)

Use the asynchronous scroll operation in scrollBehavior

const router = new Router({
  scrollBehavior(to, from, savedPosition) {
    // keep-alive returns the cached page and records the browsing location
    if (savedPosition && to.meta.keepAlive) {
      return savedPosition;
    }
    // asynchronous scroll operation
    return new Promise((resolve) = > {
      setTimeout((a)= > {
        resolve({ x: 0.y: 1 });
      }, 0); }); }});Copy the code

This solution works directly on the route, is compatible with each page and does not produce a 1px scroll position after the page is loaded.

Why can’t we just return instead of using an asynchronous scroll operation? Here are some personal insights that you are welcome to comment on.

  1. The first step is to understand the component lifecycle after which the scrollBehavior function is executed. ScrollBehavior is executed beforeUpdate before mounted in the component’s life cycle.

  2. Return {x:0, y:100} directly in the scrollBehavior function, entering the page is still at the top. Why don’t you scroll to 100px? Mounted specifies that a/vue/view layer is updated. / mounted specifies that vue/view layer is updated.

  3. To verify the above guess, set up a static page where the data is already written to death in HTML. Return {x:0, y: 100} from scrollBehavior. Proof: does relate to the operation after the asynchronous request returns.

  4. Then learn what vue does with Mounted and beforeUpdate phases. Mounted: Data Is mounted on a page. BeforeUpdate and Updated periods: When vue finds that data in data has changed, it triggers a re-rendering of the corresponding component.

  5. Mounted does not block subsequent operations on the main thread. Therefore, the scrollBehavior function continues to execute before the request callback event is triggered (the assignment to data is not performed). Return {x:0, y:100}. This is equivalent to scrolling before the asynchronous request callback event is executed. After the scroll, the asynchronous request callback event is executed and variable A is assigned to data, causing the component to re-render and return to the top. The entire process scroll is rolled against the original data page of the data, so the mask layer still appears.

  6. To sum up: asynchronous scrolling must be used, using setTimeout to jump out of the main thread to queue the callback event. Since Mouted executes before scrollBehavior, callback events for asynchronous requests are queued first, followed by setTimeout callback events. First in, first out. An asynchronous request callback event is performed to assign the value of variable A in data. This is already a static page, and I just return {x:0, y: 100}. This has triggered the page scroll to 100px. But because of the data changes, the page is re-rendered and goes back to the top. At this point, the entire touch scrolling effect has been implemented secretly, and the mask layer is no longer present.