Skip to content

Class binding - can't pass string of classes when mixing array with object definition #2682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sqal opened this issue Apr 16, 2016 · 11 comments

Comments

@sqal
Copy link
Contributor

sqal commented Apr 16, 2016

Vue.js version

1.0.21

Reproduction Link

http://www.webpackbin.com/4kszqXok-

Steps to reproduce

Try to bind multiple classes like this :class="['class-1 class-2', { 'class-3': true }]"

What is Expected?

Be be able to bind classes like I described above.

What is actually happening?

Getting console error:

Uncaught InvalidCharacterError: Failed to execute 'add' on 'DOMTokenList': The token provided ('color-green text-uppercase') contains HTML space characters, which are not valid in tokens

Is this bug or am i doing it right wrong?

@posva
Copy link
Member

posva commented Apr 16, 2016

Hello @sqal
Why would you pass a static class name in the binding? you should add class-1 and class-2 directly on the class attribute

I'm pretty sure the feature is really easy to add but adding static class names on the class binding doesn't look right to me. Have you taken a look at the guide section concerning class bindings? It may help you http://vuejs.org/guide/class-and-style.html#ad

@simplesmiler
Copy link
Member

As far as I'm aware, it's already fixed in dev: #2678

@sqal
Copy link
Contributor Author

sqal commented Apr 16, 2016

@posva Hi. I have dropdown component and I want to bind some custom classes from options prop and also some additional classes if some of the options are true e.g.

...
<div v-show="open" class="dropdown-menu" :class="[options.menuClasses, { 'dropdown-menu-right': options.right }]" :transition="options.effect">
  <slot name="dropdown-content"></slot>
</div>
...

name: 'Dropdown',
props: {
  open: {
    type: Boolean,
    twoWay: true,
    default: false,
  },
  options: {
    type: Object,
    coerce(options) {
      return Object.assign({}, dropdownDefaults, options);
    },
  },
},
...

@posva
Copy link
Member

posva commented Apr 16, 2016

I see, I didn't know it was already supported 😅
I'd have created an array with a computed property

Since it's already fixed I'm closing the issue. If you see the problem appears in the new release, feel free to open the issue again.

@posva posva closed this as completed Apr 16, 2016
@crswll
Copy link

crswll commented Apr 16, 2016

Just a heads up, that use isn't actually in dev.

@sqal is doing:

:class="['class-1 class-2', { 'class-3': true }]"

but

:class="['class-1', 'class-2', { 'class-3': true }]"

is what would work in dev.

@posva posva reopened this Apr 16, 2016
@crswll
Copy link

crswll commented Apr 17, 2016

Wait... I'm sorry. I'm wrong. You can close it again. Long day. I even wrote that test.

@phanan phanan closed this as completed Apr 17, 2016
@bensmeets
Copy link

In case it helps, might be too new @ Vue, but I couldn't get the above "static" example working when that static value is coming from the Vuex "store" property. It seems to always lag 1 "commit" behind.

<template>
  <div id="app" :class="[this.$store.state.bodyColor, { 'nav-is-open': this.$store.state.menu }]">
    <span>{{this.$store.state.bodyColor}}</span>
  </div>
</template>

in the above example, the is updated, but the classes are not, whenever the store changes.

@sqal
Copy link
Contributor Author

sqal commented Jul 4, 2017

@bensmeets it probably doesn't work because you use this inside the template. Never do this!

:class="[$store.state.bodyColor, { 'nav-is-open': $store.state.menu }]">

@bensmeets
Copy link

Tnx @sqal, I tried that, but the behaviour is the same. It doesn't update in the class, but it does in the span.

@bensmeets
Copy link

@sqal Doh... found out what it was. It was an issue with Safari not updating the dev-tools. In Chrome it does, and there everything it works fine. It seems either Safari or the combination of Vue's Dom with Safari makes it not showing the actual DOM in the inspector.

@mityukov
Copy link

In this example, you could make a computed property returning array, instead. Like this:

computedClass() {
  let res = this.$store.state.bodyColor

  if (this.$store.state.menu) {
    res.push('nav-is-open')
  }

  return res
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants