文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue使用节流函数会遇到什么问题

2023-06-15 03:43

关注

小编给大家分享一下vue使用节流函数会遇到什么问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

举一个? 业务场景

vue使用节流函数会遇到什么问题

概念:

关于防抖函数的介绍

关于addEventListener

使用示例:

function debounce(fn) {        let timeout = null; // 创建一个标记用来存放定时器的返回值        return function () {            clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉            timeout = setTimeout(() => {                // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的                // interval 间隔内如果还有字符输入的话,就不会执行 fn 函数                fn.apply(this, arguments);            }, 500);        };    }    function sayHi() {        console.log('防抖成功');    }    var inp = document.getElementById('inp');    inp.addEventListener('input', debounce(sayHi)); // 防抖

在vue中使用?

首先说一下之前的踩坑行为

下面的代码为简易版的一个场景

function debounce(fn) {        let timeout = null; // 创建一个标记用来存放定时器的返回值        return function () {            clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉            timeout = setTimeout(() => {                // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的                // interval 间隔内如果还有字符输入的话,就不会执行 fn 函数                fn.apply(this, arguments);            }, 500);        };   }

错误的使用方式

<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>

为什么错误?

源码层级分析

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

总结: 实例初始化阶段调用的初始化事件函数initEvents实际上初始化的是父组件在模板中使用v-on或@注册的监听子组件内触发的事件

vue的事件机制

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 {        //这个_events属性就是用来作为当前实例的事件中心,所有绑定在这个实例上的事件都会存储在事件中心_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中 调用了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中某个属性名重名了 抛出异常            if (props && hasOwn(props, key)) {                warn(`Method "${key}" has already been defined as a prop.`, vm);            }                        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绑定到实例 vm上  这样我们就可以通过this.xxx 来访问了            // 同时如果在vue中  let m1 = this.xxx  m1() this也指向vue            vm[key] = methods[key] == null ? noop : bind(methods[key], vm);        }

划重点:

getSearchResult.apply(this, agrs)<===>  apply的调用可以写成下面的形式this.getSearchResult(args)// 进而变成这种执行debounce(function() {      console.log(this.searchValue);})();// 这里的debounce 返回了一个函数 于是变成(function (fn) {      clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉      timeout = setTimeout(() => {          // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的          // interval 间隔内如果还有字符输入的话,就不会执行 fn 函数          fn.apply(this, arguments);      }, 500);})()// 到这里  其实就变成了匿名函数的自执行// 由于每次触发input都会返回一个新的匿名函数  生成一个新的函数执行栈  所以防抖失效~

那么应该如何调用

<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>

分析执行过程

getSearchResult().apply(this, args)<===> 忽略参数行为 只关注执行栈let func = function () {    clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉    timeout = setTimeout(() => {        // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的        // interval 间隔内如果还有字符输入的话,就不会执行 fn 函数        fn.apply(this, arguments);    }, 500);};this.func(args)<===>

子组件触发input的行为  返回的始终是一个同一个函数体  防抖成功

Vue的优点

Vue具体轻量级框架、简单易学、双向数据绑定、组件化、数据和结构的分离、虚拟DOM、运行速度快等优势,Vue中页面使用的是局部刷新,不用每次跳转页面都要请求所有数据和dom,可以大大提升访问速度和用户体验。

以上是“vue使用节流函数会遇到什么问题”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯