在VueJS中单击切换类

时间:2016-12-19 21:26:33

标签: javascript vuejs2

我正在学习Vuejs,我不断发现简单的事情,比如删除课程是一种痛苦。请告诉我如何根据3个链接之间的点击添加或删除.active类。

在下面的示例中,添加工作正常,但它会将.active添加到所有链接,并且在再次单击时不会删除。

<div id="app">
  <h2>App</h2>
  <ul>
    <li><a href="#" class="link" :class="{ active: isActive }" @click="activeLink">Link text</a></li>
    <li><a href="#" class="link" :class="{ active: isActive }" @click="activeLink">Link text</a></li>
    <li><a href="#" class="link" :class="{ active: isActive }" @click="activeLink">Link text</a></li>
  </ul>
</div>

JS

var app = new Vue({
  el: '#app',
  data: {
    isActive: false
},
methods: {
  activeLink() {
    // the line below did not work
    // document.getElementsByClassName("active").isActive = false,
    this.isActive = true
  }
 }
})

JSfiddle在这里,https://jsfiddle.net/s9r4q0gc/

4 个答案:

答案 0 :(得分:6)

你需要在方法中捕获事件处理程序并使用它来引用被调用者,即在这种情况下的锚对象。

请参阅小提琴:https://jsfiddle.net/s9r4q0gc/2/

var mystub = sinon.stub();
var myarg = { val: 1, mylist: [ {a:1}, {b:2}, {c:3,d:4} ] };

mystub(myarg);

sinon.assert.calledOnce(mystub).withArgs(
  sinon.match({val: 1, mylist: [{a:1},{b:2},{c:3,d:4}]}) // this doesn't work
);

<强>更新:

可以尝试这个小提琴,看看它是否会击中靶心:https://jsfiddle.net/s9r4q0gc/4/

activeLink(event) {
    if(event.target.className == "noclass")
    {
        event.target.className = "link active";
    }
    else
    {
        event.target.className = "noclass";
    }
  }

答案 1 :(得分:3)

您可以使用data属性来保存当前活动的链接。然后,如果它是活动链接并且应该应用.active类,那么您将能够进行任何给定的链接测试。

然后,只需在单击链接时设置该属性的新值即可。如果单击当前处于活动状态的相同链接,则清除该属性,从而从所有链接中删除.active类。否则,该类将添加到单击的链接中。

这是一个CodePen,展示了我的意思,但你的标记看起来像这样:

<li><a href="#" class="link" :class="{ active: activeId == 'link-1' }"
    @click.prevent="activeLink('link-1')">Link text</a></li>

<li><a href="#" class="link" :class="{ active: activeId == 'link-2' }"
    @click.prevent="activeLink('link-2')">Link text</a></li>

<li><a href="#" class="link" :class="{ active: activeId == 'link-3' }"
    @click.prevent="activeLink('link-3')">Link text</a></li>

你的JS看起来像这样:

data: {
  activeId: null
},
methods: {
  activeLink(linkIdent) {
    this.activeId = this.activeId === linkIdent ? null : linkIdent
  }
}

它显然不是一个尽可能干净的解决方案,但我坚持要求解决方案符合您提供的标记。

答案 2 :(得分:2)

使用V-for和一系列项目,因此您无需静态键入链接。这允许您正在寻找的动态功能。

  var app = new Vue({
    el: '#app',
    data: {
      links: [
       {text: "Link Text", active: false},
       {text: "Link Text", active: false},
       {text: "Link Text", active: false}
      ]
    },
    methods: {
      activate(link) {
        link.active = !link.active
      }
    }
  })
.link{
  text-decoration: none;
  color: #555;
}
.active{
  text-decoration: underline;
  color: #42b983;
}
<div id="app">
      <h2>App</h2>
      <ul>
        <li v-for="link in links"><a href="#" class="link" :class="{ active: link.active }" @click="activate(link)">Link text</a></li>
      </ul>
    </div>

答案 3 :(得分:1)

这是一个替代解决方案,可能会比您想要的更多地修改您的代码。我认为这可能是有用的,因为你只是在学习并可能对另一种选择感兴趣。我首先将您的链接声明为vue中的对象数组,以便我们可以为每个对象分配一个活动属性。然后我们可以直接切换活动值或使用toggleActive函数(当前没有使用..如果您更喜欢使用函数而不是内联逻辑,那么就在那里进行说明)。

HTML:

<div id="app">
  <h2>App</h2>
  <ul>
    <li v-for="l in links">
      <a href="#" class="link" :class="{ active: l.active}" @click="l.active = !l.active">{{l.text}}</a>
    </li>
  </ul>
</div>

使用Javascript:

var app = new Vue({
  el: '#app',
  data: {
    links: [{
      text: "Link text",
      active: false
    },{
      text: "Second text",
      active: false
    },{
      text: "Third text",
      active: false
    }]
  },
  methods: {
    //To use this function make @click in html to:
    //@click="toggleActive(l)"
    toggleActive(x) {
      x.active = !x.active;
    }
  }
})

https://jsfiddle.net/yrbt90v9/