【问题标题】:Input value overridden on mutation with v-debounce使用 v-debounce 在突变时覆盖输入值
【发布时间】:2019-05-21 01:20:49
【问题描述】:

考虑以下示例:

https://codesandbox.io/s/vdebounce-input-override-ej4nz

它是大型应用程序的简化(大部分是模拟)版本,使用 Observables 根据用户输入从多个 API 中获取过滤结果。我需要去抖输入。
在应用程序中,去抖动值较大,因此问题不太明显,但我在示例中降低了它以使问题更容易发现。我还尝试模拟服务器响应时间的随机性。

问题是,每当我收到回复时,如果我在输入中输入内容,我会丢失一些字符,具体取决于我输入的速度。
如果我删除v-debounce 指令(或.lazy 修饰符),问题就消失了,但没有去抖。

我还在 v-debounce 回购中提出了它。

我知道我可以完全转储 v-debounce 并在手表内使用 lodash 的去抖动,但我希望我不必这样做(因为 v-debounce 应该为 Vue 提供服务,对吧! ?)。到目前为止,我一直尽量保持“Vue”。


重要编辑:(在回答后)似乎有两个包定义了v-debounce 指令。好的在这里:npm,github。

npm i vue-debounce

我使用的是v-debounce 并覆盖了输入。

【问题讨论】:

    标签: vue.js vuejs2 debounce v-debounce


    【解决方案1】:

    了解问题

    您遇到的问题是 标记呈现 和 事件去抖动 之间的相互作用(这可能是 v-debounce 的问题或预期的行为意见可能会有所不同) :

    • 您正在消除输入元素上 change 事件 的触发
      • 去抖事件触发调用时输入的值(也就是说,它不存储去抖调用中的调用数据)
    • 单独(在每次实际调用 debounce 时)您有一个异步操作(模拟服务器搜索)更改组件的状态,并触发 组件重新渲染
      • 此重新渲染检查整个组件 DOM,并“更正”它认为错误的输入值
    • 当异步操作后触发去抖动更改事件时,它会使用当前 DOM 输入值触发,该值现在已经过时(如果您继续输入,甚至会出现一些混乱)

    可能的解决方案

    这里的主要问题是应该跟踪实际的搜索值。您希望消除搜索操作的抖动,而不是值更改本身(当然也不是输入更改事件)

    自己处理去抖

    Here is an alternative to your app,执行以下操作:

    • 保留一个 v-model - search - 没有去抖动
    • 在更改上述 v 模型时:
      • 如果当前正在进行搜索,立即取消它
      • 触发去抖动搜索操作(只有在停止输入时才会真正开始)
    [...]
      mounted() {
        this.debouncedSearch = _.debounce(this.search, 500);
      },
      methods: {
        search() {
          this.loading = true;
          this.$searchTimeout = setTimeout(() => {
            store.albums = albums.filter(
              album => album.title.indexOf(this.term) > -1
            );
            store.searchTerm = this.term;
            this.loading = false;
          }, Math.floor(Math.random() * 1000 + 300));
        }
      },
      watch: {
        term() {
          if (this.$searchTimeout) {
            this.loading = false;
            clearTimeout(this.$searchTimeout);
            delete this.$searchTimeout;
          }
          this.debouncedSearch();
        }
      }
    

    不影响v-model 的去抖动指令

    Here is another solution 使用自定义指令来消除输入事件处理程序的抖动,不会弄乱与 change 的 v-model 绑定

    这里是应用程序:

    • 保持 v-model - search - 没有去抖动
      • 在更改上述 v-model 时,如果当前正在进行搜索,立即取消它
    • 使用 v-debounce 指令触发去抖动搜索操作(仅在停止输入时才真正开始)
    <input 
      v-model="term" 
      v-debounce="{ delay: 500, handler: search}" 
      @input="clearSearch">
    

    【讨论】:

    • 所以,基本上,v-debounce 是无用的,因为它破坏了用户体验。感谢您的详细解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多