vue js 使用单个处理程序监视多个属性
Posted
技术标签:
【中文标题】vue js 使用单个处理程序监视多个属性【英文标题】:vue js watch multiple properties with single handler 【发布时间】:2017-08-01 21:34:41 【问题描述】:目前我必须看一些属性。如果它们每个都发生变化,我必须调用相同的函数:
export default
// ...... rest of code
watch:
propa: function(after,before)
doSomething(after,before);
,
propb: function(after,before)
doSomething(after,before);
// ... so on
所以我不得不在上面多次编写相同的代码。 是否可以简单地监视所有属性并调用它们的更改处理程序,而不必多次编写相同的代码?
PS:我使用的是 vue 1.x
【问题讨论】:
取决于您的数据的结构。如果您将观察到的数据放在一个对象中,您可以使用 deep: true 属性观察单个对象,并触发该方法。您也可以观察整个数据对象,但我不建议这样做。 我认为没有像here 讨论的那样有某种方法,您可以像完成here 那样创建计算属性,但这也不是很干净。 【参考方案1】:更新:2020 年 4 月
对于使用 Vue 3 的人,watch API 可以接受多个来源
import watch, ref from 'vue';
export default
setup(() =>
const a = ref(1), b = ref('hello');
watch([a, b], ([newA, newB], [prevA, prevB]) =>
// do whatever you want
);
);
;
Vue 2 的原始答案
没有官方方法可以解决您的问题(see this)。但是您可以使用计算属性作为技巧:
export default
// ...
computed:
propertyAAndPropertyB()
return `$this.propertyA|$this.propertyB`;
,
,
watch:
propertyAAndPropertyB(newVal, oldVal)
const [oldPropertyA, oldProvertyB] = oldVal.split('|');
const [newPropertyA, newProvertyB] = newVal.split('|');
// doSomething
,
,
如果您只是想做某事而不关心什么是新/旧值。 忽略两行
const [oldPropertyA, oldProvertyB] = oldVal.split('|');
const [newPropertyA, newProvertyB] = newVal.split('|');
【讨论】:
截至您 4 月的更新,我对使用这种方法很感兴趣,但我无法找到文档,因为我无法获得正确的语法,只找到了 v2 和v3,但这些都没有显示我需要的语法。需要以下语法:export default watch: --watcher for multiple props here--
使用 vue 2 和 composition-api 插件,它与一个返回值数组的函数一起工作:watch(() => [a, b], ....)
使用 vue 2,当我控制台我在 watch 方法中获得的任何属性时,我得到 [Object object]。我猜它不起作用?
@aasutossh 答案将其强制转换为字符串。如果您需要任何其他类型,最好从计算属性返回一个对象。 startAndEnd() const start, end = this; return start, end ; ,
。然后,您可以在其 corect 类型中使用不同的值,例如 newVal.start 和 newVal.end。你必须确保每次都发出一个新创建的对象,这样你就不会在你的 oldVal 中得到变异的对象。
我使用的是 3.0。我有一长串想要查看的变量,但我不关心它们的值。如何编写监视语句而不包含变量值?我没有任何运气想出语法,而且似乎没有任何关于此的文档。【参考方案2】:
另一种可能性:
new Vue(
el: '#app',
data:
name: 'Alice',
surname: 'Smith',
fullName: '' // IRL you would use a computed for this, I'm updating it using a watch just to demo how it'd be used
,
mounted()
this.$watch(vm => [vm.name, vm.surname], val =>
this.fullName = this.name + ' ' + this.surname;
,
immediate: true, // run immediately
deep: true // detects changes inside objects. not needed here, but maybe in other cases
)
);
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div>
name:<input v-model="name">
</div>
<div>
surname:<input v-model="surname">
</div>
<div>
full name: fullName
</div>
</div>
有关Vue API docs for vm.$watch
的更多信息。
【讨论】:
这对我很有帮助,但应该注意的是,我正在查看一组对象,为此我需要添加deep: true
官方 Vue JS 文档实际上对这个主题很有帮助:vuejs.org/v2/api/#vm-watch
@JohnMellor 好的,很高兴知道。我在上面的示例中添加了链接和deep: true
,以防万一
这个太酷了,谢谢分享!!【参考方案3】:
像这样:
data()
return
propa: '',
propb: ''
,
computed:
changeData()
const propa, propb = this
return
propa,
propb
,
watch:
changeData:
handler: function(val)
console.log('value change: ', val)
,
deep: true
【讨论】:
您可以简单地返回要跟踪的项目数组。changeData() return [this.propa, this.propb]
这是最好的答案。保留类型并且在没有 this.$watch 的情况下很容易实现。数组也可以,但是通过返回一个对象,您可以保持每个属性的名称不变,而不必依赖索引。
这应该被标记为vue2的正确答案。【参考方案4】:
首先,您的定义可以简化。 doSomething
似乎不是 Vue 上的方法,所以你的手表可能只是
watch:
propa: doSomething,
propb: doSomething
其次,有时重要的是要记住 Vue 定义对象只是普通的 javascript 对象。它们可以被操纵。
如果你想查看数据对象中的每个属性,你可以这样做
function doSomething(after, before)
console.log(after,before);
function buildWatch(def)
if (!def.watch)
def.watch = ;
for (let prop of Object.keys(def.data))
def.watch[prop] = doSomething;
return def;
let vueDefinition =
data:
propa: "testing",
propb: "testing2",
propc: "testing3"
export default buildWatch(vueDefinition)
如果您只想查看一些已定义的属性列表:
// First argument is the definition, the rest are property names
function buildWatch(def)
if (!def.watch)
def.watch = ;
const properties = Array.prototype.slice.call(arguments,1);
for (let prop of properties)
def.watch[prop] = doSomething;
return def;
export default buildWatch(vueDefinition, "propa", "propb")
【讨论】:
【参考方案5】:对于 Vue 打字稿,您可以这样做。经过测试。
@Watch('varA')
@Watch('varB')
private oneOfAboveChanged(newVal)
console.log(newVal)
【讨论】:
【参考方案6】:我对 vue2 的解决方案:
export default
data()
return
status: null,
name: null,
date: null,
mobile: null,
page: 1,
,
watch:
...["status", "name", "date", "mobile", "page"].reduce((acc, currentKey) =>
acc[currentKey] = (newValue) =>
// doSomething
// console.log(newValue, currentKey)
return acc
, ),
【讨论】:
【参考方案7】:vm.$data
如果你想监听data()
里面的所有属性,可以使用this.$data
<script>
export default
data ()
return
propA: 'Hello',
propB: 'world'
watch:
$data (newValue) // Watches for any changes in data()
// Do something with the new data
</script>
【讨论】:
【参考方案8】:老问题,但答案可能对仍在使用 vue 1 的人有用。
您可以通过将多个道具括在引号中来观看它们:
data()
return
foo:
prop1: 1,
prop2: 2,
watch:
'[foo.prop1, foo.prop2]'(newVal, oldVal)
//do sth
console.log(newVal); // prints ([prop1, prop2])
console.log(oldVal); // prints ([prop1, prop2])
【讨论】:
以上是关于vue js 使用单个处理程序监视多个属性的主要内容,如果未能解决你的问题,请参考以下文章