Skip to content

Commit 286ae93

Browse files
committed
make paramAttribute deal with attributes containing dashes
1 parent e1a9ec6 commit 286ae93

File tree

6 files changed

+38
-15
lines changed

6 files changed

+38
-15
lines changed

changes.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ By default, all child components **DO NOT** inherit the parent scope. Only anony
7373
})
7474
```
7575

76+
- #### `paramAttributes` change
77+
78+
`paramAttributes` now behaves a little differently when the attribute name contains dashes:
79+
80+
1. If the attribute is a data attribute, the `data-` prefix will be auto stripped;
81+
2. If the attribute still contains dashes, it will be camelized. The reason is because it's inconvenient to access top level properties containing dashes in templates: the expression `my-param` will be parsed as a minus expression unless you use the awkward `this['my-param']` syntax.
82+
83+
This means a param attribute `data-hello` will be set on the vm as `vm.hello`; And `my-param` will be set as `vm.myParam`.
84+
7685
- #### new option: `events`.
7786

7887
When events are used extensively for cross-vm communication, the ready hook can get kinda messy. The new `events` option is similar to its Backbone equivalent, where you can declaratiely register a bunch of event listeners. You can also use it to register hook listeners.
@@ -131,7 +140,7 @@ By default, all child components **DO NOT** inherit the parent scope. Only anony
131140
// -> 2
132141
```
133142

134-
- #### new options: `name`.
143+
- #### new option: `name`.
135144

136145
This option, when used with `Vue.extend`, gives your returned constructor a more descriptive name rather than the generic `VueComponent`. This makes debugging easier when you log instances in the console. For example:
137146

src/api/global.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ exports.extend = function (extendOptions) {
5555

5656
function createClass (name) {
5757
return new Function(
58-
'return function ' + _.camelize(name) +
58+
'return function ' + _.camelize(name, true) +
5959
' (options) { this._init(options) }'
6060
)()
6161
}

src/compile/compile.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,25 +346,31 @@ function compileParamAttributes (el, attrs, options) {
346346
* @return {Function} paramsLinkFn
347347
*/
348348

349+
var dataAttrRE = /^data-/
350+
349351
function makeParamsLinkFn (params, options) {
350352
var def = options.directives['with']
351353
return function paramsLinkFn (vm, el) {
352354
var i = params.length
353-
var param
355+
var param, path
354356
while (i--) {
355357
param = params[i]
358+
// params could contain dashes, which will be
359+
// interpreted as minus calculations by the parser
360+
// so we need to wrap the path here
361+
path = _.camelize(param.name.replace(dataAttrRE, ''))
356362
if (param.dynamic) {
357363
// dynamic param attribtues are bound as v-with.
358364
// we can directly duck the descriptor here beacuse
359365
// param attributes cannot use expressions or
360366
// filters.
361367
vm._bindDir('with', el, {
362-
arg: param.name,
368+
arg: path,
363369
expression: param.value
364370
}, def)
365371
} else {
366372
// just set once
367-
vm.$set(param.name, param.value)
373+
vm.$set(path, param.value)
368374
}
369375
}
370376
}

src/util/lang.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,12 @@ exports.stripQuotes = function (str) {
6363
* @return {String}
6464
*/
6565

66-
var camelRE = /(?:^|[-_])(\w)/g
67-
exports.camelize = function (str) {
68-
return str.replace (camelRE, function (_, c) {
66+
var camelRE = /[-_](\w)/g
67+
var capitalCamelRE = /(?:^|[-_])(\w)/g
68+
69+
exports.camelize = function (str, cap) {
70+
var RE = cap ? capitalCamelRE : camelRE
71+
return str.replace(RE, function (_, c) {
6972
return c ? c.toUpperCase () : '';
7073
})
7174
}

test/unit/specs/compile/compile_spec.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,25 +148,27 @@ if (_.inBrowser) {
148148

149149
it('param attributes', function () {
150150
var options = merge(Vue.options, {
151-
paramAttributes: ['a', 'b', 'c']
151+
paramAttributes: ['a', 'data-some-attr', 'some-other-attr', 'invalid']
152152
})
153153
var def = Vue.options.directives['with']
154154
el.setAttribute('a', '1')
155-
el.setAttribute('b', '{{a}}')
156-
el.setAttribute('c', 'a {{b}} c') // invalid
155+
el.setAttribute('data-some-attr', '{{a}}')
156+
el.setAttribute('some-other-attr', '2')
157+
el.setAttribute('invalid', 'a {{b}} c') // invalid
157158
var linker = compile(el, options)
158159
linker(vm, el)
159160
// should skip literal & invliad
160161
expect(vm._bindDir.calls.count()).toBe(1)
161162
var args = vm._bindDir.calls.argsFor(0)
162163
expect(args[0]).toBe('with')
163164
expect(args[1]).toBe(el)
164-
// skipping descriptor because it's ducked inline
165+
expect(args[2].arg).toBe('someAttr')
165166
expect(args[3]).toBe(def)
166167
// invalid should've warn
167168
expect(_.warn).toHaveBeenCalled()
168169
// literal should've called vm.$set
169170
expect(vm.$set).toHaveBeenCalledWith('a', '1')
171+
expect(vm.$set).toHaveBeenCalledWith('someOtherAttr', '2')
170172
})
171173

172174
it('DocumentFragment', function () {

test/unit/specs/util/lang_spec.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@ describe('Util - Language Enhancement', function () {
2525
})
2626

2727
it('camelize', function () {
28-
expect(_.camelize('abc')).toBe('Abc')
29-
expect(_.camelize('some-long-name')).toBe('SomeLongName')
30-
expect(_.camelize('what_about_this')).toBe('WhatAboutThis')
28+
expect(_.camelize('abc')).toBe('abc')
29+
expect(_.camelize('some-long-name')).toBe('someLongName')
30+
expect(_.camelize('what_about_this')).toBe('whatAboutThis')
31+
expect(_.camelize('abc', true)).toBe('Abc')
32+
expect(_.camelize('some-long-name', true)).toBe('SomeLongName')
33+
expect(_.camelize('what_about_this', true)).toBe('WhatAboutThis')
3134
})
3235

3336
it('bind', function () {

0 commit comments

Comments
 (0)