Skip to content

Commit ee2b99e

Browse files
committed
remove v-with
1 parent c02a5a9 commit ee2b99e

File tree

15 files changed

+250
-350
lines changed

15 files changed

+250
-350
lines changed

component.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@
3838
"src/directives/model/radio.js",
3939
"src/directives/model/select.js",
4040
"src/directives/on.js",
41+
"src/directives/prop.js",
4142
"src/directives/ref.js",
4243
"src/directives/repeat.js",
4344
"src/directives/show.js",
4445
"src/directives/style.js",
4546
"src/directives/text.js",
4647
"src/directives/transition.js",
47-
"src/directives/with.js",
4848
"src/filters/array-filters.js",
4949
"src/filters/index.js",
5050
"src/instance/compile.js",

examples/svg/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<div id="demo">
2525
<!-- Use the component -->
2626
<svg width="200" height="200">
27-
<g v-component="polygraph" v-with="stats:stats"></g>
27+
<g v-component="polygraph" stats="{{stats}}"></g>
2828
</svg>
2929
<!-- controls -->
3030
<div v-repeat="stats">

examples/svg/svg.js

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ var stats = [
1010

1111
// A resusable polygon graph component
1212
Vue.component('polygraph', {
13+
props: ['stats'],
1314
template: '#polygraph-template',
1415
computed: {
1516
// a computed property for the polygon's points

examples/tree/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
<ul id="demo">
4747
<li class="item"
4848
v-component="item"
49-
v-with="model: treeData">
49+
model="{{treeData}}">
5050
</li>
5151
</ul>
5252

examples/tree/tree.js

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ var data = {
3030

3131
// define the item component
3232
Vue.component('item', {
33+
props: ['model'],
3334
template: '#item-template',
3435
data: function () {
3536
return {

src/compiler/compile.js

+34-52
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ var textParser = require('../parsers/text')
44
var dirParser = require('../parsers/directive')
55
var templateParser = require('../parsers/template')
66

7+
// internal directives
8+
var propDef = require('../directives/prop')
9+
// var componentDef = require('../directives/component')
10+
711
module.exports = compile
812

913
/**
@@ -108,12 +112,11 @@ function teardownDirs (vm, dirs, destroying) {
108112

109113
/**
110114
* Compile the root element of a component. There are
111-
* 4 types of things to process here:
115+
* 3 types of things to process here:
112116
*
113117
* 1. props on parent container (child scope)
114-
* 2. v-with on parent container (child scope)
115-
* 3. other attrs on parent container (parent scope)
116-
* 4. attrs on the component template root node, if
118+
* 2. other attrs on parent container (parent scope)
119+
* 3. attrs on the component template root node, if
117120
* replace:true (child scope)
118121
*
119122
* Also, if this is a block instance, we only need to
@@ -129,37 +132,25 @@ function compileRoot (el, options) {
129132
var containerAttrs = options._containerAttrs
130133
var replacerAttrs = options._replacerAttrs
131134
var props = options.props
132-
var propsLinkFn, withLinkFn, parentLinkFn, replacerLinkFn
135+
var propsLinkFn, parentLinkFn, replacerLinkFn
133136
// 1. props
134137
propsLinkFn = props
135-
? compileProps(el, containerAttrs, props, options)
138+
? compileProps(el, containerAttrs, props)
136139
: null
137-
// 2. v-with
138-
var withName = config.prefix + 'with'
139-
var withVal = containerAttrs && containerAttrs[withName]
140-
if (withVal) {
141-
containerAttrs[withName] = null
142-
withLinkFn = makeNodeLinkFn([{
143-
name: 'with',
144-
descriptors: dirParser.parse(withVal),
145-
def: options.directives['with']
146-
}])
147-
}
148140
if (!isBlock) {
149-
// 3. container attributes
141+
// 2. container attributes
150142
if (containerAttrs) {
151143
parentLinkFn = compileDirectives(containerAttrs, options)
152144
}
153145
if (replacerAttrs) {
154-
// 4. replacer attributes
146+
// 3. replacer attributes
155147
replacerLinkFn = compileDirectives(replacerAttrs, options)
156148
}
157149
}
158150
return function rootLinkFn (vm, el, host) {
159-
// explicitly passing null to props and v-with
151+
// explicitly passing null to props
160152
// linkers because they don't need a real element
161153
if (propsLinkFn) propsLinkFn(vm, null)
162-
if (withLinkFn) withLinkFn(vm, null)
163154
if (parentLinkFn) parentLinkFn(vm.$parent, el, host)
164155
if (replacerLinkFn) replacerLinkFn(vm, el, host)
165156
}
@@ -384,14 +375,13 @@ function makeChildLinkFn (linkFns) {
384375
* @param {Element|DocumentFragment} el
385376
* @param {Object} attrs
386377
* @param {Array} propNames
387-
* @param {Object} options
388378
* @return {Function} propsLinkFn
389379
*/
390380

391-
function compileProps (el, attrs, propNames, options) {
381+
function compileProps (el, attrs, propNames) {
392382
var props = []
393383
var i = propNames.length
394-
var name, value, param
384+
var name, value, prop
395385
while (i--) {
396386
name = propNames[i]
397387
if (/[A-Z]/.test(name)) {
@@ -404,8 +394,9 @@ function compileProps (el, attrs, propNames, options) {
404394
)
405395
}
406396
value = attrs[name]
407-
if (value !== null) {
408-
param = {
397+
/* jshint eqeqeq:false */
398+
if (value != null) {
399+
prop = {
409400
name: name,
410401
value: value
411402
}
@@ -415,53 +406,44 @@ function compileProps (el, attrs, propNames, options) {
415406
el.removeAttribute(name)
416407
}
417408
attrs[name] = null
418-
param.dynamic = true
419-
param.value = textParser.tokensToExp(tokens)
420-
param.oneTime = tokens.length === 1 && tokens[0].oneTime
409+
prop.dynamic = true
410+
prop.value = textParser.tokensToExp(tokens)
411+
prop.oneTime = tokens.length === 1 && tokens[0].oneTime
421412
}
422-
props.push(param)
413+
props.push(prop)
423414
}
424415
}
425-
return makeParamsLinkFn(props, options)
416+
return makePropsLinkFn(props)
426417
}
427418

428419
/**
429-
* Build a function that applies param attributes to a vm.
420+
* Build a function that applies props to a vm.
430421
*
431422
* @param {Array} props
432-
* @param {Object} options
433423
* @return {Function} propsLinkFn
434424
*/
435425

436426
var dataAttrRE = /^data-/
437427

438-
function makeParamsLinkFn (props, options) {
439-
var def = options.directives['with']
428+
function makePropsLinkFn (props) {
440429
return function propsLinkFn (vm, el) {
441430
var i = props.length
442-
var param, path
431+
var prop, path
443432
while (i--) {
444-
param = props[i]
433+
prop = props[i]
445434
// props could contain dashes, which will be
446435
// interpreted as minus calculations by the parser
447436
// so we need to wrap the path here
448-
path = _.camelize(param.name.replace(dataAttrRE, ''))
449-
if (param.dynamic) {
450-
if (param.oneTime) {
451-
vm.$set(path, vm.$parent.$get(param.value))
452-
} else {
453-
// dynamic param attribtues are bound as v-with.
454-
// we can directly duck the descriptor here beacuse
455-
// param attributes cannot use expressions or
456-
// filters.
457-
vm._bindDir('with', el, {
458-
arg: path,
459-
expression: param.value
460-
}, def)
461-
}
437+
path = _.camelize(prop.name.replace(dataAttrRE, ''))
438+
if (prop.dynamic) {
439+
vm._bindDir('prop', el, {
440+
arg: path,
441+
expression: prop.value,
442+
oneWay: prop.oneTime
443+
}, propDef)
462444
} else {
463445
// just set once
464-
vm.$set(path, param.value)
446+
vm.$set(path, prop.value)
465447
}
466448
}
467449
}

src/directive.js

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function Directive (name, el, vm, descriptor, def, host) {
3333
this.arg = descriptor.arg
3434
this.filters = _.resolveFilters(vm, descriptor.filters)
3535
// private
36+
this._descriptor = descriptor
3637
this._host = host
3738
this._locked = false
3839
this._bound = false

src/directives/component.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var templateParser = require('../parsers/template')
33

44
module.exports = {
55

6+
_internal: true,
67
isLiteral: true,
78

89
/**

src/directives/index.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@ exports.transition = require('./transition')
1414
exports.on = require('./on')
1515
exports.model = require('./model')
1616

17-
// child vm directives
18-
exports.component = require('./component')
17+
// logic control directives
1918
exports.repeat = require('./repeat')
2019
exports['if'] = require('./if')
2120

2221
// child vm communication directives
23-
exports['with'] = require('./with')
24-
exports.events = require('./events')
22+
exports.events = require('./events')
23+
24+
// internal directives that should not be used directly
25+
// but we still want to expose them for advanced usage.
26+
exports.component = require('./component')
27+
exports._prop = require('./prop')

src/directives/prop.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
var _ = require('../util')
2+
var Watcher = require('../watcher')
3+
var expParser = require('../parsers/expression')
4+
5+
module.exports = {
6+
7+
_internal: true,
8+
9+
bind: function () {
10+
11+
var child = this.vm
12+
var parent = child.$parent
13+
var childKey = this.arg
14+
var parentKey = this.expression
15+
16+
// simple lock to avoid circular updates.
17+
// without this it would stabilize too, but this makes
18+
// sure it doesn't cause other watchers to re-evaluate.
19+
var locked = false
20+
var lock = function () {
21+
locked = true
22+
_.nextTick(unlock)
23+
}
24+
var unlock = function () {
25+
locked = false
26+
}
27+
28+
this.parentWatcher = new Watcher(
29+
parent,
30+
parentKey,
31+
function (val) {
32+
if (!locked) {
33+
lock()
34+
child.$set(childKey, val)
35+
}
36+
}
37+
)
38+
39+
// set the child initial value first, before setting
40+
// up the child watcher to avoid triggering it
41+
// immediately.
42+
child.$set(childKey, this.parentWatcher.value)
43+
44+
// only setup two-way binding if this is not a one-way
45+
// binding, and the parentKey is a "settable" simple path.
46+
if (
47+
!this._descriptor.oneWay &&
48+
expParser.isSimplePath(parentKey)
49+
) {
50+
this.childWatcher = new Watcher(
51+
child,
52+
childKey,
53+
function (val) {
54+
if (!locked) {
55+
lock()
56+
parent.$set(parentKey, val)
57+
}
58+
}
59+
)
60+
}
61+
},
62+
63+
unbind: function () {
64+
if (this.parentWatcher) {
65+
this.parentWatcher.teardown()
66+
}
67+
if (this.childWatcher) {
68+
this.childWatcher.teardown()
69+
}
70+
}
71+
72+
}

0 commit comments

Comments
 (0)