Evan You 12 лет назад
Родитель
Сommit
fc80d8186e
4 измененных файлов с 30 добавлено и 19 удалено
  1. 6 0
      changes.md
  2. 3 2
      src/instance/scope.js
  3. 9 5
      src/vue.js
  4. 12 12
      test/unit/specs/instance_scope_spec.js

+ 6 - 0
changes.md

@@ -34,6 +34,12 @@ It's probably easy to understand why `el` and `parent` are instance only. But wh
 
 When events are used extensively for cross-vm communication, the ready hook can get kinda messy. The new `events` option is similar to its Backbone equivalent, where you can declaratiely register a bunch of event listeners.
 
+### new option: `inheritScope`.
+
+Default: `true`.
+
+Whether to inherit parent scope data. Set it to `false` if you want to create a component that have an isolated scope of its own.
+
 ### removed options: `id`, `tagName`, `className`, `attributes`, `lazy`.
 
 Since now a vm must always be provided the `el` option or explicitly mounted to an existing element, the element creation releated options have been removed for simplicity. If you need to modify your element's attributes, simply do so in the new `beforeMount` hook.

+ 3 - 2
src/instance/scope.js

@@ -14,7 +14,8 @@ var scopeEvents = ['set', 'mutate', 'add', 'delete']
 
 exports._initScope = function () {
   var parent = this.$parent
-  var scope = this.$scope = parent
+  var inherit = parent && this.$options.inheritScope
+  var scope = this.$scope = inherit
     ? Object.create(parent.$scope)
     : {}
   // create scope observer
@@ -23,7 +24,7 @@ exports._initScope = function () {
     doNotAlterProto: true
   })
 
-  if (!parent) return
+  if (!inherit) return
 
   // relay change events that sent down from
   // the scope prototype chain.

+ 9 - 5
src/vue.js

@@ -28,14 +28,18 @@ extend(Vue, require('./api/global'))
  * Vue and every constructor that extends Vue has an
  * associated options object, which can be accessed during
  * compilation steps as `this.constructor.options`.
+ *
+ * These can be seen as the default options of every
+ * Vue instance.
  */
 
 Vue.options = {
-  directives : require('./directives'),
-  filters    : require('./filters'),
-  partials   : {},
-  effects    : {},
-  components : {}
+  directives    : require('./directives'),
+  filters       : require('./filters'),
+  partials      : {},
+  effects       : {},
+  components    : {},
+  inheritScope  : true
 }
 
 /**

+ 12 - 12
test/unit/specs/instance_scope_spec.js

@@ -33,7 +33,7 @@ describe('Scope', function () {
 
     it('should trigger set events', function () {
       var spy = jasmine.createSpy('basic')
-      vm._observer.on('set', spy)
+      vm.$observer.on('set', spy)
 
       // set on scope
       vm.$scope.a = 2
@@ -48,7 +48,7 @@ describe('Scope', function () {
 
     it('should trigger add/delete events', function () {
       var spy = jasmine.createSpy('instantiation')
-      vm._observer
+      vm.$observer
         .on('add', spy)
         .on('delete', spy)
 
@@ -159,25 +159,25 @@ describe('Scope', function () {
       // when a shadowed property changed on parent scope,
       // the event should NOT be propagated down
       var spy = jasmine.createSpy('inheritance')
-      child._observer.on('set', spy)
+      child.$observer.on('set', spy)
       parent.c = 'c changed'
       expect(spy.calls.count()).toBe(1)
       expect(spy).toHaveBeenCalledWith('c', 'c changed', u)
 
       spy = jasmine.createSpy('inheritance')
-      child._observer.on('add', spy)
+      child.$observer.on('add', spy)
       parent.$scope.$add('e', 123)
       expect(spy.calls.count()).toBe(1)
       expect(spy).toHaveBeenCalledWith('e', 123, u)
 
       spy = jasmine.createSpy('inheritance')
-      child._observer.on('delete', spy)
+      child.$observer.on('delete', spy)
       parent.$scope.$delete('e')
       expect(spy.calls.count()).toBe(1)
       expect(spy).toHaveBeenCalledWith('e', u, u)
 
       spy = jasmine.createSpy('inheritance')
-      child._observer.on('mutate', spy)
+      child.$observer.on('mutate', spy)
       parent.arr.reverse()
       expect(spy.calls.mostRecent().args[0]).toBe('arr')
       expect(spy.calls.mostRecent().args[1]).toBe(parent.arr)
@@ -189,7 +189,7 @@ describe('Scope', function () {
       // when a shadowed property changed on parent scope,
       // the event should NOT be propagated down
       var spy = jasmine.createSpy('inheritance')
-      child._observer.on('set', spy)
+      child.$observer.on('set', spy)
       parent.a = 'a changed'
       expect(spy.calls.count()).toBe(0)
     })
@@ -213,8 +213,8 @@ describe('Scope', function () {
       
       var parentSpy = jasmine.createSpy('parent')
       var childSpy = jasmine.createSpy('child')
-      parent._observer.on('set', parentSpy)
-      child._observer.on('set', childSpy)
+      parent.$observer.on('set', parentSpy)
+      child.$observer.on('set', childSpy)
       child.a = 3
 
       // make sure data sync is working
@@ -240,8 +240,8 @@ describe('Scope', function () {
     var vmSpy = jasmine.createSpy('vm')
     var vmAddSpy = jasmine.createSpy('vmAdd')
     var oldDataSpy = jasmine.createSpy('oldData')
-    vm._observer.on('set', vmSpy)
-    vm._observer.on('add', vmAddSpy)
+    vm.$observer.on('set', vmSpy)
+    vm.$observer.on('add', vmAddSpy)
     oldData.$observer.on('set', oldDataSpy)
 
     vm.$data = newData
@@ -274,7 +274,7 @@ describe('Scope', function () {
       parent: parent
     })
     var spy = jasmine.createSpy('teardown')
-    child._observer.on('set', spy)
+    child.$observer.on('set', spy)
 
     it('should stop relaying parent events', function () {
       child._teardownScope()