最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue使用節(jié)流函數(shù)的踩坑實(shí)例指南

 更新時(shí)間:2021年05月20日 10:30:19   作者:majunchang  
防抖和節(jié)流的目的都是為了減少不必要的計(jì)算,下面這篇文章主要給大家介紹了關(guān)于vue使用節(jié)流函數(shù)踩坑的相關(guān)資料,需要的朋友可以參考下

前言

一個(gè)常見的業(yè)務(wù)場(chǎng)景,我們要在input搜索框輸入結(jié)束后,發(fā)送相關(guān)請(qǐng)求,獲取搜索數(shù)據(jù)。頻繁的事件觸發(fā)會(huì)導(dǎo)致接口請(qǐng)求過于頻繁。所以需要我們對(duì)此加以限制,來禁止不必要的請(qǐng)求,以免資源的浪費(fèi)~

舉一個(gè)🌰 業(yè)務(wù)場(chǎng)景

概念:

關(guān)于防抖函數(shù)的介紹

關(guān)于addEventListener

使用示例:

    function debounce(fn) {
        let timeout = null; // 創(chuàng)建一個(gè)標(biāo)記用來存放定時(shí)器的返回值
        return function () {
            clearTimeout(timeout); // 每當(dāng)用戶輸入的時(shí)候把前一個(gè) setTimeout clear 掉
            timeout = setTimeout(() => {
                // 然后又創(chuàng)建一個(gè)新的 setTimeout, 這樣就能保證輸入字符后的
                // interval 間隔內(nèi)如果還有字符輸入的話,就不會(huì)執(zhí)行 fn 函數(shù)
                fn.apply(this, arguments);
            }, 500);
        };
    }
    function sayHi() {
        console.log('防抖成功');
    }

    var inp = document.getElementById('inp');
    inp.addEventListener('input', debounce(sayHi)); // 防抖

在vue中使用?

首先說一下之前的踩坑行為

下面的代碼為簡(jiǎn)易版的一個(gè)場(chǎng)景

function debounce(fn) {
        let timeout = null; // 創(chuàng)建一個(gè)標(biāo)記用來存放定時(shí)器的返回值
        return function () {
            clearTimeout(timeout); // 每當(dāng)用戶輸入的時(shí)候把前一個(gè) setTimeout clear 掉
            timeout = setTimeout(() => {
                // 然后又創(chuàng)建一個(gè)新的 setTimeout, 這樣就能保證輸入字符后的
                // interval 間隔內(nèi)如果還有字符輸入的話,就不會(huì)執(zhí)行 fn 函數(shù)
                fn.apply(this, arguments);
            }, 500);
        };
   }

錯(cuò)誤的使用方式

<template>
    <div class="search-view">
        <div class="header">
            <Search 
                class="search-box" 
                v-model='searchValue' 
                @input='getSearchResult' 
                placeholder='搜索想要的好物' />
            <span @click="goBack" class="cancel">取消</span>
        </div>
        <div class="serach-view-content" />
    </div>

</template>

<script>
import Search from './components/Search';
import debounce from './config';

export default {
    name: 'SearchView',
    components: {
        Search
    },
    data() {
        return {
            searchValue: ''
        };
    },
    methods: {
        getSearchResult() {
            debounce(function() {
                console.log(this.searchValue);
            })();
        }
    }
};
</script>

為什么錯(cuò)誤?

源碼層級(jí)分析

vue模板編譯 的解析事件

export const onRE = /^@|^v-on:/
export const dirRE = /^v-|^@|^:/

function processAttrs (el) {
  const list = el.attrsList
  let i, l, name, value, modifiers
  for (i = 0, l = list.length; i < l; i++) {
    name  = list[i].name
    value = list[i].value
    if (dirRE.test(name)) {
      // 解析修飾符
      modifiers = parseModifiers(name)
      if (modifiers) {
        name = name.replace(modifierRE, '')
      }
      if (onRE.test(name)) { // v-on
        name = name.replace(onRE, '')
        addHandler(el, name, value, modifiers, false, warn)
      }
    }
  }
}

總結(jié): 實(shí)例初始化階段調(diào)用的初始化事件函數(shù)initEvents實(shí)際上初始化的是父組件在模板中使用v-on或@注冊(cè)的監(jiān)聽子組件內(nèi)觸發(fā)的事件

vue的事件機(jī)制

Vue.prototype.$on = function(event, fn) {
    const vm = this;
    if (Array.isArray(event)) {
        for (let i = 0; i < event.length; i++) {
            this.$on(event[i], fn);
        }
    } else {
        //這個(gè)_events屬性就是用來作為當(dāng)前實(shí)例的事件中心,所有綁定在這個(gè)實(shí)例上的事件都會(huì)存儲(chǔ)在事件中心_events屬性中。
        (vm._events[event] || (vm._events[event] = [])).push(fn);
    }
    return vm;
};

Vue.prototype.$emit = function(event) {
    const vm = this;
    let cbs = vm._events[event];
    if (cbs) {
        cbs = cbs.length > 1 ? toArray(cbs) : cbs;
        let args = toArray(arguments, 1);
        for (let i = 0; i < cbs.length; i++) {
            try {
                cbs[i].apply(vm, args);
            } catch (e) {
                handleError(e, vm, `event handler for "${event}"`);
            }
        }
    }
    return vm;
};

vue的initState中 調(diào)用了initMethods方法

initMethods中掛在methods方法到this上

for (const key in methods) {
        if (process.env.NODE_ENV !== 'production') {
            if (methods[key] == null) {
                warn(
                    `Method "${key}" has an undefined value in the component definition. ` +
                        `Did you reference the function correctly?`,
                    vm
                );
            }
            // 如果和props中某個(gè)屬性名重名了 拋出異常
            if (props && hasOwn(props, key)) {
                warn(`Method "${key}" has already been defined as a prop.`, vm);
            }
            /*
            如果methods中某個(gè)方法名如果在實(shí)例vm中已經(jīng)存在并且方法名是以_或$開頭的,就拋出異常:
            提示用戶方法名命名不規(guī)范
            */
            if (key in vm && isReserved(key)) {
                warn(
                    `Method "${key}" conflicts with an existing Vue instance method. ` +
                        `Avoid defining component methods that start with _ or $.`
                );
            }
            // 將method綁定到實(shí)例 vm上  這樣我們就可以通過this.xxx 來訪問了
            // 同時(shí)如果在vue中  let m1 = this.xxx  m1() this也指向vue
            vm[key] = methods[key] == null ? noop : bind(methods[key], vm);
        }

劃重點(diǎn):

  • 子組件$emit('input事件')
  • 父組件接收事件
getSearchResult.apply(this, agrs)
<===>  apply的調(diào)用可以寫成下面的形式
this.getSearchResult(args)

// 進(jìn)而變成這種執(zhí)行
debounce(function() {
      console.log(this.searchValue);
})();

// 這里的debounce 返回了一個(gè)函數(shù) 于是變成
(function (fn) {
      clearTimeout(timeout); // 每當(dāng)用戶輸入的時(shí)候把前一個(gè) setTimeout clear 掉
      timeout = setTimeout(() => {
          // 然后又創(chuàng)建一個(gè)新的 setTimeout, 這樣就能保證輸入字符后的
          // interval 間隔內(nèi)如果還有字符輸入的話,就不會(huì)執(zhí)行 fn 函數(shù)
          fn.apply(this, arguments);
      }, 500);
})()
// 到這里  其實(shí)就變成了匿名函數(shù)的自執(zhí)行
// 由于每次觸發(fā)input都會(huì)返回一個(gè)新的匿名函數(shù)  生成一個(gè)新的函數(shù)執(zhí)行棧  所以防抖失效~

那么應(yīng)該如何調(diào)用

<template>
    <div class="search-view">
        <div class="header">
            <Search
                class="search-box"
                v-model='searchValue'
                @input='getSearchResult()'
                placeholder='搜索想要的好物'
            />
            <span
                @click="goBack"
                class="cancel">取消</span>
        </div>
        <div class="serach-view-content">
            
        </div>
    </div>

</template>

<script>
import debounce from 'lodash.debounce';
export default {
    name: 'SearchView',
    components: {
        Search,
    },
    data() {
        return {
            searchValue: '',
        };
    },
    methods: {
        getSearchResult: debounce(function () {
            console.log(this.searchValue);
        }, 500),
    },

};
</script>

分析執(zhí)行過程

getSearchResult().apply(this, args)
<===> 忽略參數(shù)行為 只關(guān)注執(zhí)行棧

let func = function () {
    clearTimeout(timeout); // 每當(dāng)用戶輸入的時(shí)候把前一個(gè) setTimeout clear 掉
    timeout = setTimeout(() => {
        // 然后又創(chuàng)建一個(gè)新的 setTimeout, 這樣就能保證輸入字符后的
        // interval 間隔內(nèi)如果還有字符輸入的話,就不會(huì)執(zhí)行 fn 函數(shù)
        fn.apply(this, arguments);
    }, 500);
};

this.func(args)

<===>

子組件觸發(fā)input的行為  返回的始終是一個(gè)同一個(gè)函數(shù)體  防抖成功

類比于文章開始時(shí)介紹的addEventListener

總結(jié)

到此這篇關(guān)于vue使用節(jié)流函數(shù)踩坑的文章就介紹到這了,更多相關(guān)vue節(jié)流函數(shù)踩坑內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Pinia進(jìn)階setup函數(shù)式寫法封裝到企業(yè)項(xiàng)目

    Pinia進(jìn)階setup函數(shù)式寫法封裝到企業(yè)項(xiàng)目

    這篇文章主要為大家介紹了Pinia進(jìn)階setup函數(shù)式寫法封裝到企業(yè)項(xiàng)目實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • vue3搭配pinia的踩坑實(shí)戰(zhàn)記錄

    vue3搭配pinia的踩坑實(shí)戰(zhàn)記錄

    Pinia是一個(gè)同時(shí)支持Vue2和Vue3的應(yīng)用狀態(tài)管理工具,簡(jiǎn)單來說就是為了管理整個(gè)應(yīng)用中的響應(yīng)式數(shù)據(jù),解決各個(gè)組件交互時(shí)數(shù)據(jù)狀態(tài)的不好管理的問題,下面這篇文章主要給大家介紹了關(guān)于vue3搭配pinia踩坑的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • Vue 2.X的狀態(tài)管理vuex記錄詳解

    Vue 2.X的狀態(tài)管理vuex記錄詳解

    這篇文章主要介紹了Vue 2.X的狀態(tài)管理vuex記錄的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家的理解和學(xué)習(xí)具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-03-03
  • ElementUI表格中添加表頭圖標(biāo)懸浮提示

    ElementUI表格中添加表頭圖標(biāo)懸浮提示

    本文主要介紹了ElementUI表格中添加表頭圖標(biāo)懸浮提示,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Vue導(dǎo)出頁(yè)面為PDF格式的實(shí)現(xiàn)思路

    Vue導(dǎo)出頁(yè)面為PDF格式的實(shí)現(xiàn)思路

    這篇文章主要介紹了Vue導(dǎo)出頁(yè)面為PDF格式的實(shí)現(xiàn)思路,其實(shí)思路也很簡(jiǎn)單,就是將頁(yè)面轉(zhuǎn)換成圖片格式.然后通過圖片的base64碼.生成PDF..感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-07-07
  • vue2.0數(shù)據(jù)雙向綁定與表單bootstrap+vue組件

    vue2.0數(shù)據(jù)雙向綁定與表單bootstrap+vue組件

    這篇文章主要介紹了vue2.0數(shù)據(jù)雙向綁定與表單bootstrap+vue組件,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • Vue?elementUI表單嵌套表格并對(duì)每行進(jìn)行校驗(yàn)詳解

    Vue?elementUI表單嵌套表格并對(duì)每行進(jìn)行校驗(yàn)詳解

    element-ui中有詳細(xì)的各種表格及表格方法,下面這篇文章主要給大家介紹了關(guān)于Vue?elementUI表單嵌套表格并對(duì)每行進(jìn)行校驗(yàn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • vue項(xiàng)目接口管理,所有接口都在apis文件夾中統(tǒng)一管理操作

    vue項(xiàng)目接口管理,所有接口都在apis文件夾中統(tǒng)一管理操作

    這篇文章主要介紹了vue項(xiàng)目接口管理,所有接口都在apis文件夾中統(tǒng)一管理操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • js 實(shí)現(xiàn)拖拽排序詳情

    js 實(shí)現(xiàn)拖拽排序詳情

    這篇文章主要介紹了js 實(shí)現(xiàn)拖拽排序,拖拽排序?qū)τ谛』锇閭儊碚f應(yīng)該不陌生,平時(shí)工作的時(shí)候,可能會(huì)選擇使用類似Sortable.js這樣的開源庫(kù)來實(shí)現(xiàn)需求。但在完成需求后,大家有沒有沒想過拖拽排序是如何實(shí)現(xiàn)的呢?感興趣得話一起來看看下面文章得小心內(nèi)容吧
    2021-11-11
  • vue中el-table多層級(jí)嵌套的具體實(shí)現(xiàn)

    vue中el-table多層級(jí)嵌套的具體實(shí)現(xiàn)

    本文主要介紹了vue中el-table多層級(jí)嵌套的具體實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-10-10

最新評(píng)論

枣强县| 磐石市| 和顺县| 龙川县| 桦川县| 宁城县| 景宁| 洮南市| 饶阳县| 历史| 阿图什市| 诸城市| 航空| 仲巴县| 衡阳市| 濮阳市| 铜山县| 湄潭县| 神池县| 宁远县| 宜君县| 法库县| 韩城市| 宁武县| 界首市| 繁昌县| 会昌县| 宣恩县| 徐闻县| 甘泉县| 安多县| 元朗区| 松原市| 河间市| 胶州市| 武宁县| 孝昌县| 蒲城县| 梧州市| 永春县| 漳州市|