vue js 使用单个处理程序监视多个属性
vue js watch multiple properties with single handler
目前我要看几个楼盘。如果它们每个都发生变化,我必须调用相同的函数:
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
首先,您的定义可以简化。 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")
更新:2020 年 4 月
对于使用 Vue 3 的人,手表 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
},
},
}
如果您只想做点什么而不关心什么是 new/old 值。
忽略两行
const [oldPropertyA, oldProvertyB] = oldVal.split('|');
const [newPropertyA, newProvertyB] = newVal.split('|');
另一种可能性:
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
的更多信息。
像这样:
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
}
}
对于 Vue 打字稿,您可以这样做。已测试。
@Watch('varA')
@Watch('varB')
private oneOfAboveChanged(newVal) {
console.log(newVal)
}
我对 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
}, {}),
}
}
vm.$数据
如果想监听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>
老问题,但答案可能对那些仍在使用 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])
}
}
目前我要看几个楼盘。如果它们每个都发生变化,我必须调用相同的函数:
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
首先,您的定义可以简化。 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")
更新:2020 年 4 月
对于使用 Vue 3 的人,手表 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
},
},
}
如果您只想做点什么而不关心什么是 new/old 值。 忽略两行
const [oldPropertyA, oldProvertyB] = oldVal.split('|');
const [newPropertyA, newProvertyB] = newVal.split('|');
另一种可能性:
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
的更多信息。
像这样:
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
}
}
对于 Vue 打字稿,您可以这样做。已测试。
@Watch('varA')
@Watch('varB')
private oneOfAboveChanged(newVal) {
console.log(newVal)
}
我对 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
}, {}),
}
}
vm.$数据
如果想监听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>
老问题,但答案可能对那些仍在使用 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])
}
}