Vue.js Klasse beim Klicken umschalten

74

Wie kann eine Klasse in vue.js umgeschaltet werden?

Ich habe folgendes:

<th class="initial " v-on="click: myFilter">
    <span class="wkday">M</span>
</th>

new Vue({
  el: '#my-container',
  data: {},
  methods: {
    myFilter: function(){
      // some code to filter users
    }
  }
});

Wenn ich auf klicke, thmöchte ich mich activewie folgt als Klasse bewerben :

<th class="initial active" v-on="click: myFilter">
    <span class="wkday">M</span>
</th>      

Dies muss umgeschaltet werden, dh jedes Mal, wenn darauf geklickt wird, muss die Klasse hinzugefügt / entfernt werden.

adam78
quelle

Antworten:

73

Die aktive Klasse könnte von einem booleschen Datenwert abhängig sein:

<th 
  class="initial " 
  v-on="click: myFilter"
  v-class="{active: isActive}">
  <span class="wkday">M</span>
</th>

new Vue({
  el: '#my-container',

  data: {
    isActive: false
  },

  methods: {
    myFilter: function() {
      this.isActive = !this.isActive;
      // some code to filter users
    }
  }
})
Douglas.Sesar
quelle
34
Aus irgendeinem Grund v-class="active: isActive"stürzt meine App ab, v-bind:class="{ active: isActive }" funktioniert aber für mich. Hoffe das ist hilfreich für jemanden.
Frazer Kirkman
4
Die Syntax scheint sich mit vue ständig zu ändern. In 2. * können Sie auch einfach tun:class="..."
rzb
5
Ich mache es in vue.js-2. Wenn ich auf eine Zeile klicke, wird die activeKlasse auf alle Zeilen angewendet. Mache ich etwas falsch?
Syed
1
Sie können jede Zeile zu einer eigenen Komponente machen, die für ihre eigene isActiveEigenschaft verantwortlich ist
Douglas.Sesar
2
Alle Beispiele zum Festlegen einer aktiven Klasse beziehen sich nur auf ein Element. Wenn ich mehrere I v-for gerendert hätte, wie würde ich dann der zuletzt angeklickten dieser Liste eine aktive Klasse zuweisen. <a href="#" @click="switchRoom(room)" class="rooms" :class="{currentRoom: room.isActive}" v-for="(room, index) in allRooms" :key="index">{{ room.name }} </a>
Akin Hwan
74

Ohne die Notwendigkeit einer Methode:

// html element
<div id="mobile-toggle"
 v-bind:class="{ active: showMobileMenu }"
 v-on:click="showMobileMenu = !showMobileMenu">
</div>

//in your vue.js app
data: {
    showMobileMenu: false
}
Moabi
quelle
2
@ConnorLeech <li v-for="(item, index) in items" :key="item.id" v-bind:class="{ active: active == item }" @click="active = item">Dann füge .active {styles}es hinzu und lege es in<ul>
nbixler
Und was ist aktiv? showMobileMenuist eine Variable, aber was ist die Klasse?
rjurney
29

Wenn Sie nicht von außerhalb des Elements auf den Umschalter zugreifen müssen, funktioniert dieser Code ohne Datenvariable:

<a @click="e => e.target.classList.toggle('active')"></a>
Fabian von Ellerts
quelle
Wollte das. Einfach und allgemein.
Ron16
23

Diese Antwort ist relevant für Vue.js version 2

<th 
  class="initial " 
  v-on:click="myFilter"
  v-bind:class="{ active: isActive }"
>
  <span class="wkday">M</span>
</th>

Der Rest der Antwort von Douglas gilt weiterhin (Einrichten der neuen Vue-Instanz mit isActive: falseusw.).

Relevante Dokumente: https://vuejs.org/v2/guide/class-and-style.html#Object-Syntax und https://vuejs.org/v2/guide/events.html#Method-Event-Handlers

NateW
quelle
Wenn ich auf eine Zeile klicke, wird die activeKlasse auf alle Zeilen angewendet. Mache ich etwas falsch?
Syed
Das gleiche Problem hier, dies funktioniert nur, wenn es nur ein anklickbares Element in der Komponente gibt. Was ist, wenn eine Komponente mehrere anklickbare Elemente enthält?
Kokodoko
Wenn Sie eine neue Frage stellen, kann ich sie prüfen. Danke
NateW
14

In diesem Beispiel werden Listen verwendet: Wenn Sie auf ein Li klicken, wird es rot

html:

<div id="app">
  <ul>
    <li @click="activate(li.id)" :class="{ active : active_el == li.id }" v-for="li in lista">{{li.texto}}</li>   
  </ul>
</div>

JS:

var app = new Vue({
  el:"#app",
  data:{
    lista:[{"id":"1","texto":"line 1"},{"id":"2","texto":"line 2"},{"id":"3","texto":"line 3"},{"id":"4","texto":"line 4"},{"id":"5","texto":"line 5"}],
    active_el:0
  },
  methods:{
    activate:function(el){
        this.active_el = el;
    }
  }
});

CSS

ul > li:hover {
  cursor:pointer;
}
.active {
  color:red;
  font-weight:bold;
}

Geige:

https://jsfiddle.net/w37vLL68/158/

ClaudioC
quelle
7

Wenn Sie zusätzlich zur Antwort von NateW Bindestriche in Ihrem CSS-Klassennamen haben, sollten Sie diese Klasse in (einfache) Anführungszeichen setzen:

<th 
  class="initial " 
  v-on:click="myFilter"
  v-bind:class="{ 'is-active' : isActive}"
>

 <span class="wkday">M</span>
 </th>

Weitere Informationen zu diesem Thema finden Sie in diesem Thema.

hbulens
quelle
5

1.

@click="$event.target.classList.toggle('active')"

2.

:class="{ active }"
@click="active = !active"

3.

:class="'initial ' + (active ? 'active' : '')"  
@click="active = !active"

4.

:class="['initial', { active }]"  
@click="active = !active"

Referenzlink: https://vuejs.org/v2/guide/class-and-style.html

Demo:

new Vue({
  el: '#app1'
});

new Vue({
  el: '#app2',
  data: { active: false }
});

new Vue({
  el: '#app3',
  data: { active: false }
});

new Vue({
  el: '#app4',
  data: { active: false }
});
.initial {
  width: 300px;
  height: 100px;
  background: gray;
}

.active {
  background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<!-- directly manipulation: not recommended -->
<div id="app1">
    <button 
      class="initial"  
      @click="$event.target.classList.toggle('active')"
    >$event.target.classList.toggle('active')</button>
</div>

<!-- binding by object -->
<div id="app2">
    <button 
      class="initial"  
      :class="{ active }"
      @click="active = !active"
    >class="initial" :class="{ active }"</button>
</div>

<!-- binding by expression -->
<div id="app3">
    <button 
      :class="'initial ' + (active ? 'active' : '')"  
      @click="active = !active"
    >'initial ' + (active ? 'active' : '')</button>
</div>

<!-- binding with object combined array -->
<div id="app4">
    <button 
      :class="['initial', { active }]"  
      @click="active = !active"
    >['initial', { active }]</button>
</div>

Loi Nguyen Huynh
quelle
3

Wenn Sie mehr als 1 Klasse benötigen

Du kannst das:

<i id="icon" 
  v-bind:class="{ 'fa fa-star': showStar }"
  v-on:click="showStar = !showStar"
  >
</i> 

data: {
  showStar: true
}

Beachten Sie die einfachen Anführungszeichen um die Klassen!

Vielen Dank an alle anderen Lösungen.

Ben Winding
quelle
1

Ich habe eine Lösung, mit der Sie nach verschiedenen Werten einer Requisite suchen können und somit verschiedene <th>Elemente aktiv / inaktiv werden. Verwenden der Vue 2-Syntax.

<th 
class="initial " 
@click.stop.prevent="myFilter('M')"
:class="[(activeDay == 'M' ? 'active' : '')]">
<span class="wkday">M</span>
</th>
...
<th 
class="initial " 
@click.stop.prevent="myFilter('T')"
:class="[(activeDay == 'T' ? 'active' : '')]">
<span class="wkday">T</span>
</th>



new Vue({
  el: '#my-container',

  data: {
      activeDay: 'M'
  },

  methods: {
    myFilter: function(day){
        this.activeDay = day;
      // some code to filter users
    }
  }
})
bgreater
quelle
0

Für nuxt link und bootstrap v5 navbar-nav habe ich eine untergeordnete Komponente verwendet

             <nuxt-link
              @click.prevent.native="isDropdwonMenuVisible = !isDropdwonMenuVisible"
              to=""
              :title="item.title"
              :class="[item.cssClasses, {show: isDropdwonMenuVisible}]"
              :id="`navbarDropdownMenuLink-${index}`"
              :aria-expanded="[isDropdwonMenuVisible ? true : false]"
              class="nav-link dropdown-toggle"
              aria-current="page"
              role="button"
              data-toggle="dropdown"
            >
              {{ item.label }}
            </nuxt-link>

data() {
    return {
      isDropdwonMenuVisible: false
    }
  },
Arlan T.
quelle
-1

new Vue({
  el: '#fsbar',
  data:{
    isActive: false
  },
  methods: {
    toggle: function(){
      this.isActive = !this.isActive;
    }
  }
});
/*
    DEMO STYLE
*/
@import "https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700";


body {
    font-family: 'Poppins', sans-serif;
    background: #fafafa;
}

p {
    font-family: 'Poppins', sans-serif;
    font-size: 1.1em;
    font-weight: 300;
    line-height: 1.7em;
    color: #999;
}

a, a:hover, a:focus {
    color: inherit;
    text-decoration: none;
    transition: all 0.3s;
}

.navbar {
    padding: 15px 10px;
    background: #fff;
    border: none;
    border-radius: 0;
    margin-bottom: 40px;
    box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
}

.navbar-btn {
    box-shadow: none;
    outline: none !important;
    border: none;
}

.line {
    width: 100%;
    height: 1px;
    border-bottom: 1px dashed #ddd;
    margin: 40px 0;
}

i, span {
    display: inline-block;
}

/* ---------------------------------------------------
    SIDEBAR STYLE
----------------------------------------------------- */
.wrapper {
    display: flex;
    align-items: stretch;
}

#sidebar {
    min-width: 250px;
    max-width: 250px;
    background: #7386D5;
    color: #fff;
    transition: all 0.3s;
}

#sidebar.active {
    min-width: 80px;
    max-width: 80px;
    text-align: center;
}

#sidebar.active .sidebar-header h3, #sidebar.active .CTAs {
    display: none;
}

#sidebar.active .sidebar-header strong {
    display: block;
}

#sidebar ul li a {
    text-align: left;
}

#sidebar.active ul li a {
    padding: 20px 10px;
    text-align: center;
    font-size: 0.85em;
}

#sidebar.active ul li a i {
    margin-right:  0;
    display: block;
    font-size: 1.8em;
    margin-bottom: 5px;
}

#sidebar.active ul ul a {
    padding: 10px !important;
}

#sidebar.active a[aria-expanded="false"]::before, #sidebar.active a[aria-expanded="true"]::before {
    top: auto;
    bottom: 5px;
    right: 50%;
    -webkit-transform: translateX(50%);
    -ms-transform: translateX(50%);
    transform: translateX(50%);
}

#sidebar .sidebar-header {
    padding: 20px;
    background: #6d7fcc;
}

#sidebar .sidebar-header strong {
    display: none;
    font-size: 1.8em;
}

#sidebar ul.components {
    padding: 20px 0;
    border-bottom: 1px solid #47748b;
}

#sidebar ul li a {
    padding: 10px;
    font-size: 1.1em;
    display: block;
}
#sidebar ul li a:hover {
    color: #7386D5;
    background: #fff;
}
#sidebar ul li a i {
    margin-right: 10px;
}

#sidebar ul li.active > a, a[aria-expanded="true"] {
    color: #fff;
    background: #6d7fcc;
}


a[data-toggle="collapse"] {
    position: relative;
}

a[aria-expanded="false"]::before, a[aria-expanded="true"]::before {
    content: '\e259';
    display: block;
    position: absolute;
    right: 20px;
    font-family: 'Glyphicons Halflings';
    font-size: 0.6em;
}
a[aria-expanded="true"]::before {
    content: '\e260';
}


ul ul a {
    font-size: 0.9em !important;
    padding-left: 30px !important;
    background: #6d7fcc;
}

ul.CTAs {
    padding: 20px;
}

ul.CTAs a {
    text-align: center;
    font-size: 0.9em !important;
    display: block;
    border-radius: 5px;
    margin-bottom: 5px;
}

a.download {
    background: #fff;
    color: #7386D5;
}

a.article, a.article:hover {
    background: #6d7fcc !important;
    color: #fff !important;
}



/* ---------------------------------------------------
    CONTENT STYLE
----------------------------------------------------- */
#content {
    padding: 20px;
    min-height: 100vh;
    transition: all 0.3s;
}


/* ---------------------------------------------------
    MEDIAQUERIES
----------------------------------------------------- */
@media (max-width: 768px) {
    #sidebar {
        min-width: 80px;
        max-width: 80px;
        text-align: center;
        margin-left: -80px !important ;
    }
    a[aria-expanded="false"]::before, a[aria-expanded="true"]::before {
        top: auto;
        bottom: 5px;
        right: 50%;
        -webkit-transform: translateX(50%);
        -ms-transform: translateX(50%);
        transform: translateX(50%);
    }
    #sidebar.active {
        margin-left: 0 !important;
    }

    #sidebar .sidebar-header h3, #sidebar .CTAs {
        display: none;
    }

    #sidebar .sidebar-header strong {
        display: block;
    }

    #sidebar ul li a {
        padding: 20px 10px;
    }

    #sidebar ul li a span {
        font-size: 0.85em;
    }
    #sidebar ul li a i {
        margin-right:  0;
        display: block;
    }

    #sidebar ul ul a {
        padding: 10px !important;
    }

    #sidebar ul li a i {
        font-size: 1.3em;
    }
    #sidebar {
        margin-left: 0;
    }
    #sidebarCollapse span {
        display: none;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">

        <title>Collapsible sidebar using Bootstrap 3</title>

         <!-- Bootstrap CSS CDN -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <!-- Our Custom CSS -->
        <link rel="stylesheet" href="style4.css">
    </head>
    <body>



        <div class="wrapper" id="fsbar">
            <!-- Sidebar Holder -->
            <nav id="sidebar" :class="{ active: isActive }">
                <div class="sidebar-header">
                    <h3>Bootstrap Sidebar</h3>
                    <strong>BS</strong>
                </div>

                <ul class="list-unstyled components">
                    <li class="active">
                        <a href="#homeSubmenu" data-toggle="collapse" aria-expanded="false">
                            <i class="glyphicon glyphicon-home"></i>
                            Home
                        </a>
                        <ul class="collapse list-unstyled" id="homeSubmenu">
                            <li><a href="#">Home 1</a></li>
                            <li><a href="#">Home 2</a></li>
                            <li><a href="#">Home 3</a></li>
                        </ul>
                    </li>
                    <li>
                        <a href="#">
                            <i class="glyphicon glyphicon-briefcase"></i>
                            About
                        </a>
                        <a href="#pageSubmenu" data-toggle="collapse" aria-expanded="false">
                            <i class="glyphicon glyphicon-duplicate"></i>
                            Pages
                        </a>
                        <ul class="collapse list-unstyled" id="pageSubmenu">
                            <li><a href="#">Page 1</a></li>
                            <li><a href="#">Page 2</a></li>
                            <li><a href="#">Page 3</a></li>
                        </ul>
                    </li>
                    <li>
                        <a href="#">
                            <i class="glyphicon glyphicon-link"></i>
                            Portfolio
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <i class="glyphicon glyphicon-paperclip"></i>
                            FAQ
                       isActive: false, </a>
                    </li>
                    <li>
                        <a href="#">
                            <i class="glyphicon glyphicon-send"></i>
                            Contact
                        </a>
                    </li>
                </ul>

                <ul class="list-unstyled CTAs">
                    <li><a href="https://bootstrapious.com/tutorial/files/sidebar.zip" class="download">Download source</a></li>
                    <li><a href="https://bootstrapious.com/p/bootstrap-sidebar" class="article">Back to article</a></li>
                </ul>
            </nav>

            <!-- Page Content Holder -->
            <div id="content">

                <nav class="navbar navbar-default">
                    <div class="container-fluid">

                        <div class="navbar-header">
                            <button type="button" id="sidebarCollapse" class="btn btn-info navbar-btn" @click="toggle()">
                                <i class="glyphicon glyphicon-align-left"></i>
                                <span>Toggle Sidebar</span>
                            </button>
                        </div>

                        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                            <ul class="nav navbar-nav navbar-right">
                                <li><a href="#">Page</a></li>
                                <li><a href="#">Page</a></li>
                                <li><a href="#">Page</a></li>
                                <li><a href="#">Page</a></li>
                            </ul>
                        </div>
                    </div>
                </nav>

                <h2>Collapsible Sidebar Using Bootstrap 3</h2>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

                <div class="line"></div>

                <h2>Lorem Ipsum Dolor</h2>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

                <div class="line"></div>

                <h2>Lorem Ipsum Dolor</h2>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

                <div class="line"></div>

                <h3>Lorem Ipsum Dolor</h3>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
            </div>
        </div>





        <!-- jQuery CDN -->
         <script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
         <!-- Bootstrap Js CDN -->
         <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

        /<script type="text/javascript">
         //    $(document).ready(function () {
          //       $('#sidebarCollapse').on('click', function () {
           //          $('#sidebar').toggleClass('active');
            //     });
            // }); jquery equivalent to vue
         </script>
    </body>
</html>

SagitSri
quelle
-1

Versuchen :

<template>
   <th :class="'initial '+ active" v-on="click: myFilter">
       <span class="wkday">M</span>
   </th>  
</template>

<script lang="ts">

    active:string=''
    myFilter(){
       this.active='active'
    }
</script>

<style>
  .active{
     /***your action***/
   }

</style>    
Mostafa Ahmed
quelle
1
Fügen Sie neben einem Code-Snippet eine kurze Erklärung hinzu, warum dies das Problem löst.
Alexander van Oostenrijk