10

Just started with Vue so I can't get this simple thing working. All I'm trying to do is toggle a class based on a condition.

<button type="button" 
        class="btn dropdown-toggle" 
        v-bind:class="{ btn-default: (search.category != 'all') }">
    {{ filterCategoryText || 'Category' }}
</button>

4 Answers 4

22

Firstly, as you discovered, you should probably remove the duplicate class definition. You can mix static and dynamic classes in the bound class definition. (If you leave the duplicate there it still works, though)

Then, you have the choice...

Object syntax

// property names will be in the class list if their values are truthy
:class="{ 
    'btn-default': search.category != "all", 
    'btn' : true, 
    'dropdown-toggle' : true 
}"

Array syntax

// an item in the array becomes a class in the class list
:class="[
    search.category != 'all' ? 'btn-default':'',
    'btn',
    'dropdown-toggle'
]"

Simple expression

// if you only have one item, just use a simple expression
:class="search.category != 'all' ? 'btn-default':''"

Docs are here

Sign up to request clarification or add additional context in comments.

5 Comments

Right. That's exactly what I've written
Yep sorry. Daily standup then I saw your post after I posted.
Why is that bad to have this class definition 'duplication'? I stumbled upon such pattern in many sources and to me it seems like a good way to separate static data from dynamic. I don't have any information in terms of performance, but it seems redundant to keep static classes in the binding.
@oniondomes Well if you keep everything in one place you're less likely to lose things. But it's more the fact that the merging that we see is, far as I know, undocumented, and so might change. I still have missing clumps of hair from duplicate xsl attributes, specified once inline, then again in an xsl:attribute tag.
This indeed helps keeping things together. On the other hand It can enlarge the hay you need to find the error in, once one occurs. But I could be totally wrong practicing this separation.
2

You still could have used Object syntax for the class binding. I guess the code in you example didn't work because you didn't wrap object property name with quotes. Moreover, you have at least three options here. In such case I would always stick with objects if possible as it's usually more readable. Take a look:

new Vue({
  el: '#app',
  data: {
    red: 'nope',
  },
  methods: {
    toggle() {
      this.red = this.red === 'yes' ? 'nope' : 'yes';
    }
  },
})
.is-bold {
  font-weight: 900;
}

.is-red {
  color: red;
}
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p class="is-bold" :class="{'is-red': red === 'yes'}">
    Option
  </p>
  <p class="is-bold" :class="red === 'yes' ? 'is-red' : ''">
    Option 1
  </p>
  <p class="is-bold" :class="[red === 'yes' ? 'is-red' : '']">
    Option 2
  </p>
  <button @click="toggle">Toggle class</button>
</div>

jsfiddle: https://jsfiddle.net/oniondomes/06bg516h/

Comments

1

Figured it:

<button type="button" 
        :class="[(search.category) ? '' : 'btn-default', 'btn dropdown-toggle']"
    {{ filterCategoryText || 'Category' }}
</button>

Comments

0

try this instead of v-bind:class="{ 'btn-default': search.category != 'all' }"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.