Skip to content

Commit b496632

Browse files
author
An Phan
committed
Support for mutiple class names as key (close vuejs#2571)
This commit adds support for using multiple class names as key when specifying a `:class` object, for example `<div :class="{ 'a b c': flag }">`. Previously, doing so will trigger an uncaught InvalidCharacterError, as spaces are not allowed in DOM tokens. Feature request vuejs#2571 should also be satisfied by this commit.
1 parent a2fa045 commit b496632

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

src/directives/internal/class.js

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,16 @@ export default {
4141
},
4242

4343
cleanup (value) {
44-
if (this.prevKeys) {
45-
var i = this.prevKeys.length
46-
while (i--) {
47-
var key = this.prevKeys[i]
48-
if (!key) continue
49-
if (isPlainObject(key)) {
50-
var keys = Object.keys(key)
51-
for (var k = 0; k < keys.length; k++) {
52-
removeClass(this.el, keys[k])
53-
}
54-
} else {
55-
removeClass(this.el, key)
56-
}
44+
if (!this.prevKeys) return
45+
46+
var i = this.prevKeys.length
47+
while (i--) {
48+
var key = this.prevKeys[i]
49+
if (!key) continue
50+
51+
var keys = isPlainObject(key) ? Object.keys(key) : [key]
52+
for (var j = 0, l = keys.length; j < l; j++) {
53+
toggleClasses(this.el, keys[j], removeClass)
5754
}
5855
}
5956
}
@@ -63,9 +60,8 @@ function setObjectClasses (el, obj) {
6360
var keys = Object.keys(obj)
6461
for (var i = 0, l = keys.length; i < l; i++) {
6562
var key = keys[i]
66-
if (obj[key]) {
67-
addClass(el, key)
68-
}
63+
if (!obj[key]) continue
64+
toggleClasses(el, key, addClass)
6965
}
7066
}
7167

@@ -77,3 +73,31 @@ function stringToObject (value) {
7773
}
7874
return res
7975
}
76+
77+
/**
78+
* Add or remove a class/classes on an element
79+
*
80+
* @param {Element} el
81+
* @param {String} key The class name. This may or may not
82+
* contain a space character, in such a
83+
* case we'll deal with multiple class
84+
* names at once.
85+
* @param {Function} fn
86+
*/
87+
88+
function toggleClasses (el, key, fn) {
89+
key = key.trim()
90+
91+
if (key.indexOf(' ') === -1) {
92+
fn(el, key)
93+
return
94+
}
95+
96+
// The key contains one or more space characters.
97+
// Since a class name doesn't accept such characters, we
98+
// treat it as multiple classes.
99+
var keys = key.split(' ')
100+
for (var i = 0, l = keys.length; i < l; i++) {
101+
fn(el, keys[i])
102+
}
103+
}

test/unit/specs/directives/internal/class_spec.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ describe(':class', function () {
3434
expect(el.className).toBe('hoho b')
3535
dir.update(null)
3636
expect(el.className).toBe('hoho')
37+
38+
dir.update({
39+
'a b': true,
40+
c: false
41+
})
42+
expect(el.className).toBe('hoho a b')
43+
dir.update({
44+
c: true
45+
})
46+
expect(el.className).toBe('hoho c')
3747
})
3848

3949
it('array value', function () {

0 commit comments

Comments
 (0)