Issue 1:
What problem does this feature solve?

Hi,

I'd like to request a new option for the $watch() function: shallow: boolean;. This option would make watch callback function fire only if any of the first level values in an Array (a tuple) or on Object change. This would offer an alternative to the current behaviour of always calling the watch callback when watching a non-primitive variable (as per the following comment). It would also be a natural expansion of the deep: boolean; option.

Moreover, the first level properties of the watched Arrays and Objects would always be compared used strict equality comparison ===, regardless of whether they are primitive values or Arrays/Objects. This is so that the same instances of a class would not trigger the watch callback, as nothing has changed (the use case is: observing an immutable value object).

Use case 1: Watching a tuple, aka. watching many variables and having a single callback when any of the variables change. With the shallow: true option, it would be a very clean solution to current necessity of having to hash the tuple somehow (the easiest way is to .join(',') the tuple to produce a string, but not all tuples are made of primitive values, so that's not always this easy). Two tuples should evaluate equal, when all indexes of the old tuple are set to the same values in the new tuple, under the same indexes. It'd be a simple for-each loop that short-circuits on the first inequality in the old and the new tuple.

Use case 2: Watching all keys in an Object. This is a very common use case and using deep: true for it is very often not ideal (especially, if the values in the watched Object are also Objects). As in use case 1, here the old and the new Objects would evaluate unequal (and therefore trigger the watch callback), when any of the keys in the old Object doesn't strict-equal the same key in the new Object. Also, if keys are missing or there are extra keys in the new Object, this should also be treated as a change and therefore trigger the watch callback. A common context for this use case is when the watched Object is a hashmap behaving as a "form", whose keys are form keys and values are either primitive variables or value objects. Watching such a hashmap with the proposed shallow: true option would be a massive convenience (e.g. to run validation on every change in the form and enable/disable the submit button).

In angular 1, this feature is called $watchCollection.

Thank you.

What does the proposed API look like?

class Person {
constructor(name) {
this.name = name;
}
}

const vm = new Vue({
data: {
dataHashmap: {
bartender: new Person('Phil'),
bouncer: new Person('Rob'),
janitor: new Person('Tom'),
}
}
});

vm.$watch(
'dataHashmap',
() => { console.log(vm.dataHashmap); },
{ shallow: true }
);

vm.$watch(
(vm) => { return [vm.dataHashmap.bartender, vm.dataHashmap.janitor]; },
() => { console.log(vm.dataHashmap); },
{ shallow: true }
);

Issue 2:
Vue.js version

1.0.21

Reproduction Link

http://www.webpackbin.com/412B9bgJb

Steps to reproduce

click Toggle button

What is Expected?

when MyComponent is showing, the msg should be hidden

What is actually happening?

the msg always shows