Skip to content

Commit

Permalink
separate computed properties into computed option
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jan 26, 2014
1 parent 62fd49a commit 7a6169c
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 35 deletions.
9 changes: 6 additions & 3 deletions examples/firebase/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ var app = new Vue({
validation: {
name: false,
email: false
},
}
},
computed: {
isValid: {
$get: function () {
var valid = true
Expand All @@ -45,13 +47,14 @@ var app = new Vue({
methods: {
addUser: function (e) {
e.preventDefault()
console.log(this)
if (this.isValid) {
Users.push(this.newUser)
this.newUser = {}
}
},
removeUser: function (e) {
new Firebase(baseURL + 'users/' + e.targetVM.id).remove()
removeUser: function (user) {
new Firebase(baseURL + 'users/' + user.id).remove()
}
}
})
2 changes: 1 addition & 1 deletion examples/firebase/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<ul>
<li class="user" v-repeat="users" v-transition>
<span>{{name}} - {{email}}</span>
<button v-on="click:removeUser">X</button>
<button v-on="click:removeUser(this)">X</button>
</li>
</ul>
<form id="form" v-on="submit:addUser">
Expand Down
6 changes: 4 additions & 2 deletions examples/todomvc/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ var app = new Vue({

// data
data: {
// fetch the saved todos from localStorage
todos: todoStorage.fetch(),
// a computed property with custom getter/setter
},

// computed property
computed: {
allDone: {
$get: function () {
return this.remaining === 0
Expand Down
37 changes: 24 additions & 13 deletions src/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ function Compiler (vm, options) {
// setup observer
compiler.setupObserver()

// create bindings for computed properties
var computed = options.computed
if (computed) {
for (var key in computed) {
compiler.createBinding(key)
}
}

// beforeCompile hook
compiler.execHook('beforeCompile', 'created')

Expand Down Expand Up @@ -482,21 +490,24 @@ CompilerProto.define = function (key, binding) {
var compiler = this,
data = compiler.data,
vm = compiler.vm,
ob = data.__observer__

if (!(key in data)) {
data[key] = undefined
}
comps = compiler.options.computed,
ob = data.__observer__,
value

// if the data object is already observed, but the key
// is not observed, we need to add it to the observed keys.
if (ob && !(key in ob.values)) {
Observer.convert(data, key)
}

var value = binding.value = data[key]
if (utils.typeOf(value) === 'Object' && value.$get) {
if (comps && comps[key]) {
// computed property
value = binding.value = comps[key]
compiler.markComputed(binding)
} else {
if (!(key in data)) {
data[key] = undefined
}
// if the data object is already observed, but the key
// is not observed, we need to add it to the observed keys.
if (ob && !(key in ob.values)) {
Observer.convert(data, key)
}
value = binding.value = data[key]
}

Object.defineProperty(vm, key, {
Expand Down
10 changes: 6 additions & 4 deletions test/functional/fixtures/nested-props.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ <h3>Computed property that concats the two: <span v-text="d"></span></h3>
this.a = data
},
data: {
hidden: {
a: 1,
b: 2
}
},
computed: {
d: {
$get: function () {
return this.msg + (this.a.b.c || '') + (this.a.c || '')
}
},
hidden: {
a: 1,
b: 2
},
sum: {
$get: function () {
return this.hidden.a + this.hidden.b
Expand Down
4 changes: 3 additions & 1 deletion test/functional/fixtures/share-data.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
new Vue({
el: '#d',
data: {
shared: shared,
shared: shared
},
computed: {
source: {
$get: function () {
return JSON.stringify(this.shared)
Expand Down
47 changes: 42 additions & 5 deletions test/functional/fixtures/validation.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,59 @@
</head>
<body>
<div id="test">
email: <input type="text" v-model="a | email" v-class="valid:validation.email" name="email">
name: <input type="text" v-model="name | nameValidator" v-class="valid:validation.name" name="name">
email: <input type="text" v-model="email | emailValidator" v-class="valid:validation.email" name="email">
<a id="go" v-on="click:go">Go</a>
<ul>
<li class="user" v-repeat="users">
{{name}} {{email}}
</li>
</ul>
</div>
<script>
var RE = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
var test = new Vue({
el: '#test',
filters: {
email: function (val) {
this.validation.email = val === '' || RE.test(val)
nameValidator: function (val) {
this.validation.name = !!val
return val
},
emailValidator: function (val) {
this.validation.email = RE.test(val)
return val
}
},
data: {
a: 'hihi',
name: '',
email: '',
users: [],
validation: {
email: true
email: false,
name: false
}
},
computed: {
isValid: {
$get: function () {
var valid = true
for (var key in this.validation) {
if (!this.validation[key]) {
valid = false
}
}
return valid
}
}
},
methods: {
go: function () {
if (this.isValid) {
this.users.push({
name: this.name,
email: this.email
})
}
}
}
})
Expand Down
28 changes: 22 additions & 6 deletions test/functional/specs/validation.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,39 @@
casper.test.begin('Validation', 4, function (test) {
casper.test.begin('Validation', 9, function (test) {

casper
.start('./fixtures/validation.html')
.then(function () {
test.assertElementCount('.valid', 0)
this.sendKeys('input', '@hello.com')
this.sendKeys('input[name="name"]', 'haha')
})
.then(function () {
test.assertElementCount('.valid', 1)
this.sendKeys('input[name="email"]', 'hello')
})
.then(function () {
// email should be invalid
test.assertElementCount('.valid', 1)
this.sendKeys('input[name="email"]', 'heo@bar.com', { reset: true })
})
.then(function () {
// email should be valid now
test.assertField('email', 'heo@bar.com')
test.assertElementCount('.valid', 2)
})
// test edit/insertion when there are filters
.thenEvaluate(function () {
document.querySelector('input').setSelectionRange(4,4)
document.querySelector('input[name="email"]').setSelectionRange(2,2)
})
.then(function () {
this.sendKeys('input', 'hoho')
this.sendKeys('input[name="email"]', 'll')
})
.then(function () {
test.assertElementCount('.valid', 1)
test.assertField('email', 'hihihoho@hello.com')
test.assertElementCount('.valid', 2)
test.assertField('email', 'hello@bar.com')
})
.thenClick('#go', function () {
test.assertElementCount('.user', 1)
test.assertSelectorHasText('.user', 'haha hello@bar.com')
})
.run(function () {
test.done()
Expand Down

0 comments on commit 7a6169c

Please sign in to comment.