github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/themes/wind/static/libs/vue-1.0.24/src/directives/public/model/select.js (about)

     1  import { isArray, toNumber, looseEqual } from '../../../util/index'
     2  
     3  export default {
     4  
     5    bind () {
     6      var self = this
     7      var el = this.el
     8  
     9      // method to force update DOM using latest value.
    10      this.forceUpdate = function () {
    11        if (self._watcher) {
    12          self.update(self._watcher.get())
    13        }
    14      }
    15  
    16      // check if this is a multiple select
    17      var multiple = this.multiple = el.hasAttribute('multiple')
    18  
    19      // attach listener
    20      this.listener = function () {
    21        var value = getValue(el, multiple)
    22        value = self.params.number
    23          ? isArray(value)
    24            ? value.map(toNumber)
    25            : toNumber(value)
    26          : value
    27        self.set(value)
    28      }
    29      this.on('change', this.listener)
    30  
    31      // if has initial value, set afterBind
    32      var initValue = getValue(el, multiple, true)
    33      if ((multiple && initValue.length) ||
    34          (!multiple && initValue !== null)) {
    35        this.afterBind = this.listener
    36      }
    37  
    38      // All major browsers except Firefox resets
    39      // selectedIndex with value -1 to 0 when the element
    40      // is appended to a new parent, therefore we have to
    41      // force a DOM update whenever that happens...
    42      this.vm.$on('hook:attached', this.forceUpdate)
    43    },
    44  
    45    update (value) {
    46      var el = this.el
    47      el.selectedIndex = -1
    48      var multi = this.multiple && isArray(value)
    49      var options = el.options
    50      var i = options.length
    51      var op, val
    52      while (i--) {
    53        op = options[i]
    54        val = op.hasOwnProperty('_value')
    55          ? op._value
    56          : op.value
    57        /* eslint-disable eqeqeq */
    58        op.selected = multi
    59          ? indexOf(value, val) > -1
    60          : looseEqual(value, val)
    61        /* eslint-enable eqeqeq */
    62      }
    63    },
    64  
    65    unbind () {
    66      /* istanbul ignore next */
    67      this.vm.$off('hook:attached', this.forceUpdate)
    68    }
    69  }
    70  
    71  /**
    72   * Get select value
    73   *
    74   * @param {SelectElement} el
    75   * @param {Boolean} multi
    76   * @param {Boolean} init
    77   * @return {Array|*}
    78   */
    79  
    80  function getValue (el, multi, init) {
    81    var res = multi ? [] : null
    82    var op, val, selected
    83    for (var i = 0, l = el.options.length; i < l; i++) {
    84      op = el.options[i]
    85      selected = init
    86        ? op.hasAttribute('selected')
    87        : op.selected
    88      if (selected) {
    89        val = op.hasOwnProperty('_value')
    90          ? op._value
    91          : op.value
    92        if (multi) {
    93          res.push(val)
    94        } else {
    95          return val
    96        }
    97      }
    98    }
    99    return res
   100  }
   101  
   102  /**
   103   * Native Array.indexOf uses strict equal, but in this
   104   * case we need to match string/numbers with custom equal.
   105   *
   106   * @param {Array} arr
   107   * @param {*} val
   108   */
   109  
   110  function indexOf (arr, val) {
   111    var i = arr.length
   112    while (i--) {
   113      if (looseEqual(arr[i], val)) {
   114        return i
   115      }
   116    }
   117    return -1
   118  }