Просмотр исходного кода

remove options param for <select>

Evan You 10 лет назад
Родитель
Сommit
4209eadee0

+ 2 - 6
src/deprecations.js

@@ -149,12 +149,8 @@ if (process.env.NODE_ENV !== 'production') {
       )
     },
 
-    SELECT_OPTIONS: function () {
-      warn(
-        'The "options" param for <select v-model> will be deprecated in 1.0.0. ' +
-        'Use v-for to render the options. See https://github.com/yyx990803/vue/issues/1229 ' +
-        'for more details.'
-      )
+    CONTENT_SELECT: function () {
+      warn('<content select="..."> will be deprecated in in 1.0.0. in favor of <slot name="...">.')
     }
 
   }

+ 0 - 98
src/directives/model/select.js

@@ -1,6 +1,4 @@
 var _ = require('../../util')
-var Watcher = require('../../watcher')
-var dirParser = require('../../parsers/directive')
 
 module.exports = {
 
@@ -15,14 +13,6 @@ module.exports = {
       }
     }
 
-    // check options param
-    var optionsParam = this.param('options')
-    if (optionsParam) {
-      initOptions.call(this, optionsParam)
-      if (process.env.NODE_ENV !== 'production') {
-        _.deprecation.SELECT_OPTIONS()
-      }
-    }
     this.number = this.param('number') != null
     this.multiple = el.hasAttribute('multiple')
 
@@ -50,12 +40,6 @@ module.exports = {
   update: function (value) {
     var el = this.el
     el.selectedIndex = -1
-    if (value == null) {
-      if (this.defaultOption) {
-        this.defaultOption.selected = true
-      }
-      return
-    }
     var multi = this.multiple && _.isArray(value)
     var options = el.options
     var i = options.length
@@ -81,88 +65,6 @@ module.exports = {
   }
 }
 
-/**
- * Initialize the option list from the param.
- *
- * @param {String} expression
- */
-
-function initOptions (expression) {
-  var self = this
-  var el = self.el
-  var defaultOption = self.defaultOption = self.el.options[0]
-  var descriptor = dirParser.parse(expression)[0]
-  function optionUpdateWatcher (value) {
-    if (_.isArray(value)) {
-      // clear old options.
-      // cannot reset innerHTML here because IE family get
-      // confused during compilation.
-      var i = el.options.length
-      while (i--) {
-        var option = el.options[i]
-        if (option !== defaultOption) {
-          el.removeChild(option)
-        }
-      }
-      buildOptions(el, value)
-      self.forceUpdate()
-    } else {
-      process.env.NODE_ENV !== 'production' && _.warn(
-        'Invalid options value for v-model: ' + value
-      )
-    }
-  }
-  this.optionWatcher = new Watcher(
-    this.vm,
-    descriptor.expression,
-    optionUpdateWatcher,
-    {
-      deep: true,
-      filters: descriptor.filters
-    }
-  )
-  // update with initial value
-  optionUpdateWatcher(this.optionWatcher.value)
-}
-
-/**
- * Build up option elements. IE9 doesn't create options
- * when setting innerHTML on <select> elements, so we have
- * to use DOM API here.
- *
- * @param {Element} parent - a <select> or an <optgroup>
- * @param {Array} options
- */
-
-function buildOptions (parent, options) {
-  var op, el
-  for (var i = 0, l = options.length; i < l; i++) {
-    op = options[i]
-    if (!op.options) {
-      el = document.createElement('option')
-      if (typeof op === 'string') {
-        el.text = el.value = op
-      } else {
-        if (op.value != null && !_.isObject(op.value)) {
-          el.value = op.value
-        }
-        // object values gets serialized when set as value,
-        // so we store the raw value as a different property
-        el._value = op.value
-        el.text = op.text || ''
-        if (op.disabled) {
-          el.disabled = true
-        }
-      }
-    } else {
-      el = document.createElement('optgroup')
-      el.label = op.label
-      buildOptions(el, op.options)
-    }
-    parent.appendChild(el)
-  }
-}
-
 /**
  * Check the initial value for selected options.
  */

+ 1 - 6
src/directives/prop.js

@@ -34,12 +34,7 @@ module.exports = {
     )
 
     // set the child initial value.
-    var value = this.parentWatcher.value
-    if (childKey === '$data') {
-      child._data = value
-    } else {
-      _.initProp(child, prop, value)
-    }
+    _.initProp(child, prop, this.parentWatcher.value)
 
     // setup two-way binding
     if (prop.mode === bindingModes.TWO_WAY) {

+ 43 - 47
src/instance/lifecycle.js

@@ -17,57 +17,53 @@ var compiler = require('../compiler')
 
 exports._compile = function (el) {
   var options = this.$options
-  if (options._linkFn) {
-    // pre-transcluded with linker, just use it
-    this._initElement(el)
-    this._unlinkFn = options._linkFn(this, el)
-  } else {
-    // transclude and init element
-    // transclude can potentially replace original
-    // so we need to keep reference; this step also injects
-    // the template and caches the original attributes
-    // on the container node and replacer node.
-    var original = el
-    el = compiler.transclude(el, options)
-    this._initElement(el)
-
-    // root is always compiled per-instance, because
-    // container attrs and props can be different every time.
-    var rootLinker = compiler.compileRoot(el, options)
-
-    // compile and link the rest
-    var contentLinkFn
-    var ctor = this.constructor
-    // component compilation can be cached
-    // as long as it's not using inline-template
-    if (options._linkerCachable) {
-      contentLinkFn = ctor.linker
-      if (!contentLinkFn) {
-        contentLinkFn = ctor.linker = compiler.compile(el, options)
-      }
-    }
 
-    // link phase
-    // make sure to link root with prop scope!
-    var rootUnlinkFn = rootLinker(this, el, this._scope)
-    var contentUnlinkFn = contentLinkFn
-      ? contentLinkFn(this, el)
-      : compiler.compile(el, options)(this, el)
-
-    // register composite unlink function
-    // to be called during instance destruction
-    this._unlinkFn = function () {
-      rootUnlinkFn()
-      // passing destroying: true to avoid searching and
-      // splicing the directives
-      contentUnlinkFn(true)
-    }
+  // transclude and init element
+  // transclude can potentially replace original
+  // so we need to keep reference; this step also injects
+  // the template and caches the original attributes
+  // on the container node and replacer node.
+  var original = el
+  el = compiler.transclude(el, options)
+  this._initElement(el)
 
-    // finally replace original
-    if (options.replace) {
-      _.replace(original, el)
+  // root is always compiled per-instance, because
+  // container attrs and props can be different every time.
+  var rootLinker = compiler.compileRoot(el, options)
+
+  // compile and link the rest
+  var contentLinkFn
+  var ctor = this.constructor
+  // component compilation can be cached
+  // as long as it's not using inline-template
+  if (options._linkerCachable) {
+    contentLinkFn = ctor.linker
+    if (!contentLinkFn) {
+      contentLinkFn = ctor.linker = compiler.compile(el, options)
     }
   }
+
+  // link phase
+  // make sure to link root with prop scope!
+  var rootUnlinkFn = rootLinker(this, el, this._scope)
+  var contentUnlinkFn = contentLinkFn
+    ? contentLinkFn(this, el)
+    : compiler.compile(el, options)(this, el)
+
+  // register composite unlink function
+  // to be called during instance destruction
+  this._unlinkFn = function () {
+    rootUnlinkFn()
+    // passing destroying: true to avoid searching and
+    // splicing the directives
+    contentUnlinkFn(true)
+  }
+
+  // finally replace original
+  if (options.replace) {
+    _.replace(original, el)
+  }
+
   return el
 }
 

+ 1 - 203
test/unit/specs/directives/model_spec.js

@@ -343,150 +343,6 @@ if (_.inBrowser) {
       expect(vm.test[1]).toBe('c')
     })
 
-    it('select + options', function (done) {
-      var vm = new Vue({
-        el: el,
-        data: {
-          test: 'b',
-          opts: ['a', 'b', 'c']
-        },
-        template: '<select v-model="test" options="opts"></select>'
-      })
-      var opts = el.firstChild.options
-      expect(opts.length).toBe(3)
-      expect(opts[0].selected).toBe(false)
-      expect(opts[1].selected).toBe(true)
-      expect(opts[2].selected).toBe(false)
-      vm.opts = ['b', 'c']
-      _.nextTick(function () {
-        expect(opts.length).toBe(2)
-        expect(opts[0].selected).toBe(true)
-        expect(opts[1].selected).toBe(false)
-        // should teardown option watcher when unbind
-        expect(vm._watchers.length).toBe(2)
-        vm._directives[0]._teardown()
-        expect(vm._watchers.length).toBe(0)
-        done()
-      })
-    })
-
-    it('select + options + text', function () {
-      new Vue({
-        el: el,
-        data: {
-          test: 'b',
-          opts: [
-            { text: 'Select an option', value: null, disabled: true },
-            { text: 'A', value: 'a' },
-            { text: 'B', value: 'b' }
-          ]
-        },
-        template: '<select v-model="test" options="opts"></select>'
-      })
-      expect(el.firstChild.innerHTML).toBe(
-        '<option disabled="">Select an option</option>' +
-        '<option value="a">A</option>' +
-        '<option value="b">B</option>'
-      )
-      var opts = el.firstChild.options
-      expect(opts[0].disabled).toBe(true)
-      expect(opts[0].selected).toBe(false)
-      expect(opts[1].selected).toBe(false)
-      expect(opts[2].selected).toBe(true)
-    })
-
-    it('select + options + optgroup', function () {
-      new Vue({
-        el: el,
-        data: {
-          test: 'b',
-          opts: [
-            { label: 'A', options: ['a', 'b'] },
-            { label: 'B', options: ['c'] }
-          ]
-        },
-        template: '<select v-model="test" options="opts"></select>'
-      })
-      expect(el.firstChild.innerHTML).toBe(
-        '<optgroup label="A">' +
-          '<option value="a">a</option><option value="b">b</option>' +
-        '</optgroup>' +
-        '<optgroup label="B">' +
-          '<option value="c">c</option>' +
-        '</optgroup>'
-      )
-      var opts = el.firstChild.options
-      expect(opts[0].selected).toBe(false)
-      expect(opts[1].selected).toBe(true)
-      expect(opts[2].selected).toBe(false)
-    })
-
-    it('select + options with Object value', function (done) {
-      var vm = new Vue({
-        el: el,
-        data: {
-          test: { msg: 'A' },
-          opts: [
-            { text: 'a', value: { msg: 'A' }},
-            { text: 'b', value: { msg: 'B' }}
-          ]
-        },
-        template: '<select v-model="test" options="opts"></select>'
-      })
-      var select = el.firstChild
-      var opts = select.options
-      expect(opts[0].selected).toBe(true)
-      expect(opts[1].selected).toBe(false)
-      expect(vm.test.msg).toBe('A')
-      opts[1].selected = true
-      trigger(select, 'change')
-      _.nextTick(function () {
-        expect(opts[0].selected).toBe(false)
-        expect(opts[1].selected).toBe(true)
-        expect(vm.test.msg).toBe('B')
-        vm.test = { msg: 'A' }
-        _.nextTick(function () {
-          expect(opts[0].selected).toBe(true)
-          expect(opts[1].selected).toBe(false)
-          done()
-        })
-      })
-    })
-
-    it('select + options + multiple + Object value', function (done) {
-      var vm = new Vue({
-        el: el,
-        data: {
-          test: [{ msg: 'A' }, { msg: 'B'}],
-          opts: [
-            { text: 'a', value: { msg: 'A' }},
-            { text: 'b', value: { msg: 'B' }},
-            { text: 'c', value: { msg: 'C' }}
-          ]
-        },
-        template: '<select v-model="test" options="opts" multiple></select>'
-      })
-      var select = el.firstChild
-      var opts = select.options
-      expect(opts[0].selected).toBe(true)
-      expect(opts[1].selected).toBe(true)
-      expect(opts[2].selected).toBe(false)
-      vm.test = [{ msg: 'C' }]
-      _.nextTick(function () {
-        expect(opts[0].selected).toBe(false)
-        expect(opts[1].selected).toBe(false)
-        expect(opts[2].selected).toBe(true)
-        opts[1].selected = true
-        opts[2].selected = false
-        trigger(select, 'change')
-        _.nextTick(function () {
-          expect(vm.test.length).toBe(1)
-          expect(vm.test[0].msg).toBe('B')
-          done()
-        })
-      })
-    })
-
     it('select + number', function () {
       var vm = new Vue({
         el: el,
@@ -527,56 +383,7 @@ if (_.inBrowser) {
       expect(vm.test).toBe(1)
     })
 
-    it('select + options + filter', function () {
-      new Vue({
-        el: el,
-        data: {
-          opts: ['a', 'b']
-        },
-        filters: {
-          aFilter: function (opts) {
-            return opts.map(function (val, i) {
-              return val + i
-            })
-          }
-        },
-        template: '<select v-model="test" options="opts | aFilter"></select>'
-      })
-      expect(el.firstChild.innerHTML).toBe(
-        '<option value="a0">a0</option>' +
-        '<option value="b1">b1</option>'
-      )
-    })
-
-    it('select + options + static option', function (done) {
-      var vm = new Vue({
-        el: el,
-        data: {
-          opts: ['a', 'b']
-        },
-        template:
-          '<select v-model="test" options="opts">' +
-            '<option value="">default...</option>' +
-          '</select>'
-      })
-      expect(el.firstChild.innerHTML).toBe(
-        '<option value="">default...</option>' +
-        '<option value="a">a</option>' +
-        '<option value="b">b</option>'
-      )
-      expect(el.firstChild.options[0].selected).toBe(true)
-      vm.opts = ['c']
-      _.nextTick(function () {
-        expect(el.firstChild.innerHTML).toBe(
-          '<option value="">default...</option>' +
-          '<option value="c">c</option>'
-        )
-        expect(el.firstChild.options[0].selected).toBe(true)
-        done()
-      })
-    })
-
-    it('select + v-for (1.0.0)', function (done) {
+    it('select + v-for', function (done) {
       var vm = new Vue({
         el: el,
         data: {
@@ -845,15 +652,6 @@ if (_.inBrowser) {
       expect(hasWarned(_, 'does not support element type')).toBe(true)
     })
 
-    it('warn invalid option value', function () {
-      new Vue({
-        el: el,
-        data: { a: 123 },
-        template: '<select v-model="test" options="a"></select>'
-      })
-      expect(hasWarned(_, 'Invalid options value')).toBe(true)
-    })
-
     it('warn read-only filters', function () {
       new Vue({
         el: el,