ソースを参照

simplify v-repeat syntax

Evan You 12 年 前
コミット
cd90e647a7

+ 8 - 8
examples/todomvc/index.html

@@ -27,28 +27,28 @@
                 <ul id="todo-list">
                     <li
                         class="todo"
-                        v-repeat="todo:todos"
-                        v-if="todoFilter(todo.completed)"
+                        v-repeat="todos"
+                        v-if="todoFilter(completed)"
                         v-class="
-                            completed : todo.completed,
-                            editing   : todo == editedTodo
+                            completed : completed,
+                            editing   : this == editedTodo
                         "
                     >
                         <div class="view">
                             <input
                                 class="toggle"
                                 type="checkbox"
-                                v-model="todo.completed"
+                                v-model="completed"
                                 v-on="change:toggleTodo"
                             >
-                            <label v-text="todo.title" v-on="dblclick:editTodo"></label>
+                            <label v-text="title" v-on="dblclick:editTodo"></label>
                             <button class="destroy" v-on="click:removeTodo"></button>
                         </div>
                         <input
                             class="edit"
                             type="text"
-                            v-model="todo.title"
-                            v-todo-focus="todo == editedTodo"
+                            v-model="title"
+                            v-todo-focus="this == editedTodo"
                             v-on="
                                 blur  : doneEdit,
                                 keyup : doneEdit | key enter,

+ 10 - 8
examples/todomvc/js/app.js

@@ -1,3 +1,5 @@
+Vue.config({debug:true})
+
 var filters = {
     all: function () { return true },
     active: function (completed) { return !completed },
@@ -43,32 +45,32 @@ var app = new Vue({
         },
 
         removeTodo: function (e) {
-            this.todos.remove(e.item)
-            this.remaining -= e.item.completed ? 0 : 1
+            this.todos.remove(e.targetVM.$scope)
+            this.remaining -= e.targetVM.completed ? 0 : 1
             todoStorage.save()
         },
 
         toggleTodo: function (e) {
-            this.remaining += e.item.completed ? -1 : 1
+            this.remaining += e.targetVM.completed ? -1 : 1
             todoStorage.save()
         },
 
         editTodo: function (e) {
-            this.beforeEditCache = e.item.title
-            this.editedTodo = e.item
+            this.beforeEditCache = e.targetVM.title
+            this.editedTodo = e.targetVM
         },
 
         doneEdit: function (e) {
             if (!this.editedTodo) return
             this.editedTodo = null
-            e.item.title = e.item.title.trim()
-            if (!e.item.title) this.removeTodo(e)
+            e.targetVM.title = e.targetVM.title.trim()
+            if (!e.targetVM.title) this.removeTodo(e)
             todoStorage.save()
         },
 
         cancelEdit: function (e) {
             this.editedTodo = null
-            e.item.title = this.beforeEditCache
+            e.targetVM.title = this.beforeEditCache
         },
 
         removeCompleted: function () {

+ 6 - 2
src/compiler.js

@@ -95,7 +95,8 @@ function Compiler (vm, options) {
     // for repeated items, create an index binding
     // which should be inenumerable but configurable
     if (compiler.repeat) {
-        scope.$index = compiler.repeatIndex
+        //scope.$index = compiler.repeatIndex
+        def(scope, '$index', compiler.repeatIndex, false, true)
         compiler.createBinding('$index')
     }
 
@@ -463,10 +464,13 @@ CompilerProto.define = function (key, binding) {
         compiler.markComputed(binding)
     }
 
-    if (!(key in scope)) {
+    // $index is inenumerable
+    if (!(key in scope) && key !== '$index') {
         scope[key] = undefined
     }
 
+    // if the scope object is already observed, that means
+    // this binding is created late. we need to observe it now.
     if (scope.__observer__) {
         Observer.convert(scope, key)
     }

+ 2 - 6
src/directives/on.js

@@ -50,8 +50,7 @@ module.exports = {
                 var target = delegateCheck(e.target, delegator, identifier)
                 if (target) {
                     e.el = target
-                    e.vm = target.vue_viewmodel
-                    e.item = e.vm.$scope[compiler.repeatPrefix]
+                    e.targetVM = target.vue_viewmodel
                     handler.call(ownerVM, e)
                 }
             }
@@ -64,10 +63,7 @@ module.exports = {
             var vm = this.vm
             this.handler = function (e) {
                 e.el = e.currentTarget
-                e.vm = vm
-                if (compiler.repeat) {
-                    e.item = vm.$scope[compiler.repeatPrefix]
-                }
+                e.targetVM = vm
                 handler.call(ownerVM, e)
             }
             this.el.addEventListener(event, this.handler)

+ 3 - 8
src/directives/repeat.js

@@ -51,8 +51,7 @@ var mutationHandlers = {
     },
 
     sort: function () {
-        var key = this.arg,
-            vms = this.vms,
+        var vms = this.vms,
             col = this.collection,
             l = col.length,
             sorted = new Array(l),
@@ -61,7 +60,7 @@ var mutationHandlers = {
             data = col[i]
             for (j = 0; j < l; j++) {
                 vm = vms[j]
-                if (vm.$scope[key] === data) {
+                if (vm.$scope === data) {
                     sorted[i] = vm
                     break
                 }
@@ -153,7 +152,6 @@ module.exports = {
 
         var node    = this.el.cloneNode(true),
             ctn     = this.container,
-            scope   = {},
             ref, item
 
         // append node into DOM first
@@ -171,16 +169,13 @@ module.exports = {
             }, this.compiler)
         }
 
-        // set data on scope and compile
-        scope[this.arg] = data || {}
         item = new this.ChildVM({
             el: node,
-            scope: scope,
+            scope: data,
             compilerOptions: {
                 repeat: true,
                 repeatIndex: index,
                 repeatCollection: this.collection,
-                repeatPrefix: this.arg,
                 parentCompiler: this.compiler,
                 delegator: ctn
             }

+ 3 - 3
test/functional/fixtures/nested-repeat.html

@@ -8,10 +8,10 @@
     <body>
         <div id="test">
             <ul>
-                <li v-repeat="item : items" v-class="'list-' + $index">
+                <li v-repeat="items" v-class="'list-' + $index">
                     <ul>
-                        <li v-repeat="subitem : item.items" v-class="'list-' + $index">
-                            {{$parent.$index + '.' + $index + ' : ' + item.title + '&lt;-' + subitem.title}}
+                        <li v-repeat="items" v-class="'list-' + $index">
+                            {{$parent.$index + '.' + $index + ' : ' + $parent.title + '&lt;-' + title}}
                         </li>
                     </ul>
                 </li>

+ 0 - 0
test/functional/fixtures/nested-viewmodels.html → test/functional/fixtures/nested-vms.html


+ 2 - 2
test/functional/fixtures/repeated-items.html

@@ -20,8 +20,8 @@
             </p>
             <p>Total items: <span class="count" v-text="items.length"></span></p>
             <ul>
-                <li class="item" v-repeat="item:items">
-                    {{$index}} {{item.title}}
+                <li class="item" v-repeat="items">
+                    {{$index}} {{title}}
                 </li>
             </ul>
         </div>

+ 4 - 4
test/functional/fixtures/repeated-vms.html

@@ -6,19 +6,19 @@
         <script src="../../../dist/vue.js"></script>
     </head>
     <body>
-        <div class="item" v-repeat="item:items" v-component="item" v-on="click:click">
-            {{msg + ' ' + item.title}}
+        <div class="item" v-repeat="items" v-component="item" v-on="click:click">
+            {{msg + ' ' + title}}
         </div>
         <script>
             Vue.config({ debug: true })
             
             Vue.component('item', {
                 ready: function () {
-                    this.item.title += ' init'
+                    this.title += ' init'
                 },
                 proto: {
                     click: function () {
-                        this.item.title += ' click'
+                        this.title += ' click'
                     }
                 },
                 scope: {

+ 8 - 8
test/functional/fixtures/transition.html

@@ -43,19 +43,19 @@
             </div>
             <div
                 class="test"
-                v-repeat="item:items"
-                v-if="filter(item)"
+                v-repeat="items"
+                v-if="filter(this)"
                 v-transition
-                v-attr="data-id:item.a">
-                {{item.a}}
+                v-attr="data-id:a">
+                {{a}}
             </div>
             <div
                 class="test"
-                v-repeat="item:items"
-                v-show="filter(item)"
+                v-repeat="items"
+                v-show="filter(this)"
                 v-transition
-                v-attr="data-id:item.a">
-                {{item.a}}
+                v-attr="data-id:a">
+                {{a}}
             </div>
         </div>
         <h1 style="margin:0">123</h1>

+ 1 - 1
test/functional/specs/nested-vms.js

@@ -1,7 +1,7 @@
 casper.test.begin('Nested Viewmodels', 7, function (test) {
     
     casper
-    .start('./fixtures/nested-viewmodels.html', function () {
+    .start('./fixtures/nested-vms.html', function () {
 
         test.assertSelectorHasText('.ancestor', 'Andy Johnson')
         test.assertSelectorHasText('.jack', 'Jack, son of Andy')