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

support new element ref syntax

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

+ 14 - 5
src/compiler/compile.js

@@ -11,7 +11,8 @@ var resolveAsset = _.resolveAsset
 // special binding prefixes
 var bindRE = /^bind-|^:/
 var onRE = /^on-/
-var specialAttrRE = /^(bind-|:)?(el|transition)$/
+var transitionRE = /^(bind-|:)?transition$/
+var nodeRefRE = /^\$\$\./
 
 // terminal directives
 var terminalDirectives = [
@@ -545,12 +546,11 @@ function makeTerminalNodeLinkFn (el, dirName, value, options, def) {
 function compileDirectives (attrs, options) {
   var i = attrs.length
   var dirs = []
-  var attr, name, value, dirName, dirDef, parsed, isLiteral
+  var attr, name, value, dirName, dirDef, isLiteral
   while (i--) {
     attr = attrs[i]
     name = attr.name
     value = attr.value
-    parsed = dirParser.parse(value)
     // Core directive
     if (name.indexOf(config.prefix) === 0) {
       dirName = name.slice(config.prefix.length)
@@ -585,14 +585,22 @@ function compileDirectives (attrs, options) {
       })
     } else
 
-    // special attribtues: transition & el
-    if (specialAttrRE.test(name)) {
+    // special attribute: transition
+    if (transitionRE.test(name)) {
       dirName = name.replace(bindRE, '')
       pushDir(dirName, internalDirectives[dirName], {
         literal: !bindRE.test(name)
       })
     } else
 
+    // node ref: $$.xxx
+    if (nodeRefRE.test(name)) {
+      value = _.camelize(name.replace(nodeRefRE, ''))
+      pushDir('el', internalDirectives.el, {
+        literal: true
+      })
+    } else
+
     // attribute bindings
     if (bindRE.test(name)) {
       dirName = name.replace(bindRE, '')
@@ -615,6 +623,7 @@ function compileDirectives (attrs, options) {
    */
 
   function pushDir (dirName, def, opts) {
+    var parsed = dirParser.parse(value)
     var dir = {
       name: dirName,
       attr: name,

+ 0 - 3
src/directives/internal/el.js

@@ -5,9 +5,6 @@ module.exports = {
   priority: 1500,
 
   update: function (id) {
-    if (this.id) {
-      this.unbind()
-    }
     this.id = id
     var refs = (this._scope || this.vm).$$
     if (refs.hasOwnProperty(id)) {

+ 6 - 25
test/unit/specs/directives/internal/el_spec.js

@@ -17,45 +17,26 @@ if (_.inBrowser) {
         data: {
           ok: true
         },
-        template: '<div v-if="ok" el="test" id="test"></div>'
+        template: '<div v-if="ok" $$.test-el id="test"></div>'
       })
-      expect(vm.$$.test).toBeTruthy()
-      expect(vm.$$.test.id).toBe('test')
+      expect(vm.$$.testEl).toBeTruthy()
+      expect(vm.$$.testEl.id).toBe('test')
       vm.ok = false
       _.nextTick(function () {
-        expect(vm.$$.test).toBeNull()
+        expect(vm.$$.testEl).toBeNull()
         vm.ok = true
         _.nextTick(function () {
-          expect(vm.$$.test.id).toBe('test')
+          expect(vm.$$.testEl.id).toBe('test')
           done()
         })
       })
     })
 
-    it('bind-el', function (done) {
-      var vm = new Vue({
-        el: el,
-        data: {
-          id: 'test'
-        },
-        template: '<div bind-el="id" id="test"></div>'
-      })
-      expect(vm.$$.test).toBeTruthy()
-      expect(vm.$$.test.id).toBe('test')
-      vm.id = 'changed'
-      _.nextTick(function () {
-        expect(vm.$$.test).toBeNull()
-        expect(vm.$$.changed).toBeTruthy()
-        expect(vm.$$.changed.id).toBe('test')
-        done()
-      })
-    })
-
     it('inside v-for', function () {
       var vm = new Vue({
         el: el,
         data: { items: [1, 2] },
-        template: '<div v-for="n in items"><p el="test">{{n}}</p>{{$$.test.textContent}}</div>'
+        template: '<div v-for="n in items"><p $$.test>{{n}}</p>{{$$.test.textContent}}</div>'
       })
       expect(vm.$el.textContent).toBe('1122')
     })