单击Vue.js切换类


77

如何在vue.js中切换类?

我有以下内容:

<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
    }
  }
});

当我单击时,th我想按以下方式申请active课程:

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

这需要切换,即每次单击它都需要添加/删除类。

Answers:


76

您可以使活动类依赖于布尔数据值:

<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
    }
  }
})

34
由于某种原因,v-class="active: isActive"我的应用程序崩溃了,但v-bind:class="{ active: isActive }" 对我有用。希望这对某人有帮助。
弗雷泽·柯克曼

6
vue似乎总是在改变语法。在2. *中,您也可以:class="..."
rzb

6
我正在vue.js-2中执行此操作。当我单击一行时,active该类将应用于所有行。难道我做错了什么?
Syed

1
您可以使每一行成为负责其isActive财产的自己的组件
Douglas.Sesar

2
设置Active类的所有示例仅适用于一个项目,如果我渲染了多个v-for,我将如何在此列表中最近单击的菜单上赋予Active类呢? <a href="#" @click="switchRoom(room)" class="rooms" :class="{currentRoom: room.isActive}" v-for="(room, index) in allRooms" :key="index">{{ room.name }} </a>
Akin Hwan

76

不需要方法:

// 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
}

2
@ConnorLeech<li v-for="(item, index) in items" :key="item.id" v-bind:class="{ active: active == item }" @click="active = item">然后添加.active {styles}并放入<ul>
nbixler

什么是活跃的?showMobileMenu是变量,但类是什么?
rjurney

34

如果您不需要从元素外部访问切换,则此代码无需数据变量即可工作:

<a @click="e => e.target.classList.toggle('active')"></a>

1
想要这个。简单和一般。
罗恩

1
我是Vue的新手,但是此解决方案遇到了问题。当我在vue-bootstrap卡父元素上添加@ click =“ e => e.target.classList.toggle('active')”时,会发生整个卡没有CSS切换的情况,而该类适用于您只需点击部分卡片,即可在一张卡片中切换多个卡片。
凯夫兹

1
@Kevz确实是此方法的局限性-它仅切换事件目标,即您单击的嵌套最多的<a>或<button>。对于您的问题,我将改用此页面上的一种数据变量解决方案。
Fabian von Ellerts

23

此答案与 Vue.js version 2

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

Douglas的其余答案仍然适用(使用设置新的Vue实例isActive: false,等等)。

相关文档:https : //vuejs.org/v2/guide/class-and-style.html#Object-Syntaxhttps://vuejs.org/v2/guide/events.html#Method-Event-Handlers


当我单击一行时,active该类将应用于所有行。难道我做错了什么?
Syed

同样的问题,这仅在组件中只有一个可单击元素的情况下有效。如果组件具有多个可单击的元素怎么办?
Kokodoko

如果您提出一个新问题,我可以调查一下。谢谢
NateW

15

此示例使用列表:在某些位置单击时,它变为红色

的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;
}

小提琴:

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


7

除了NateW的答案外,如果CSS类名称中带有连字符,则应将该类包装在(单引号)内:

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

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

有关主题的更多信息,请参见主题。


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"

参考链接:https : //vuejs.org/v2/guide/class-and-style.html

演示:

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>


3

如果您需要超过一堂课

你可以这样做:

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

data: {
  showStar: true
}

注意类周围的单引号!

感谢其他所有人的解决方案。


1

我有一个解决方案,允许您检查道具的不同值,因此不同的<th>元素将变为活动/非活动状态。使用vue 2语法。

<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
    }
  }
})

0

对于nuxt链接和bootstrap v5 navbar-nav,我使用了子组件

             <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
    }
  },

-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>


-1

尝试:

<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>    

1
除了代码段之外,请添加简短说明,以说明这可以解决此问题的原因。
亚历山大·范·奥斯滕里克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.