programing

v-model 값을 변경할 때 @change 이벤트를 방지하는 방법

goodsources 2022. 7. 10. 21:25
반응형

v-model 값을 변경할 때 @change 이벤트를 방지하는 방법

Firebase(vue-fire 사용)에서 지원되는 Vue.js에서 자동 완성 메뉴를 구축하고 있습니다.목적은 사용자의 표시 이름을 입력하고 일치 레코드를 아래 div 목록에 표시하는 것입니다.

템플릿은 다음과 같습니다.

<b-form-input id="toUser"
    type="text"
    v-model="selectedTo"
    @change="searcher">
</b-form-input>

<div v-on:click="selectToUser(user)" class="userSearchDropDownResult" v-for="user in searchResult" v-if="showSearcherDropdown">{{ user.name }}</div>

잠재적인 일치를 클릭하면 필드의 값을 설정하고 일치 목록을 지우는 것이 목적입니다.

컴포넌트의 코드 부분은 다음과 같습니다.

computed: {
  /* method borrowed from Reddit user imGnarly: https://www.reddit.com/r/vuejs/comments/63w65c/client_side_autocomplete_search_with_vuejs/ */
  searcher() {
    let self = this;
    let holder = [];
    let rx = new RegExp(this.selectedTo, 'i');
    this.users.forEach(function (val, key) {
      if (rx.test(val.name) || rx.test(val.email)) {
        let obj = {}
        obj = val;
        holder.push(obj);
      } else {
        self.searchResult = 'No matches found';
      }
    })
    this.searchResult = holder;
    return this.selectedTo;
  },

  showSearcherDropdown() {
    if(this.searchResult == null) return false;
    if(this.selectedTo === '') return false;
    return true;
  }
},

methods: {
  selectToUser: function( user ) {
    this.newMessage.to = user['.key'];
    this.selectedTo = user.name;
    this.searchResult = null;
  }
}

자동 검색 기능은 입력 필드를 변경할 때마다 searcher() 함수가 호출되어 searchResult에 올바른 값이 입력됩니다.v-for works 및 div 목록이 표시됩니다.

div를 클릭하면 selectToUser(user)를 호출합니다.그러면 사용자 개체에서 콘솔로 세부 정보가 올바르게 보고됩니다.

단, 처음 클릭했을 때 콘솔에 예외가 표시되며 div가 지워지지 않습니다(searchResults를 null로 설정하기 때문에 사라집니다).

[Vue warn]: Error in event handler for "change": "TypeError: fns.apply is not a function"

found in

---> <BFormInput>
       <BFormGroup>
         <BTab>

TypeError: fns.apply is not a function
    at VueComponent.invoker (vue.esm.js?efeb:2004)
    at VueComponent.Vue.$emit (vue.esm.js?efeb:2515)
    at VueComponent.onChange (form-input.js?1465:138)
    at boundFn (vue.esm.js?efeb:190)
    at invoker (vue.esm.js?efeb:2004)
    at HTMLInputElement.fn._withTask.fn._withTask (vue.esm.js?efeb:1802)

두 번째 div를 클릭하면 오류가 없고 입력 값이 설정되고 div가 사라집니다.

그래서 나는 여기에 가치를 쓰는 것이 의심스럽다.selectedTo(요소의 v-model 개체이기도 함)가 @change 이벤트를 트리거합니다.두 번째 클릭 시 값은 이미 설정되어 있기 때문에 실제로는 변경되지 않습니다.따라서 searcher()에 대한 호출도 없고 오류도 없습니다.

원소가 초점을 잃었을 때도 이런 일이 일어난다는 걸 깨달았어요.

질문: 메서드를 통해 v-model 값을 변경할 때 @change 이벤트를 방지하려면 어떻게 해야 합니까?

(기타 정보: 패키지에 따라).json I는 vue 2.5.2에 있습니다.)

온:

<b-form-input id="toUser"
    type="text"
    v-model="selectedTo"
    @change="searcher">

"검색기"는 하나의 방법이어야 합니다.그때마다 호출되는 메서드b-component를 발행하다change이벤트입니다.

하지만 당신의 코드를 보니 방법이 아니라computed:

computed: {
  searcher() {
    ...
  },

  showSearcherDropdown() {
    ...
  }
},

methods: {
  selectToUser: function( user ) {
   ...
  }
}

그래서 언제?change이벤트가 발생하면 메서드가 아닌 것을 호출하려고 합니다(또는 존재하지 않는 메서드를 호출하려고 합니다).그래서 에러가 나는 거예요.

이제, 당신이 정말로 원하는 것은,searcher언제든지this.selectedTo그것을 얻기 위해서, 실제로 그것을 가질 필요는 없다.@change핸들러이것은, 다음의 코드에 의한 것입니다.computed: { searcher() {이미 의지하고 있다this.selectedTo.언제든지this.selectedTo변경, Vue가 계산한다.searcher다시.

솔루션: 간단히 제거@change="searcher"부터에서b-form. 다른 모든 것은 일할 것이다.다른 건 다 될 거야

@acdcjunior, 답변 감사합니다.

물론, 지금 물론에 대한에 대한 참조를 제거하면 됩니다 삭제하기만 참조를.searcher()그냥기 때문에 땅이 전혀 없을 것은 행동하지 않는 필드 값 변화에 있음을 의미한다.필드 값 변경 시 아무런 조치도 취하지 않으므로 필드가 전혀 작동하지 않습니다.

그 의 이동 움직이는searcher()로 기능하다에 기능이다.methods: {}대신 대신computed: {}는 입력 이벤트에 말하지 말고 변화는( 다른 미스테리는 아니지만 오늘)라고 할 것이다.는 입력 이벤트에 호출되는 것을 의미하며 변경(오늘날에는 미스테리지만 다른 미스테리)이 아닙니다.저는 그것을 노리고 있는 typeahead 기능을 빼앗고 미묘한 차이점이다.오토어헤드 기능을 빼앗는미묘한 차이.

그러나가 하지만의 결과 그것은 나에게 그 결과를 기억나게 했다 기억하게 만들었다computed: {}기능 있고 어떤 변수를 바꿀 re-computed 캐시 됩니다.함수는 캐시되며 파라미터가 변경되면 다시 캐시됩니다.이 사건에서 나는 깨달았습니다.searcher()는 기호에 .this.selectedTo 언제요?selectToUser() 세트 " " "this.selectedTo 명령어는 다른 .searcher().

수정했습니다.앞으로 비슷한 문제가 생길 경우를 대비해 다른 변수를 추가하여 구식 세마포어로 눈을 돌려 해결했습니다.

var userMadeSelection: false

여기서 searcher()는 다음 시나리오의 체크로 시작합니다.

  computed: {
      searcher() {
          if(this.userMadeSelection) {
            this.userMadeSelection = false;
            return this.selectedTo;
          }
          …

다음으로 selectToUser()를 선택합니다.

this.userMadeSelection = true;

언급URL : https://stackoverflow.com/questions/48985298/how-to-prevent-change-event-when-changing-v-model-value

반응형