亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue的指令中如何實現傳遞更多參數

發布時間:2022-05-30 13:49:43 來源:億速云 閱讀:171 作者:iii 欄目:開發技術

本篇內容主要講解“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
        });
    }
};
  • 使用閉包函getMyDirective來包裹鉤子函數bindDirective

  • 閉包函數是用戶自定義函數,我們可以設置任意多個參數

  • 在閉包函數中定義類來封裝指令的所有操作,構造方法也可以接收參數,從而將多個參數柯里化分割。

  • 通過bind方法強行將指令鉤子函數綁定的bindDirective方法的this限定為MyDirective的實例,也就是說,bindDirective方法可以通過this訪問更多的數據。

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;
  • install方法中,首先通過調用getImageLoad方法,獲取加載圖片的管理類,傳入當前App實例。

  • 實例化圖片加載管理類的對象loadImage ,傳入圖片加載的全局配置。

  • 定義自定義指令v-img-load,該指定的bind鉤子方法指向loadImage中的bindImage方法。

  • bindImage方法的this是指向loadImage對象,因此可以使用到App實例,指令全局配置,loadImage對象內的數據。

圖片加載管理類的定義

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);
        }
    }
}

為了避免參數過多,所以采用柯里化的方法,對參數進行了分割:

  • 在閉包函數getImageLoad中,定義了全局App實例參數;

  • ImageLoadManagement 類的構造方法中定義了圖片加載指令需要的全局配置參數。

  • class 作為function的語法糖使用,其本質來時function,從而實現獨立作用域。

  • bindImage方法中可以直接使用App實例的nextTick,無論該指令在父組件還是子組件中使用,都可以保證在指令中代碼執行時,所有DOM元素加載完成。

  • loadImage方法用于檢查指定URL的圖片是否存在,如果存在則顯示具體圖片,否則則顯示加載失敗的圖片。

  • renderImage方法用于設置指令綁定的Img元素的圖片地址,圖片的實際地址可以通過bindings參數的value屬性獲取。

通過上述方法,我們不僅擴展了指令的參數,使其可以支持更復雜的業務邏輯。

更重要的是。我們實現了指令的定義和實現邏輯的解耦,完全不再需要將所有的指令實現邏輯全部放在指令的注冊方法中。通過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的指令中如何實現傳遞更多參數”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

南靖县| 五峰| 阳原县| 柳江县| 广安市| 渭源县| 阿瓦提县| 大兴区| 罗甸县| 修水县| 大化| 灵璧县| 洛扎县| 临清市| 同仁县| 正蓝旗| 涟源市| 自治县| 土默特左旗| 三河市| 启东市| 长海县| 太仓市| 新民市| 芜湖市| 济阳县| 瑞金市| 邵阳市| 始兴县| 建湖县| 上虞市| 外汇| 嘉义县| 荥经县| 监利县| 松溪县| 朔州市| 岚皋县| 民县| 三原县| 绥棱县|