在 Vue 中反跳计算属性/getter
Posted
技术标签:
【中文标题】在 Vue 中反跳计算属性/getter【英文标题】:Debounce computed properties/getters in Vue 【发布时间】:2017-11-30 01:20:16 【问题描述】:我似乎无法去抖动(lodash)计算属性或 vuex getter。去抖动的函数总是返回 undefined。
https://jsfiddle.net/guanzo/yqk0jp1j/2/
html:
<div id="app">
<input v-model="text">
<div>computed: textComputed </div>
<div>debounced: textDebounced </div>
</div>
JS:
new Vue(
el:'#app',
data:
text:''
,
computed:
textDebounced: _.debounce(function()
return this.text
,500),
textComputed()
return this.text
)
【问题讨论】:
您对替代解决方案持开放态度还是要求将去抖动应用于计算项? 好吧,我想知道为什么它不起作用,但是你确定你有什么样的替代解决方案? 看看这个有趣的小提琴:jsfiddle.net/yqk0jp1j/3 去抖动是一种控制函数调用频率的方法。它本质上是异步的,不能返回值。这就是为什么它不能用于计算。 您到底想在这里尝试什么?_.debounce
本身没有任何返回值,因此您当然会看到 undefined 作为结果。内部函数内的去抖动返回值被丢弃了。
【参考方案1】:
我不知道为什么 debounce 函数不适用于计算属性。但是,另一种解决方案是将 debounce 放在 methods
部分中的函数上,并通过 watch
调用它。
https://jsfiddle.net/vsc4npv3/
HTML:
<div id="app">
<input v-model="text">
<div>computed: textComputed </div>
<div>debounced: debouncedText </div>
</div>
var x = new Vue(
el:'#app',
data:
text:'',
debouncedText: ''
,
watch:
text: function (val)
this.debouncer();
,
computed:
textComputed()
return this.text;
,
methods:
debouncer: _.debounce(function()
this.debouncedText = this.text;
,500)
)
【讨论】:
【参考方案2】:正如我在评论中提到的,去抖动本质上是异步操作,因此不能返回值。根据您的需要,您可能希望在 input 端进行去抖动。 text
中的值和textComputed
中的值没有区别,但是如果你v-model="textComputed"
,值设置会去抖动。
如果您特别想要变量的去抖动版本,mrogers 提供了一个很好的解决方案。
var x = new Vue(
el: '#app',
data:
text: 'start'
,
computed:
textComputed:
get()
return this.text;
,
set: _.debounce(function(newValue)
this.text = newValue;
, 500)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
<div id="app">
<div>
Debounced input:
<input v-model="textComputed">
</div>
<div>
Immediate input:
<input v-model="text">
</div>
<div>computed: textComputed </div>
<div>debounced: text </div>
</div>
【讨论】:
我主要想知道为什么它不起作用,谢谢。我没有对输入进行去抖动,这只是我的示例,我只是想以某种方式延迟计算的属性值。 你有推荐的 Vuex 方法吗? (例如,在存储值上使用双向绑定,设置调用提交?设置调用动作并让动作去抖动提交?) @SumNeuron 这取决于您要实现的目标。使用 Vuex,动作可以是异步的,所以你可以在那里去抖动。突变必须是同步的,所以不存在。 @RoyJ 我有一个文本字段,更改后会切换需要一段时间的计算...在玩具示例中,这不是问题,但不能很好地适应正常的人类打字速度...所以最好对商店的状态进行去抖动,这是绑定到文本输入的当前 2-way 形式... 您可以改用.lazy,但是可以,您可以取消设置操作。【参考方案3】:-
简单
没有外部依赖(如
_.debounce
)
为 Vue 量身定制
import Vue from 'vue'
// Thanks to https://github.com/vuejs-tips/v-debounce/blob/master/debounce.js
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)
function debouncedProperty(delay)
let observable = Vue.observable( value: undefined );
return
get() return observable.value; ,
set: debounce(function (newValue) observable.value = newValue; , delay)
// component
export default
computed:
myProperty: debouncedProperty(300),
,
【讨论】:
以上是关于在 Vue 中反跳计算属性/getter的主要内容,如果未能解决你的问题,请参考以下文章
使用 Getter 和 Setter 计算的 Vue 属性不会在 Webpack 中编译