فهرست منبع

implement bind- and on- syntax

Evan You 10 سال پیش
والد
کامیت
fe8f956e8e
4فایلهای تغییر یافته به همراه55 افزوده شده و 5 حذف شده
  1. 27 4
      src/compiler/compile.js
  2. 8 0
      src/directive.js
  3. 1 0
      src/directives/attr.js
  4. 19 1
      src/directives/class.js

+ 27 - 4
src/compiler/compile.js

@@ -3,6 +3,7 @@ var compileProps = require('./compile-props')
 var config = require('../config')
 var textParser = require('../parsers/text')
 var dirParser = require('../parsers/directive')
+var newDirParser = require('../parsers/directive-new')
 var templateParser = require('../parsers/template')
 var resolveAsset = _.resolveAsset
 var componentDef = require('../directives/component')
@@ -512,7 +513,7 @@ function makeTerminalNodeLinkFn (el, dirName, value, options, def) {
 function compileDirectives (attrs, options) {
   var i = attrs.length
   var dirs = []
-  var attr, name, value, dir, dirName, dirDef
+  var attr, name, value, dir, dirName, dirDef, descriptor
   while (i--) {
     attr = attrs[i]
     name = attr.name
@@ -524,6 +525,7 @@ function compileDirectives (attrs, options) {
       if (process.env.NODE_ENV !== 'production') {
         _.assertAsset(dirDef, 'directive', dirName)
 
+        // deprecations
         if (dirName === 'transition') {
           _.deprecation.V_TRANSITION()
         } else if (dirName === 'class') {
@@ -545,15 +547,36 @@ function compileDirectives (attrs, options) {
         })
       }
     } else
+
     // attribute bindings
     if (bindRE.test(name)) {
-      // TODO handle bind
+      descriptor = newDirParser.parse(value)
+      var attributeName = name.replace(bindRE, '')
+      if (attributeName === 'style' || attributeName === 'class') {
+        dirName = attributeName
+      } else {
+        dirName = 'attr'
+        descriptor.arg = attributeName
+      }
+      dirs.push({
+        name: dirName,
+        descriptors: [descriptor],
+        def: options.directives[dirName]
+      })
     } else
+
     // event handlers
     if (onRE.test(name)) {
-      // TODO handle events
+      descriptor = newDirParser.parse(value)
+      descriptor.arg = name.replace(onRE, '')
+      dirs.push({
+        name: 'on',
+        descriptors: [descriptor],
+        def: options.directives.on
+      })
     } else
-    // deprecated: mustache interpolations inside attribtues
+
+    // TODO: remove this in 1.0.0
     if (config.interpolate) {
       dir = collectAttrDirective(name, value, options)
       if (dir) {

+ 8 - 0
src/directive.js

@@ -61,6 +61,14 @@ Directive.prototype._bind = function (def) {
     this.el && this.el.removeAttribute
   ) {
     this.el.removeAttribute(config.prefix + this.name)
+    // 1.0.0: remove bind/on
+    if (this.name === 'attr') {
+      this.el.removeAttribute('bind-' + this.arg)
+    } else if (this.name === 'class' || this.name === 'style') {
+      this.el.removeAttribute('bind-' + this.name)
+    } else if (this.name === 'on') {
+      this.el.removeAttribute('on-' + this.arg)
+    }
   }
   if (typeof def === 'function') {
     this.update = def

+ 1 - 0
src/directives/attr.js

@@ -15,6 +15,7 @@ module.exports = {
     if (this.arg) {
       this.setAttr(this.arg, value)
     } else if (typeof value === 'object') {
+      // TODO no longer need to support object in 1.0.0
       this.objectHandler(value)
     }
   },

+ 19 - 1
src/directives/class.js

@@ -4,6 +4,8 @@ var removeClass = _.removeClass
 
 module.exports = {
 
+  // TODO: remove unnecessary logic in 1.0.0
+
   bind: function () {
     // interpolations like class="{{abc}}" are converted
     // to v-class, and we need to remove the raw,
@@ -27,6 +29,8 @@ module.exports = {
         this.handleObject(stringToObject(value))
       } else if (_.isPlainObject(value)) {
         this.handleObject(value)
+      } else if (_.isArray(value)) {
+        this.handleArray(value)
       } else {
         this.cleanup()
       }
@@ -46,12 +50,20 @@ module.exports = {
     }
   },
 
+  handleArray: function (value) {
+    this.cleanup(value)
+    for (var i = 0, l = value.length; i < l; i++) {
+      addClass(this.el, value[i])
+    }
+    this.prevKeys = value
+  },
+
   cleanup: function (value) {
     if (this.prevKeys) {
       var i = this.prevKeys.length
       while (i--) {
         var key = this.prevKeys[i]
-        if (!value || !value.hasOwnProperty(key)) {
+        if (!value || !contains(value, key)) {
           removeClass(this.el, key)
         }
       }
@@ -68,3 +80,9 @@ function stringToObject (value) {
   }
   return res
 }
+
+function contains (value, key) {
+  return _.isArray(value)
+    ? value.indexOf(key) > -1
+    : value.hasOwnProperty(key)
+}