In the previous section of keep-alive: Dynamic removal of the Vue whole site cache, we implemented the function of dynamically removing the cache when the route leaves. Based on this, it is possible to use the cache of the Vue whole site.

This article is a long, long story. Please skip, reread, read at random, read while lying down…

Series 1: Vue full site cache keep-alive: Dynamic cache removal

This is part 2 of a series: Vue full site Cache

Vue – Router-THEN: Before and after Page Data Transfer

Series 4: Vue-router-then: Implementation Principles for Vue global Cache

preface

From the early rough CSS, JS resources set browser local cache, to later small ICONS merged into a large picture to save request resources, and dynamic request 304 state judgment, and then Ajax opened the Web2.0 era, PJAX shine, now vue.js and other front-end framework prosperity, All of these developments, I think, speed up is a core driver.

keep-alive

In VUE, keep-alive feature is supported. Through keep-alive, old components are no longer destroyed to make way for new ones, but cached for future reuse. When the reuse of cached components, data can even be directly restored as is if there is no change. link

Keep alive and vue — the router

If router-view is placed in keep-alive, the cache function of all routing pages can be implemented roughly.

<! -- App.vue -->
<keep-alive><router-view class="transit-view"></router-view></keep-alive>
Copy the code

Why cache

One of the most common scenario is the new order when choosing address, the new order is a routing page, choose to address is a route of existing pages, so of course, we want the user to select the address back to the order page, in the order of other data such as the choice of coupons receipt date can continue.

In a number of similar scenarios, the need for data retention and reuse is constantly emerging, so VUEX emerged as a solution to save and transfer data through a common component of a third party, and it is the mainstream solution.

However, on the other hand, if the order page is cached when the address is selected, and the order component is directly reused after returning to the order page, all other data is retained, as long as the address data is updated, so that all the code logic is concentrated in the order component, wouldn’t this development experience be more intuitive and friendly?

This is a matter of opinion, and it is hard to say who is good or bad, so let’s continue to discuss the cache component solution.

There was a slight problem

If all routing pages are cached, what do you do when you don’t want to use caching? And built a new orders, for example, in different articles, editor of the components, such as into the heart of the different users, the cache is raised, we sometimes don’t want to cache function, especially some form scenarios, we both hope to retain half fill out into the next page to fill in data, we hope the new entry form is a new form page.

You can have your cake and eat it too

We want to keep the data we filled in halfway to the next page, but we also want the new form to be a completely new form page. .

In other words, use caching to go back to the previous page and not to go to the next page,

In other words, all pages are cached, and only the current page cache is removed when going backwards (back to the previous page), so that the next time you move forward (into the current page) you will naturally use a new page because there is no cache.

That is, simply implement the ability to remove the current page cache when going backwards (back to the previous page).

Define the location in the route

This is the idea of cache reuse. In order to remove the current page cache when going backwards (back to the previous page), we have a fool-fool solution: predict the usage scenario convention of the hierarchy of the various routing pages, since it is difficult to dynamically determine the user’s forward and backward behavior.

For example, in the Routes definition, we could define the route pages as follows:

// FYI, there is no routing component definition here
// router/index.js
routes: [
        {   path: '/'.redirect:'/yingshou'}, {path: '/yingshou'.meta: {rank:1.5.isShowFooter:true}, {},path: '/contract_list'.meta: {rank:1.5.isShowFooter:true}, {},path: '/customer'.meta: {rank:1.5.isShowFooter:true}, {},path: '/wode'.meta: {rank:1.5.isShowFooter:true}, {},path: '/yingfu'.meta: {rank:1.5.isShowFooter:true}, {},path: '/yingfu/pact_list'.meta: {rank:2.5}, {},path: '/yingfu/pact_detail'.meta: {rank:3.5}, {},path: '/yingfu/expend_view'.meta: {rank:4.5}, {},path: '/yingfu/jizhichu'.meta: {rank:5.5}, {},path: '/yingfu/select_pact'.meta: {rank:6.5}, {},path: '/yingfu/jiyingfu'.meta: {rank:7.5}},]Copy the code

The core idea is to define a rank field in meta to declare the page priority of the route. For example, 1.5 identifies layer 1 (home page), 2.5 identifies layer 2 (commodity list page), 3.5 identifies layer 3 (commodity details page), and so on.

If everyone is on the same level, you can also use decimal places like 1.4 and 1.5 to specify the hierarchy.

In summary, what we expect is that going from level 1 to level 2 is forward and going from level 3 to level 2 is backward.

Dynamically determine the cache removal in route hops

The route away event is intercepted using the vue. mixin method and the page cache is destroyed when the back is implemented in this interception method.

// main.js
Vue.mixin({
    beforeRouteLeave:function(to, from, next){
        if (from && from.meta.rank && to.meta.rank && from.meta.rank>to.meta.rank)
        {// If you return to the previous layer, you can change the judgment logic here according to your business and decide whether to destroy this layer cache or not.
            if (this.$vnode && this.$vnode.data.keepAlive)
            {
                if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache)
                {
                    if (this.$vnode.componentOptions)
                    {
                        var key = this.$vnode.key == null
                                    ? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? ` : :The ${this.$vnode.componentOptions.tag}` : ' ')
                                    : this.$vnode.key;
                        var cache = this.$vnode.parent.componentInstance.cache;
                        var keys  = this.$vnode.parent.componentInstance.keys;
                        if (cache[key])
                        {
                            if (keys.length) {
                                var index = keys.indexOf(key);
                                if (index > - 1) {
                                    keys.splice(index, 1); }}deletecache[key]; }}}}this.$destroy(); } next(); }});Copy the code

Is that all

No, this only solves the dynamic removal of the cache, allowing the user to go to both the new page and back to the old page. I haven’t talked about the former going to the new page, and the latter going back to the old page.

Is caching just for the taking

Even if the routing page reuses the cache, only the cached components and data are reused. In the actual scenario, if you enter detail B from List A and then enter List C, list C and List A are the same routing page, but will their data be the same? Should it be the same?

So update data even if it’s cached?

It looks like we’ve come to a new conclusion that cache page data is unreliable, too.

There should be a way.

Created Mounted is triggered when A cached component is reused. A beforeRouteUpdate event is also triggered when A page list is added to A page list B due to different URL parameters. Link 1 link 2 Link 3

It seems that we can do something by capturing these events.

ooops

The first instinct is to pull data to update the page after capturing the page loading event. Come to think of it, we spent a lot of time in order to enter the cache page and stop looking at the loading bar. It fell? It came back around.

Stupid way

Here provides a stupid way, the event should capture we still want to capture, but whether to do pull data this action, we can be open to debate.

  • Register a method in all routing pages, call it PageEnter, no matter from what situation, we will trigger this method.
// list.vue
    data(){
        return {
            params        : null,}},methods: {pageenter:function(){
            this.params = {
                        'uuid'                 : this.$route.query.uuid , }; }},Copy the code
  • If you watch the params directly, this thing still can’t play (please think about why?). If the string does not change, do nothing. If the string does not change, do nothing.
// list.vue
    computed:{
        paramsToString(){
            return JSON.stringify(this.params); }},watch: {paramsToString:function(){
            this.loadContent(); }},methods: {loadContent:function(){
            // Pull data here
            //this.$http.get(....)}},Copy the code
  • In main.js, vue. mixin can be used to intercept the three events mentioned above to trigger the PageEnter method.
//main.js
Vue.mixin({
    /* When the component is initialized, the PageEnter method */ is triggered
    mounted:function(){
       if (this.pageenter)
       {
           this.pageenter(); }},// * Returns from other components to activate the current component */
    activated:function(){
       if (this.pageenter)
       {
           this.pageenter(); }},/* When switching routes (parameter changes) in the same component */
    beforeRouteUpdate:function(to, from, next){
        if (this.pageenter)
        {
            this.$nextTick((a)= >{
                this.pageenter(); }); } next(); }});Copy the code

After the language

At this point, the framework of the whole site cache is basically built

?

Continue reading – Series 3: VUe-router-THEN for Vue whole site Caching: Before and after Page Data Transfer

From the original star blog: wanyaxing.com/blog/201807…