【问题标题】:VueJs set active class, when one li element clicked in v-for loopVueJs设置活动类,当在v-for循环中单击一个li元素时
【发布时间】:2023-03-24 21:43:02
【问题描述】:

当我执行 v-for 循环并且已经选择了一个类时,我无法弄清楚如何正确选择(设置活动类)。让我分享代码并进一步解释

这些是我的可用订阅,并且已根据用户数据选择了一个

<ul>
    <li v-for="(s, key, index) in subscriptions"
        :class="checkIfClassActive(s.subscription_key)"
        @click="setActive(key, index)">
        {{ s.name }}
    </li>
</ul>

还有我的js代码

checkIfClassActive(userSubscriptionKey) {
    if (userSubscriptionKey === this.userSubscription.subscription_key) {
        return 'active';
    }
},
setActive(key, index) {

},

这就是显示的方式

现在下一步是当我单击一个 li 元素时,它应该变为活动状态,所有其他 li 元素都应该失去活动类,但问题是我不知道如何正确编写 setActive 函数。你能帮帮我吗,怎么做。

如果您需要任何其他信息,请告诉我,我会提供。谢谢!

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    添加名为activeIndexdata 属性:

      data() {
        return {
          activeIndex: undefined
        }
      },
    

    还有你的setActive 方法:

      methods: {
        setActive(subscription, index) { 
          this.activeIndex = index;
          this.userSubscription.subscription_key = subscription.subscription_key
    },
        getSubscriptions() {
           .....
           // fetch subscriptions in this.subscriptions var
           .....
           // select preselected subscription, when fetching subscriptions 
           let userSubscriptionKey = this.userSubscription.subscription_key;
           let indexOfObject = this.subscriptions.findIndex(
                o => o.subscription_key === userSubscriptionKey
           );
           this.setActive(this.userSubscription, indexOfObject);
    
        }
      }
    

    对您的模板稍作修改:

    <ul>
        <li v-for="(s, index) in subscriptions"
            :class="{ 'active': activeIndex === index }" :key="s.id"
            @click="setActive(s, index)">
            {{ s.name }}
        </li>
    </ul>
    

    您基本上设置了一个应该处于活动状态的索引,就是这样。当列表元素的索引与activeIndex相同时添加activecss类。

    至于在用户更改之前将activeIndex设置为现有选项,您可以在获取订阅数据时将activeIndex设置为用户当前订阅。

    小提琴:http://jsfiddle.net/eywraw8t/256701/

    【讨论】:

    • OP 也有用户定义的值被预选。
    • 我已经更新了一个代码来选择预先选择的值
    • 对于任何使用嵌套循环的人:"{ 'active': activeIndex === index_levelone * 10 + index_leveltwo }"
    【解决方案2】:

    每次选择选项卡时更改您的this.userSubscription.subscription_key 变量。为此,请通过setActive(s.subscription_key) 你可以这样做,

    <li v-for="(s, key, index) in subscriptions"
            :class="checkIfClassActive(s.subscription_key)"
            @click="setActive(s.subscription_key)">
            {{ s.name }}
    </li>
    

    Js

    checkIfClassActive(userSubscriptionKey) {
        if (userSubscriptionKey === this.userSubscription.subscription_key) {
            return 'active';
        }
    },
    setActive(subscription_key) {
        this.userSubscription.subscription_key=subscription_key;
    },
    

    【讨论】:

      【解决方案3】:

      这很快

      如果你使用 v-for:

                  <template>
                      <div>
                          <ul>
                              <li 
                              class="anyThings"
                              v-for="cat in cats"
                              :key="cat.index"
                              @click="itemActive(cat.index)"
                              :class="[(itemA == cat.index) ? 'active':'']"
                              >{{ cat.yourObjectKey }}
                              </li>
                          </ul>
                      </div>
                  </template>
      
                  <script>
                      export default {
                          data() {
                              return {
                                  itemA:'0' // for first load and in curent path
                              }
                          },
                          computed: {
                              cats() {
                                  ...
                              }
                          },
                          methods: {
                              itemActive(e) {
                                  this.itemA = e;
                              }
                          },
      
                      }
                  </script>
      
                  <style>
                      .active {
                          ...
                      }
                  </style>
      

      如果你不需要使用 v-for 并在元素中使用 router-link:

                  <template>
                      <div>
                          <ul>
                              <li @click="itemActive($route.path)">
                                  <router-link to="/" class="anyThings" 
                                  :class="[(itemA == '/') ? 'active':'']"
                                  >your text
                                  </router-link>  
                              </li>
                              <li @click="itemActive($route.path)">
                                  <router-link to="/article" class="anyThings" 
                                  :class="[(itemA == '/article') ? 'active':'']"
                                  >your text
                                  </router-link>  
                              </li>
                               .
                               .
                               .
                          </ul>
                      </div>
                  </template>
      
                  <script>
                      export default {
                          data() {
                              return {
                                  itemA:this.$route.path // for first load and in curent path
                              }
                          },
                          methods: {
                              itemActive(e) {
                                  this.itemA = e;
                              }
                          },
      
                      }
                  </script>
      
                  <style>
                      .active {
                          ...
                      }
                  </style>
      

      【讨论】:

        【解决方案4】:

        显示逻辑的简单示例:

        html部分:

        <div id="app">
          <ul>
            <li 
            v-for="item in items"
            :key="item.id"
            :class="item.class"
            @click="set_active_id(item.id)"
            >{{ item.text }}</li>
          </ul>
        </div>
        

        js部分:

        new Vue({
          el: "#app",
          data: {
            items: [
              { id: 1, text: 'text1', class: 'active' }, //default active
              { id: 2, text: 'text2', class: '' },
              { id: 3, text: 'text3', class: '' }
            ],
            previous_active_id: 1
          },
          methods: {
            set_active_id(id) {
              if (this.previous_active_id === id) return //no need to go further
              this.items.find(item => item.id === this.previous_active_id).class = '' //remove the active class from old active li
              this.items.find(item => item.id === id).class = 'active' //set active class to new li
              this.previous_active_id = id //store the new active li id
            }
          }
        })
        

        See it in action

        【讨论】:

          猜你喜欢
          • 2021-02-15
          • 2021-02-16
          • 1970-01-01
          • 2019-05-09
          • 2018-03-20
          • 1970-01-01
          • 2018-02-01
          • 2022-06-25
          • 1970-01-01
          相关资源
          最近更新 更多