> 웹 프론트엔드 > View.js > Vue 구성 요소에서 손떨림 방지 및 조절을 사용하는 방법에 대한 간략한 분석

Vue 구성 요소에서 손떨림 방지 및 조절을 사용하는 방법에 대한 간략한 분석

青灯夜游
풀어 주다: 2021-11-25 19:41:39
앞으로
2756명이 탐색했습니다.

Vue 구성 요소에서 손떨림 방지 및 조절을 어떻게 사용하나요? 다음 기사에서는 예제를 통해 Vue 구성 요소에서 손떨림 방지 및 조절 제어 관찰자와 이벤트 핸들러를 사용하는 방법을 보여줍니다.

Vue 구성 요소에서 손떨림 방지 및 조절을 사용하는 방법에 대한 간략한 분석

사용자 입력 상자 입력, 창 크기 조정, 스크롤, 교차점 관찰자 이벤트 등 자주 발생하는 이벤트를 모니터링할 때는 주의하세요.

이러한 이벤트는 항상 자주 발생하며, 몇 초에 한 번씩 발생합니다. 모든 이벤트에 대해 가져오기 요청(또는 유사한 동작)을 발행하는 것은 현명하지 않습니다.

우리가 해야 할 일은 이벤트 핸들러의 실행 속도를 늦추는 것뿐입니다. 이 버퍼링 기술은 디바운스 및 스로틀링입니다.

이 기사에서는 손떨림 방지 및 제한을 사용하여 Vue 구성 요소에서 감시자와 이벤트 처리기를 제어하는 ​​방법을 배웁니다. [관련 권장 사항: "vue.js Tutorial"]

1. Observer anti-shake

우리의 작업은 사용자가 텍스트 상자에 입력한 텍스트를 콘솔에 출력하는 것입니다.

<template>
  <input v-model="value" type="text" />
  <p>{{ value }}</p>
</template>
<script>
export default {
  data() {
    return {
      value: "",
    };
  },
  watch: {
    value(newValue, oldValue) {
      console.log("Value changed: ", newValue);
    }
  }
};
</script>
로그인 후 복사

데모 열기:

https://codesandbox.io/s/vue-input-szgn1?file=/src/App.vue

데모를 열고 입력 상자에 몇 글자를 입력하세요. 입력될 때마다 값이 콘솔에 기록됩니다.

우리는 데이터 속성을 수신하는 감시자를 사용하여 로그 인쇄를 구현합니다. 그러나 관찰자의 콜백에 매개변수로 value를 사용하여 GET 요청을 포함하려는 경우 요청을 너무 자주 수행할 것으로 예상해서는 안 됩니다.

value 数据属性 来实现了打印日志。但如果你想在 观察者的回调 中加入一个 使用 value 作为参数 的 GET 请求,那你应该不会期望太过频繁地发起请求。

我们来对 打印控制台日志 这个行为做一下 防抖。核心思想是创建一个 防抖函数,然后在 观察者 内部调用该函数。

我在这里选择了 &#39;lodash.debounce&#39; 的 防抖实现,但你可以自由选择喜欢的实现方式。

我们来将 防抖逻辑 应用到组件:

<template>
  <input v-model="value" type="text" />
  <p>{{ value }}</p>
</template>
<script>
import debounce from "lodash.debounce";
export default {
  data() {
    return {
      value: "",
    };
  },
  watch: {
    value(...args) {
      this.debouncedWatch(...args);
    },
  },
  created() {
    this.debouncedWatch = debounce((newValue, oldValue) => {
      console.log(&#39;New value:&#39;, newValue);
    }, 500);
  },
  beforeUnmount() {
    this.debouncedWatch.cancel();
  },
};
</script>
로그인 후 복사

试试 demo

https://codesandbox.io/s/vue-input-debounced-4vwex?file=/src/App.vue

如果你打开这个 demo,你会发现其实从用户角度来看,变化不大:你依旧可以像上一个 demo 中一样自由输入字符。

但有一个区别:只有在最后一次输入的 500ms 之后,才会将新的输入值打印日志到控制台。这说明 防抖 在生效。

观察者 的 防抖实现 只需要 3 个简单步骤:

  • create() 钩子 里,创建 防抖回调,并将其赋值到实例上:this.debouncedWatch = debounce(..., 500)

  • 在 观察者 回调 watch.value() { ... } 中 传入正确的参数 调用 this.debouncedWatch()

  • 最后,beforeUnmount() 钩子中 调用 this.debouncedWatch.cancel() ,在卸载组件之前,取消所有还在 pending 的 防抖函数执行。

采用同样的方式,你可以对任意数据属性的 观察者 应用 防抖。然后就可以安全执行 防抖回调内部的一些比较重的操作,比如 网络请求、繁重的 DOM 操作,等等。

2. 事件处理器 防抖

上面一节,我展示了如何对 观察者 使用 防抖,那么常规的事件处理器呢?

我们重用之前用户输入数据到输入框的例子,但这一次会给输入框加个 事件处理器。

像往常一样,如果你没有采取任何缓冲的措施,每当值被修改时,会被打印到控制台:

<template>
  <input v-on:input="handler" type="text" />
</template>
<script>
export default {
  methods: {
    handler(event) {
      console.log(&#39;New value:&#39;, event.target.value);
    }
  }
};
</script>
로그인 후 복사

试试 demo:

https://codesandbox.io/s/vue-event-handler-plls4?file=/src/App.vue

打开这个 demo,在输入框打几个字符。看看控制台:你会发现每次你输入的时候就会有日志被打印出来。

同样,如果你会执行一些比较重的操作(比如网络请求),可就不合适了。

对 事件处理器 使用 防抖,可以参考下面这个:

<template>
  <input v-on:input="debouncedHandler" type="text" />
</template>
<script>
import debounce from "lodash.debounce";
export default {
  created() {
    this.debouncedHandler = debounce(event => {
      console.log(&#39;New value:&#39;, event.target.value);
    }, 500);
  },
  beforeUnmount() {
    this.debouncedHandler.cancel();
  }
};
</script>
로그인 후 복사

试试 demo:

https://codesandbox.io/s/vue-event-handler-debounced-973vn?file=/src/App.vue

打开 demo,输入一些字符。组件只有在最后一次输入的 500ms 之后,才会将新的输入值打印日志到控制台。防抖 再一次生效了!

事件处理器 的 防抖实现 只需要 3 个步骤:

  • .在 create() 钩子 里,创建实例后,立刻将 防抖回调 debounce(event => {...}, 500) 赋值到 this.debouncedHandler콘솔 로그 인쇄 동작에 흔들림 방지를 적용해 보겠습니다. 핵심 아이디어는 디바운스 함수를 만든 다음 관찰자 내에서 해당 함수를 호출하는 것입니다.

    🎜여기에서는 'lodash.debounce'의 손떨림 방지 구현을 선택했지만 원하는 구현을 자유롭게 선택할 수 있습니다. 🎜🎜디바운스 로직을 구성 요소에 적용해 보겠습니다. 🎜
    // ...
      methods: {
        // Why not?
        debouncedHandler: debounce(function () { ... }}, 500)
      }
    // ...
    로그인 후 복사
    로그인 후 복사
    🎜🎜데모를 사용해 보세요🎜🎜https://codesandbox.io/s/vue-input-debounced-4vwex?file=/src/App.vue🎜🎜🎜 이 데모를 열면 사용자 관점에서 볼 때 크게 변경된 사항이 없다는 것을 알 수 있습니다. 이전 데모에서처럼 여전히 자유롭게 문자를 입력할 수 있습니다. 🎜🎜하지만 한 가지 차이점이 있습니다. 새 입력 값은 마지막 입력 후 500ms만 콘솔에 기록됩니다. 이는 손떨림 방지가 적용되고 있음을 나타냅니다. 🎜🎜옵저버의 흔들림 방지 구현에는 간단한 3단계만 필요합니다: 🎜
    • 🎜 create() 후크에서, 반송 방지 콜백을 생성하고 이를 인스턴스에 할당합니다: this.debouncedWatch = debounce(..., 500). 🎜
    • 🎜관찰자 콜백 watch.value() { ... }에서 올바른 매개변수를 전달하고 this.debouncedWatch()를 호출하세요. 🎜
    • 🎜마지막으로 beforeUnmount() 후크에서 this.debouncedWatch.cancel()을 호출하여 구성 요소를 제거하기 전에 보류 중인 모든 구성 요소를 취소하세요. 손떨림 방지 기능이 실행됩니다. 🎜
    🎜같은 방식으로 모든 데이터 속성의 관찰자에게 흔들림 방지를 적용할 수 있습니다. 그러면 흔들림 방지 콜백 내에서 네트워크 요청, 과도한 DOM 작업 등과 같은 일부 무거운 작업을 안전하게 수행할 수 있습니다. 🎜

    2. 이벤트 핸들러 흔들림 방지🎜🎜위 섹션에서는 관찰자를 위한 흔들림 방지 사용 방법을 설명했지만 일반 이벤트 핸들러는 어떻습니까? 🎜🎜사용자가 입력 상자에 데이터를 입력하는 이전 예제를 재사용하지만 이번에는 입력 상자에 이벤트 핸들러를 추가하겠습니다. 🎜🎜평소처럼 버퍼링 조치를 취하지 않으면 값이 수정될 때마다 콘솔에 인쇄됩니다. 🎜
    <template>
      <input v-on:input="debouncedHandler" type="text" />
    </template>
    <script>
    import debounce from "lodash.debounce";
    export default {
      methods: {
        // Don&#39;t do this!
        debouncedHandler: debounce(function(event) {
          console.log(&#39;New value:&#39;, event.target.value);
        }, 500)
      }
    };
    </script>
    로그인 후 복사
    로그인 후 복사
    🎜🎜데모 사용해 보기: 🎜🎜https://codesandbox.io/s/vue - event-handler-plls4?file=/src/App.vue🎜🎜🎜이 데모를 열고 입력 상자에 몇 글자를 입력하세요. 콘솔을 살펴보면 입력할 때마다 로그가 인쇄되는 것을 확인할 수 있습니다. 🎜🎜마찬가지로, 일부 무거운 작업(예: 네트워크 요청)을 수행하는 경우에는 적합하지 않습니다. 🎜🎜이벤트 핸들러에서 손떨림 방지를 사용하려면 다음을 참조하세요. 🎜
    // ...
      created() {
        this.debouncedCallback = debounce((...args) => {
          // The debounced callback
        }, 500);
      },
    // ...
    로그인 후 복사
    로그인 후 복사
    🎜🎜데모 사용해 보기: 🎜🎜https://codesandbox.io/s/vue-event-handler-debounced-973vn?file =/src/ App.vue🎜🎜🎜데모를 열고 문자를 입력하세요. 구성요소는 마지막 입력 후 500ms만 콘솔에 새 입력 값을 기록합니다. 흔들림 방지 기능이 다시 작동합니다! 🎜🎜이벤트 핸들러의 흔들림 방지 구현에는 3단계만 필요합니다: 🎜
    • 🎜 create() 후크에서. , 인스턴스를 생성한 후 즉시 디바운스 콜백 debounce(event => {...}, 500)this.debouncedHandler에 할당하세요. 🎜
    • 在输入框的 template 中 给 v-on:input 赋上 debouncedHandler<input v-on:input="debouncedHandler" type="text" />

    • 最后,在卸载组件之前, 在 beforeUnmount() 钩子中 调用 this.debouncedHandler.cancel() ,取消所有还在 pending 的 函数调用。

    另一方面,这些例子应用了 防抖 的技术。然而,同样的方式可以以用于创建 节流函数。

    3. 注意

    你可能不理解:为什么不直接在 组件的 method 选项中创建 防抖函数,然后在 template 中调用这些方法作为事件处理器?

    // ...
      methods: {
        // Why not?
        debouncedHandler: debounce(function () { ... }}, 500)
      }
    // ...
    로그인 후 복사
    로그인 후 복사

    这比在实例对象上创建 防抖函数 要简单的多。

    例如:

    <template>
      <input v-on:input="debouncedHandler" type="text" />
    </template>
    <script>
    import debounce from "lodash.debounce";
    export default {
      methods: {
        // Don&#39;t do this!
        debouncedHandler: debounce(function(event) {
          console.log(&#39;New value:&#39;, event.target.value);
        }, 500)
      }
    };
    </script>
    로그인 후 복사
    로그인 후 복사

    试试 demo

    https://codesandbox.io/s/vue-event-handler-debounced-incorrectly-320ci?file=/src/App.vue

    这次不是在 created() 钩子 里创建 防抖回调了,而是将 防抖回调 赋给了 methods.debouncedHandler

    你如果试过 demo,你会发现是有效果的!

    问题是,组件使用 export default { ... } 导出的 options 对象,包括方法,会被组件实例重用。

    如果网页中有 2 个以上的组件实例,那么所有的组件都会应用 相同 的防抖函数 methods.debouncedHandler — 这会导致防抖出现故障。

    4. 总结

    在 Vue 中,可以很轻松的对 观察者 和 事件处理器 应用 防抖 和 节流。

    核心逻辑就是,在 created() 钩子 里,创建 防抖 或 节流 的回调,并赋值在实例上。

    // ...
      created() {
        this.debouncedCallback = debounce((...args) => {
          // The debounced callback
        }, 500);
      },
    // ...
    로그인 후 복사
    로그인 후 복사

    A)然后在观察者内部调用实例上的防抖函数:

    // ...
      watch: {
        value(...args) {
          this.debouncedCallback(...args);
        },
      },
    // ...
    로그인 후 복사

    B)或在 template 中设定一个事件处理器:

    <template>
      <input v-on:input="debouncedHandler" type="text" />
    </template>
    로그인 후 복사

    在这之后,每次调用 this.debouncedCallback(...args) ,就算执行频率非常高,内部的回调也能缓冲执行。

    你对 Vue 中的 防抖 和 节流 还什么问题吗?欢迎提问!

    更多编程相关知识,请访问:编程入门!!

    위 내용은 Vue 구성 요소에서 손떨림 방지 및 조절을 사용하는 방법에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿