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

Series 2: Vue full site Cache 2: How to design full Site Cache

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

This article is part 4: Vue -router-then: Implementation principles for Vue full site Cache

preface

As far as the effect is concerned, I am very satisfied with the improvement of development efficiency brought by v-Model-link instruction. However, the code implementation of vue-router-then plug-in itself is a little rough, and I always feel that my understanding of VUE is still superficial. Sometimes WHEN I read other people’s articles, I always feel confused and sad. However, as I said in my blog introduction in zhihu column, high-rise buildings grow from ground to ground, we also want to add a brick, my own three wooden axe should be presented or not, to attract jade.

DPS is alive

From the first article Vue full site cache keep-alive: Vue-router-then is a feature that builds on the success of the page cache. If you don’t use the page cache properly, or if the page cache is destroyed, vue-router-then is meaningless.

Realize the principle of

The principle of this plugin is very crude implementation, in short: in the route jump event to bind the new page component events.

Return a Promise

Wrap a promise based on the this.$router family of methods and store the resolve method.

const routerThen = {
        '$router':null.resolve:null.// Skip to the specified page and return promise
        request:function(requestType='push', location, onComplete=null, onAbort=null){
            if(! location || location==' ')
            {
                throw new Error('location is missing');
            }
            return new Promise( (resolve, reject) = >{
                if (this.$router)
                {
                    console.log('this.$router'.this.$router);
                    this.resolve = resolve;
                    switch (requestType)
                    {
                        case 'push':
                            this.$router.push(location, onComplete, onAbort);
                            break;
                        case 'replace':
                            this.$router.replace(location, onComplete, onAbort);
                            break;
                        case 'go':
                            this.$router.go(location);
                            break;
                        default:
                            reject('requestType error:'+requestType);
                            break; }}else
                {
                    reject('$router missing');
                }
            }).catch(error= >{
                this.resolve = null;
                throw new Error(error);
            });
        },
Copy the code

Put some bootleg in the routing event

Once resolve is saved, the page should jump, and you can catch the routing event and call back the new page object VM to the Promise after the new page loads.

        Vue.mixin({
            Register a callback event for the next page before the route jumps to the next page.
            beforeRouteEnter:function(to, from, next){
                if (routerThen.resolve)
                {
                    next(vm= >{
                            routerThen.resolve(vm);
                            routerThen.resolve = null;
                    });
                }
                else{ next(); }},beforeRouteUpdate:function(to, from, next){
                if (routerThen.resolve)
                {
                    routerThen.resolve(this);
                    routerThen.resolve = null; } next(); }});Copy the code

Get the page object and everything will be fine

The modelLink method, for example, takes the VM object and stuffs it with an input event.

        modelLink:function(link, el=null){
            return this.push(link).then(vm= >{
                vm.$once('input',value=>{
                    if (typeof el == 'function')
                    {
                        el(value);
                    }
                    else if (typeof el == 'object')
                    {
                        if (el.$emit)
                        {
                            el.$emit('input',value);
                        }
                        else if (el.tagName)
                        {
                            el.value = value;
                            const e = document.createEvent('HTMLEvents');
                            // e.initEvent(binding.modifiers.lazy? 'change':'input', true, true);
                            e.initEvent('input'.true.true); el.dispatchEvent(e); }}});returnvm; })},Copy the code

V-model-link is just a syntactic sugar

I love the idea of grammar sugar, simplicity for complex things.

        clickElFun:function(event){
            let link = this.getAttribute('model-link');
            if (link)
            {
                console.log(this);
                return routerThen.modelLink(link,this.vnode && this.vnode.componentInstance?this.vnode.componentInstance:this);
            }
            return Promise.resolve();
        },

    Vue.directive('model-link'.function (el, binding, vnode) {
            el.binding = binding;
            el.vnode   = vnode;
            el.setAttribute('model-link',binding.value);
            el.removeEventListener('click',routerThen.clickElFun);
            el.addEventListener('click',routerThen.clickElFun);
        });
Copy the code

After the language

Again, this code is a little rough, for your reference.

I like the concept of full site cache very much. At present, there are few similar articles in the VUE community. I hope more friends can participate in it and dig out the bright spots.

END

I am also studying the sharing and updating of data across multiple levels of pages in the case of full site caching. It will be very interesting. Please look forward to it.

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