Răsfoiți Sursa

Merge remote-tracking branch 'upstream/dev' into dev

fergaldoyle 10 ani în urmă
părinte
comite
1f7a45a383

+ 4 - 2
src/compiler/compile-props.js

@@ -192,8 +192,10 @@ function makePropsLinkFn (props) {
         }
       } else if (prop.optimizedLiteral) {
         // optimized literal, cast it and just set once
-        raw = _.stripQuotes(raw)
-        value = _.toBoolean(_.toNumber(raw))
+        var stripped = _.stripQuotes(raw)
+        value = stripped === raw
+          ? _.toBoolean(_.toNumber(raw))
+          : stripped
         _.initProp(vm, prop, value)
       } else {
         // string literal, but we need to cater for

+ 0 - 4
src/compiler/compile.js

@@ -662,10 +662,6 @@ function compileDirectives (attrs, options) {
       }
 
       if (dirDef) {
-        if (_.isLiteral(value)) {
-          value = _.stripQuotes(value)
-          modifiers.literal = true
-        }
         pushDir(dirName, dirDef)
       }
     }

+ 8 - 0
src/directives/internal/component.js

@@ -132,6 +132,10 @@ module.exports = {
         self.transition(newComponent, cb)
       })
     } else {
+      // update ref for kept-alive component
+      if (cached) {
+        newComponent._updateRef()
+      }
       this.transition(newComponent, cb)
     }
   },
@@ -241,6 +245,10 @@ module.exports = {
     }
     var child = this.childVM
     if (!child || this.keepAlive) {
+      if (child) {
+        // remove ref
+        child._updateRef(true)
+      }
       return
     }
     // the sole purpose of `deferCleanup` is so that we can

+ 1 - 4
src/directives/public/for.js

@@ -495,11 +495,8 @@ module.exports = {
       }
       return res
     } else {
-      var type = typeof value
-      if (type === 'number') {
+      if (typeof value === 'number') {
         value = range(value)
-      } else if (type === 'string') {
-        value = _.toArray(value)
       }
       return value || []
     }

+ 3 - 5
src/instance/init.js

@@ -79,11 +79,6 @@ exports._init = function (options) {
     this.$parent.$children.push(this)
   }
 
-  // set ref
-  if (options._ref) {
-    (this._scope || this._context).$refs[options._ref] = this
-  }
-
   // merge options.
   options = this.$options = mergeOptions(
     this.constructor.options,
@@ -91,6 +86,9 @@ exports._init = function (options) {
     this
   )
 
+  // set ref
+  this._updateRef()
+
   // initialize data as empty object.
   // it will be filled up in _initScope().
   this._data = {}

+ 22 - 8
src/instance/lifecycle.js

@@ -2,6 +2,26 @@ var _ = require('../util')
 var Directive = require('../directive')
 var compiler = require('../compiler')
 
+/**
+ * Update v-ref for component.
+ *
+ * @param {Boolean} remove
+ */
+
+exports._updateRef = function (remove) {
+  var ref = this.$options._ref
+  if (ref) {
+    var refs = (this._scope || this._context).$refs
+    if (remove) {
+      if (refs[ref] === this) {
+        refs[ref] = null
+      }
+    } else {
+      refs[ref] = this
+    }
+  }
+}
+
 /**
  * Transclude, compile and link element.
  *
@@ -136,14 +156,8 @@ exports._destroy = function (remove, deferCleanup) {
   var parent = this.$parent
   if (parent && !parent._isBeingDestroyed) {
     parent.$children.$remove(this)
-    // unregister ref
-    var ref = this.$options._ref
-    if (ref) {
-      var scope = this._scope || this._context
-      if (scope.$refs[ref] === this) {
-        scope.$refs[ref] = null
-      }
-    }
+    // unregister ref (remove: true)
+    this._updateRef(true)
   }
   // destroy all children.
   i = this.$children.length

+ 5 - 2
test/unit/specs/compiler/compile_spec.js

@@ -90,7 +90,6 @@ if (_.inBrowser) {
       expect(args[0].name).toBe('b')
       expect(args[0].expression).toBe('1')
       expect(args[0].def).toBe(defB)
-      expect(args[0].modifiers.literal).toBe(true)
       expect(args[1]).toBe(el.firstChild)
       // 4 (explicit literal)
       args = vm._bindDir.calls.argsFor(3)
@@ -245,12 +244,14 @@ if (_.inBrowser) {
         testTwoWay: null,
         twoWayWarn: null,
         testOneTime: null,
-        optimizeLiteral: null
+        optimizeLiteral: null,
+        optimizeLiteralStr: null
       }
       el.innerHTML = '<div ' +
         'v-bind:test-normal="a" ' +
         'test-literal="1" ' +
         ':optimize-literal="1" ' +
+        ':optimize-literal-str="\'true\'"' +
         ':test-two-way.sync="a" ' +
         ':two-way-warn.sync="a + 1" ' +
         ':test-one-time.once="a"></div>'
@@ -261,6 +262,8 @@ if (_.inBrowser) {
       expect(vm._data.testLiteral).toBe('1')
       expect(vm.optimizeLiteral).toBe(1)
       expect(vm._data.optimizeLiteral).toBe(1)
+      expect(vm.optimizeLiteralStr).toBe('true')
+      expect(vm._data.optimizeLiteralStr).toBe('true')
       // one time
       expect(vm.testOneTime).toBe('from parent: a')
       expect(vm._data.testOneTime).toBe('from parent: a')

+ 19 - 0
test/unit/specs/directives/public/ref_spec.js

@@ -53,6 +53,25 @@ if (_.inBrowser) {
       })
     })
 
+    it('with dynamic component + keep-alive', function (done) {
+      var vm = new Vue({
+        el: el,
+        components: components,
+        data: { test: 'test' },
+        template: '<component :is="test" v-ref:test keep-alive></component>'
+      })
+      expect(vm.$refs.test.$options.id).toBe('test')
+      vm.test = 'test2'
+      _.nextTick(function () {
+        expect(vm.$refs.test.$options.id).toBe('test2')
+        vm.test = ''
+        _.nextTick(function () {
+          expect(vm.$refs.test).toBe(null)
+          done()
+        })
+      })
+    })
+
     it('should be reactive when bound by dynamic component and hoisted', function (done) {
       var vm = new Vue({
         el: el,

+ 2 - 0
test/unit/specs/instance/init_spec.js

@@ -6,6 +6,7 @@ describe('Instance Init', function () {
     constructor: {
       options: { a: 1, b: 2 }
     },
+    _updateRef: jasmine.createSpy(),
     _initEvents: jasmine.createSpy(),
     _callHook: jasmine.createSpy(),
     _initState: jasmine.createSpy(),
@@ -38,6 +39,7 @@ describe('Instance Init', function () {
   it('should call other init methods', function () {
     expect(stub._initEvents).toHaveBeenCalled()
     expect(stub._initState).toHaveBeenCalled()
+    expect(stub._updateRef).toHaveBeenCalled()
   })
 
   it('should call created hook', function () {