Vue2에서 디바운스를 구현하는 방법?
나는 Vue 템플릿에 간단한 입력란을 가지고 있는데, 나는 디바운스를 거의 이와 같이 사용하고 싶다.
<input type="text" v-model="filterKey" debounce="500">
하지만, 그debounce
Vue 2에서는 속성이 더 이상 사용되지 않았다.권장 사항에는 "v-on:input + 타사 디바운스 기능 사용"이라고만 나와 있다.
어떻게 그것을 올바르게 구현하는가?
lodash, v-on:input, v-model을 사용하여 구현해 보았지만 추가 변수 없이 구현이 가능한지 궁금하다.
템플릿:
<input type="text" v-on:input="debounceInput" v-model="searchInput">
스크립트에서:
data: function () {
return {
searchInput: '',
filterKey: ''
}
},
methods: {
debounceInput: _.debounce(function () {
this.filterKey = this.searchInput;
}, 500)
}
그런 다음 필터 키가 나중에 사용됨computed
소품
디바운스 NPM 패키지를 사용하여 다음과 같이 구현한다.
<input @input="debounceInput">
methods: {
debounceInput: debounce(function (e) {
this.$store.dispatch('updateInput', e.target.value)
}, config.debouncers.default)
}
로다시와 질문의 예를 사용하여, 구현은 다음과 같이 보인다.
<input v-on:input="debounceInput">
methods: {
debounceInput: _.debounce(function (e) {
this.filterKey = e.target.value;
}, 500)
}
옵션 1: 재사용 가능, 디프 없음
- 프로젝트에 두 번 이상 필요한 경우 권장
/helpers.js
export function debounce (fn, delay) {
var timeoutID = null
return function () {
clearTimeout(timeoutID)
var args = arguments
var that = this
timeoutID = setTimeout(function () {
fn.apply(that, args)
}, delay)
}
}
/구성요소.부에를 하다
<script>
import {debounce} from './helpers'
export default {
data () {
return {
input: '',
debouncedInput: ''
}
},
watch: {
input: debounce(function (newVal) {
this.debouncedInput = newVal
}, 500)
}
}
</script>
옵션 2: 구성 요소 내, 디프 없음
- 한 번 사용하거나 소규모 프로젝트에서 사용할 경우 권장
/구성요소.부에를 하다
<template>
<input type="text" v-model="input" />
</template>
<script>
export default {
data: {
timeout: null,
debouncedInput: ''
},
computed: {
input: {
get() {
return this.debouncedInput
},
set(val) {
if (this.timeout) clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
this.debouncedInput = val
}, 300)
}
}
}
}
</script>
디바인 할당 중methods
문제가 될 수 있다.그래서 이것 대신에:
// Bad
methods: {
foo: _.debounce(function(){}, 1000)
}
다음을 시도해 보십시오.
// Good
created () {
this.foo = _.debounce(function(){}, 1000);
}
구성 요소 인스턴스가 여러 개 있을 경우 문제가 됨(방식과 유사함)data
물체를 반환하는 함수여야 한다.각 사례는 독립적으로 행동해야 하는 경우 자체적인 디바운스 기능이 필요하다.
문제의 예는 다음과 같다.
Vue.component('counter', {
template: '<div>{{ i }}</div>',
data: function(){
return { i: 0 };
},
methods: {
// DON'T DO THIS
increment: _.debounce(function(){
this.i += 1;
}, 1000)
}
});
new Vue({
el: '#app',
mounted () {
this.$refs.counter1.increment();
this.$refs.counter2.increment();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<div id="app">
<div>Both should change from 0 to 1:</div>
<counter ref="counter1"></counter>
<counter ref="counter2"></counter>
</div>
하숙 없이 매우 단순함
handleScroll: function() {
if (this.timeout)
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
// your action
}, 200); // delay
}
나도 같은 문제가 있었는데 여기 플러그 인 없이 작동하는 솔루션이 있어.
이후<input v-model="xxxx">
와 정확히 같다
<input
v-bind:value="xxxx"
v-on:input="xxxx = $event.target.value"
>
xxxx의 할당에 대해 디바운스 함수를 설정할 수 있다고 생각했다.xxxx = $event.target.value
이것처럼.
<input
v-bind:value="xxxx"
v-on:input="debounceSearch($event.target.value)"
>
방법:
debounceSearch(val){
if(search_timeout) clearTimeout(search_timeout);
var that=this;
search_timeout = setTimeout(function() {
that.xxxx = val;
}, 400);
},
만약 당신이 이것에 대해 아주 미니멀한 접근법을 필요로 한다면, 나는 여기서 이용할 수 있는 하나를 만들었다. https://www.npmjs.com/package/v-debounce
사용량:
<input v-model.lazy="term" v-debounce="delay" placeholder="Search for something" />
그런 다음 구성 요소에서 다음을 수행하십시오.
<script>
export default {
name: 'example',
data () {
return {
delay: 1000,
term: '',
}
},
watch: {
term () {
// Do something with search term after it debounced
console.log(`Search term changed to ${this.term}`)
}
},
directives: {
debounce
}
}
</script>
이 답변은 수락된 답변보다 먼저 게시한 것에 유의하십시오.그건 옳지 않아.문제의 해결책에서 한 발짝만 앞서 나간 것이다.나는 저자의 구현과 내가 사용한 최종 구현을 보여주기 위해 합격된 질문을 편집했다.
코멘트와 링크된 마이그레이션 문서에 따라 다음 코드를 몇 가지 변경했다.
템플릿:
<input type="text" v-on:input="debounceInput" v-model="searchInput">
스크립트에서:
watch: {
searchInput: function () {
this.debounceInput();
}
},
그리고 필터 키를 설정하는 방법은 그대로 유지된다.
methods: {
debounceInput: _.debounce(function () {
this.filterKey = this.searchInput;
}, 500)
}
이것은 전화가 한 통 덜 걸려온 것 같다.v-model
, 그리고 그.v-on:input
).
하숙집과 함께 동적 지연을 적용해야 할 경우debounce
함수:
props: {
delay: String
},
data: () => ({
search: null
}),
created () {
this.valueChanged = debounce(function (event) {
// Here you have access to `this`
this.makeAPIrequest(event.target.value)
}.bind(this), this.delay)
},
methods: {
makeAPIrequest (newVal) {
// ...
}
}
템플릿:
<template>
//...
<input type="text" v-model="search" @input="valueChanged" />
//...
</template>
참고: 위의 예에서 나는 API를 호출할 수 있는 검색 입력의 예를 만들었는데, API는 다음과 같이 사용자 지정 지연으로 제공된다.props
비록 여기 있는 거의 모든 해답은 이미 정확하지만, 만약 누군가 빠른 해결책을 찾고 있다면, 나는 이것에 대한 지침을 가지고 있다.https://www.npmjs.com/package/vue-lazy-input
@input 및 v-model에 적용되며, 사용자 지정 구성 요소와 DOM 요소, 디바운스 및 스로틀을 지원한다.
Vue.use(VueLazyInput)
new Vue({
el: '#app',
data() {
return {
val: 42
}
},
methods:{
onLazyInput(e){
console.log(e.target.value)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/lodash/lodash.min.js"></script><!-- dependency -->
<script src="https://unpkg.com/vue-lazy-input@latest"></script>
<div id="app">
<input type="range" v-model="val" @input="onLazyInput" v-lazy-input /> {{val}}
</div>
디버깅된 메소드를 만들려면 컴퓨터 사용법을 구성 요소의 여러 인스턴스 간에 공유하지 마십시오.
<template>
<input @input="handleInputDebounced">
<template>
<script>
import debounce from 'lodash.debouce';
export default {
props: {
timeout: {
type: Number,
default: 200,
},
},
methods: {
handleInput(event) {
// input handling logic
},
},
computed: {
handleInputDebounced() {
return debounce(this.handleInput, this.timeout);
},
},
}
</script>
통제할 수 없는 상태로 작동시킬 수 있다.v-model
또한:
<template>
<input v-model="debouncedModel">
<template>
<script>
import debounce from 'lodash.debouce';
export default {
props: {
value: String,
timeout: {
type: Number,
default: 200,
},
},
methods: {
updateValue(value) {
this.$emit('input', value);
},
},
computed: {
updateValueDebounced() {
return debounce(this.updateValue, this.timeout);
},
debouncedModel: {
get() { return this.value; },
set(value) { this.updateValueDebounced(value); }
},
},
}
</script>
만약 당신이 Vue를 사용하고 있다면 당신은 또한 사용할 수 있다.v.model.lazy
대신에debounce
하지만 기억해라v.model.lazy
Vue가 사용자 지정 구성 요소에 대해 제한하므로 항상 작동하지 않음
사용자 지정 구성 요소의 경우:value
와 함께@change.native
<b-input :value="data" @change.native="data = $event.target.value" ></b-input>
1 화살표 기능을 사용한 짧은 버전(기본 지연 값 포함)
file: debounce.js in ex: (수입 디바운스 '../../utils/proutcounts' )
export default function (callback, delay=300) {
let timeout = null
return (...args) => {
clearTimeout(timeout)
const context = this
timeout = setTimeout(() => callback.apply(context, args), delay)
}
}
2 믹신 옵션
파일: 디바운스믹신.js
export default {
methods: {
debounce(func, delay=300) {
let debounceTimer;
return function() {
// console.log("debouncing call..");
const context = this;
const args = arguments;
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => func.apply(context, args), delay);
// console.log("..done");
};
}
}
};
vueComponent에서 사용:
<script>
import debounceMixin from "../mixins/debounceMixin";
export default {
mixins: [debounceMixin],
data() {
return {
isUserIdValid: false,
};
},
mounted() {
this.isUserIdValid = this.debounce(this.checkUserIdValid, 1000);
},
methods: {
isUserIdValid(id){
// logic
}
}
</script>
다른 옵션, 예
나는 거의 실행하지 않고 디바운드를 사용할 수 있었다.
나는 부스트랩-뷰와 함께 Vue 2.6.14를 사용하고 있다.
이 pkg을 너의 패키지에 추가해라.json: https://www.npmjs.com/package/debounce
이것을 main.js:
import { debounce } from "debounce";
Vue.use(debounce);
내 구성 요소에는 다음과 같은 입력이 있다.
<b-form-input
debounce="600"
@update="search()"
trim
id="username"
v-model="form.userName"
type="text"
placeholder="Enter username"
required
>
</b-form-input>
검색() 메서드를 호출하고 검색 메서드는 검색을 수행하기 위해 양식.userName을(를) 사용한다.
디바운스 기능의 실행을 클래스 메서드로 이동할 수 있는 경우, 유틸리티 디코더 lib에서 장식가를 사용할 수 있다(npm install --save utils-decorators
):
import {debounce} from 'utils-decorators';
class SomeService {
@debounce(500)
getData(params) {
}
}
public debChannel = debounce((key) => this.remoteMethodChannelName(key), 200)
부에아제네이터
참조URL: https://stackoverflow.com/questions/42199956/how-to-implement-debounce-in-vue2
'IT이야기' 카테고리의 다른 글
reactive native app를 만들 수 없음입력이 필요하지만 엑스포가 비인터랙티브 모드에 있음 (0) | 2022.03.22 |
---|---|
Vue.js의 URL에서 쿼리 매개 변수를 가져오는 방법 (0) | 2022.03.22 |
VueJs에서 기능별로 키 누름 처리 (0) | 2022.03.22 |
반응-Native FlexDirection: 여러 줄로 '행' (0) | 2022.03.22 |
@click과 v-on의 차이:Vuejs 클릭 (0) | 2022.03.22 |