Sfoglia il codice sorgente

make v-with unidirectional

Evan You 11 anni fa
parent
commit
50f65cffde
2 ha cambiato i file con 33 aggiunte e 15 eliminazioni
  1. 12 0
      changes.md
  2. 21 15
      src/directives/with.js

+ 12 - 0
changes.md

@@ -279,6 +279,18 @@ computed: {
 
     When used as a dynamic component, it will check for the `keep-alive` attribute. When `keep-alive` is present, already instantiated components will be cached. This is useful when you have large, nested view components and want to maintain the state when switching views.
 
+- #### Usage change for `v-with`
+
+  In 0.10 and earlier, `v-with` creates a two-way binding between the parent and child instance. In 0.11, it no longer creates a two-way binding but rather facilitates a unidirectional data flow from parent to child.
+
+  For example:
+
+  ``` html
+  <div v-component="test" v-with="childKey:parentKey">{{childKey}}</div>
+  ```
+
+  Here when you do `this.a = 123` in the child, the child's view will update, but the parent's scope will remain unaffected. When `parent.parentKey` changes again, it will overwrite `child.childKey`.
+
 - #### New directive option: `twoWay`
 
   This option indicates the directive is two-way and may write back to the model. Allows the use of `this.set(value)` inside directive functions.

+ 21 - 15
src/directives/with.js

@@ -1,31 +1,37 @@
 var _ = require('../util')
+var Watcher = require('../watcher')
 
 module.exports = {
 
   priority: 900,
 
   bind: function () {
-    if (this.el !== this.vm.$el) {
-      this.invalid = true
+    var vm = this.vm
+    if (this.el !== vm.$el) {
       _.warn(
         'v-with can only be used on instance root elements.'
       )
-      return
-    }
-    if (this.arg) {
-      var self = this
-      this.vm.$watch(this.arg, function (val) {
-        self.set(_.toNumber(val))
-      })
+    } else if (!vm.$parent) {
+      _.warn(
+        'v-with must be used on an instance with a parent.'
+      )
+    } else {
+      var key = this.arg
+      this.watcher = new Watcher(
+        vm.$parent,
+        this.expression,
+        function (val) {
+          vm.$set(key, val)
+        }
+      )
+      // initial set
+      vm.$set(key, this.watcher.value)
     }
   },
 
-  update: function (value) {
-    if (this.invalid) return
-    if (this.arg) {
-      this.vm.$set(this.arg, value)
-    } else if (this.vm.$data !== value) {
-      this.vm.$data = value
+  unbind: function () {
+    if (this.watcher) {
+      this.watcher.teardown()
     }
   }