Vue的指令中如何实现传递更多参数

发布时间:2022-05-30 13:49:43 作者:iii
来源:亿速云 阅读:171

本篇内容主要讲解“Vue的指令中如何实现传递更多参数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue的指令中如何实现传递更多参数”吧!

基本原理

本文介绍的指令扩展方法,主要以闭包为基础,并且使用了一些函数参数柯里化的方式来管理多个参数的传递过程。

我们以Vue2.0的指令定义方式为例,说明基本原理。本文所使用的指令定义方式,都已基于插件化的定义方式,在main.js中,通过use方法使用。

示例代码如下:

const myDirective = {
    install(app,options){
        app.directive("img-load", {
            bind:function(el,binding,vnode){ },
            inserted:function(el,binding,vnode){ },
            update:function(el,binding,vnode){ },
            componentUpdated:function(el,binding,vnode){ },
            unbind:function(el,binding,vnode){ },
        });
    }
};
export default myDirective ;

按照上述标准的指令定义方式,无论使用哪个钩子函数,我们只能传递三个参数,指令所绑定的DOM元素,指令接收的APP中绑定参数和虚拟节点。

基于闭包的扩展方案

指令的钩子函数参数已经固定,我们无法修改。但是我们可以通过闭包设置钩子函数的作用域,让闭包函数来接收更多参数。

代码如下: 

export default function getMyDirective(Vue) {
    return class MyDirective{
        constructor(options) {
            this.options = options;
            this.bindDirective= this.bindDirective.bind(this);
        }
        bindDirective(el, bindings) {                        
        }
    }
}
const myDirective = {
    install(app,options){
         const DirectiveClass = getMyDirective(app) ;
        var myDirective = new DirectiveClass(options);
        app.directive("my-dirctive", {
            bind:myDirective.bindDirective
        });
    }
};

JS中函数具有独立作用域,所以指令的绑定方法bindDirective在执行过程中,可以在不受任何外界其他代码的干扰下,使用闭包函数传递的参数。

实例和代码实现

本文以一个图片自动加载的指令为例,介绍自定义指令的参数扩展方式。

自定义指令的基本功能是根据图片的URL地址加载并显示图片,具体实现包括:

本文以自顶向下的方式来介绍该实例的代码实现

Main.js中将指令对应的插件全局化

使用use方法,在全局定义插件ImageLoad,该插件主要是功能是在全局定义一个图片加载指令,为该指令接收一个全局配置,即加载中图片地址和加载失败的图片地址。

Vue.use.use(ImageLoad, {
  loading: "http://localhost:4000/images/loading.gif",
  error: "http://localhost:4000/images/error.jpeg",
});

ImageLoad插件定义

ImageLoad插件和其他插件一样,既然要通过use使用,所以要定义install方法,install方法的第一个参数是当前App实例,第二个则是指令的全局配置。

import getImageLoad from './getImageLoad'
const ImageLoad = {
    install(app,options){
        const ImgClass = getImageLoad(app) ;
        var loadImage = new ImgClass(options);
        app.directive("img-load", {
            bind: loadImage.bindImage
        });
    }
};
export default ImageLoad;

图片加载管理类的定义

ImageLoadManagement定义了v-img-load指令的全部实现。

export default function getImageLoad(Vue) {
    return class ImageLoadManagement {
        constructor(options) {
            this.options = options;
            this.bindImage = this.bindImage.bind(this);
            this.renderImage = this.renderImage.bind(this);
        }
        bindImage(el, bindings) {
            const self = this;
            Vue.nextTick(function(){
                const src = bindings.value;
                self.renderImage('loading', src, el);
                self.loadImage(src).then(
                    () => self.renderImage('', src, el),
                    () => self.renderImage('error', src, el),
                );
            });
            
        }
        loadImage(src) {
            return new Promise((resolve, reject) => {
                const img = new Image();
                img.src = src;
                img.onload = resolve;
                img.onerror = reject;
            });
        }
        renderImage(type, src, el) {
            let _src;
            const {
                error,
                loading
            } = this.options;
            switch (type) {
                case 'loading':
                    _src = loading;
                    break;
                case 'error':
                    _src = error;
                    break;
                default:
                    _src = src;
                    break;
            }
            el.setAttribute("src", _src);
        }
    }
}

为了避免参数过多,所以采用柯里化的方法,对参数进行了分割:

通过上述方法,我们不仅扩展了指令的参数,使其可以支持更复杂的业务逻辑。

更重要的是。我们实现了指令的定义和实现逻辑的解耦,完全不再需要将所有的指令实现逻辑全部放在指令的注册方法中。通过ImageLoadManagement 的定义,将所有的指令实现逻辑都内聚在其中。

Vue 3.0的实现

Vue 3.0中,指令参数的扩展方法思路与2.0一致,只是因为Vue 3.0中指令的钩子函数名称与2.0不一致,造成一些区别。

具体代码如下:

import getImageLoad from './getImageLoad'
const ImageLoad = {
    install(app,options){
        const ImgClass = getImageLoad(options) ;
        var loadImage = new ImgClass();
        app.directive("img-load", {
            mounted: loadImage.bindImage
        });
    }
};
export default ImageLoad;
export default function getImageLoad(options) {
    return class ImageLoadManagement {
        constructor() {
            this.options = options;
            this.bindImage = this.bindImage.bind(this);
            this.renderImage = this.renderImage.bind(this);
        }
        bindImage(el, bindings) {
            const src = bindings.value;
            this.renderImage('loading', src, el);
            this.loadImage(src).then(
                () => this.renderImage('', src, el),
                () => this.renderImage('error', src, el),
            );
        }
        loadImage(src) {
            return new Promise((resolve, reject) => {
                const img = new Image();
                img.src = src;
                img.onload = resolve;
                img.onerror = reject;
            });
        }
        renderImage(type, src, el) {
            let _src;
            const {
                error,
                loading
            } = this.options;
            switch (type) {
                case 'loading':
                    _src = loading;
                    break;
                case 'error':
                    _src = error;
                    break;
                default:
                    _src = src;
                    break;
            }
            el.setAttribute("src", _src);
        }
    }
}

到此,相信大家对“Vue的指令中如何实现传递更多参数”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. vue路由跳转怎么传递参数
  2. vue中怎么实现组件间参数传递

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue

上一篇:C语言如何实现飞机售票系统

下一篇:基于JS如何实现接粽子小游戏

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》