3 / 28 如何實現一個指令 ?

前面的話

前端日問,鞏固基礎,不打烊!!!

解答

基本用法

使用Vue.directive()來註冊自定義指令:

全局註冊

比如制定一個懶加載指令v-lazyLoad

Vue.directive('lazyLoad', {
	// ...指令選項
})
指令選項
  • bind: 只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數可以定義一個綁定時執行一次的初始化動作
  • inserted: 被綁定元素插入父結點時調用。
  • update:被綁定元素所在的模板更新時調用,而不論綁定值是否變化
  • componentUpdated:被綁定元素所在模板完成一次更新週期時調用
  • unbind: 只調用一次,指令與元素解綁時調用
實現一個圖片懶加載指令
//Vue 圖片懶加載
// 引入節流函數
import { throttle } from './util';

export default (Vue, options = {}) => {
    // 在數組原型上添加remove方法 找到item所在的位置,並刪除
    if (!Array.prototype.remove) {
        Array.prototype.remove = function (item) {
            // 如果長度爲0 跳出
            if (!this.length) return;
            let index = this.indexOf(item);
            // 否則刪除
            if (index > -1) {
                this.splice(index, 1);
                return this;
            }
        };
    }
    // 設置初始值
    let init = {
        // 默認圖片
        default: 'http://ps.missyuan.com/uploads/allimg/120703/1F4543522-0.jpg'
    };
    // 要顯示的圖片列表
    let listenList = [];
    // 已經加載過的圖片地址
    let alredyArray = [];
    // 判斷是否加載過
    const isAlredyLoad = (imageSrc) => {
        if (alredyArray.indexOf(imageSrc) > -1) {
            return true;
        } else {
            return false;
        }
    };
    //檢測圖片是否可以加載,如果可以則進行加載
    const isCanLoad = (item) => {
        let ele = item.ele;
        let src = item.src;
        //圖片距離頁面頂部的距離
        let top = ele.getBoundingClientRect().top;
        //top + 10 已經進入了可視區域10像素
        if (top + 10 < window.innerHeight) {
            let image = new Image();
            image.src = src;
            image.onload = function () {
                ele.src = src;
                alredyArray.push(src);
                listenList.remove(item);
            };
            return true;
        } else {
            return false;
        }
    };
    //Vue 指令最終的方法
    const addListener = (ele, binding) => {
        //綁定的圖片地址
        let imageSrc = binding.value;
        //如果已經加載過,則無需重新加載,直接將src賦值
        if (isAlredyLoad(imageSrc)) {
            ele.src = imageSrc;
            return false;
        }
        let item = {
            ele: ele,
            src: imageSrc
        };
        //圖片顯示默認的圖片
        ele.src = init.default;
        //再看看是否可以顯示此圖片
        if (isCanLoad(item)) {
            return;
        };
        //否則將圖片地址和元素均放入監聽的lisenList裏
        listenList.push(item);

        //然後開始監聽頁面scroll事件

        window.onscroll = () => {
            let carriedOut = throttle(function () {
                let length = listenList.length;
                for (let i = 0; i < length; i++) {
                    isCanLoad(listenList[i]);
                }
            }, 1000);
            carriedOut();
        };
    };
    Vue.directive('lazyLoad', {
        bind: addListener
    });
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章