【问题标题】:Vue dynamically binding to class does not workVue动态绑定到类不起作用
【发布时间】:2021-02-17 02:39:37
【问题描述】:

我在 Vue 组件中有一些复制手风琴的代码,我希望在当前项目处于活动状态时下拉箭头旋转 90 度。但是,无论我尝试什么,都没有任何效果。

<template>
  <div
    class="short-term__table"
    v-for="(credit, index) in credits"
    :key="index"
  >
    <div class="row ribbon">
      
      <div class="col" @click="showDetails(index)">
        <i
          class="caret-right fas fa-caret-right"
          :class="credit.active ? 'active' : ''"
        >
        </i>
      </div>
    </div>
    <CreditDetails v-if="credits[index].active" />
  </div>
</template>

<script>
import CreditDetails from "./credit-item-details.component";
export default {
  components: {
    CreditDetails,
  },
  data() {
    return {
      credits: [
        {

          active: false,
        },
        {
          active: false,
        },
        {
          active: true,
        },
      ],
    };
  },
  methods: {
    showDetails(index) {
      this.credits[index].active = !this.credits[index].active;
    },
  },
};
</script>

<style scoped lang="scss">

  .active {
    transform: rotate(90deg);
  }

</style>

这在创建组件时有效,但是当数据更改时类不会更新?

所以问题: 为什么 credit.active 不更新类绑定。

【问题讨论】:

  • 可能你的问题出在 CSS 而不是 Vue。尝试将 ʻactive` 类附加到元素上进行测试。

标签: css vue.js vuejs3


【解决方案1】:

您正在通过索引更改数组项,这将不起作用。当您通过索引改变数组项时,Vue 无法检测到它并且模板不会重新渲染。 VueJS docs.中提到了这一点

你可以像这样更新数组项:

showDetails(index) {
  this.$set(this.credits, index, {
    ...this.credits[index],
    active: !this.credits[index].active
  })
},

或者像这样:

showDetails(index) {
  this.credits.splice(index, 1, {     
    ...this.credits[index], active: !this.credits[index].active   
  })
}

请深入阅读 VueJS 文档以了解反应性。

【讨论】:

  • 我正在使用 vue 3 并且它抛出 this.$set 不是一个函数?
  • 那你可以试试这个:this.credits.splice(index, 1, { ...this.credits[index], active: !this.credits[index].active })我也更新了答案
  • 谢谢你的回答,但这对我仍然不起作用:(
【解决方案2】:

在下面的例子中可以正常工作:

const {
  createApp,
  computed,
  onMounted,
  watch
} = Vue;



const app = createApp({
  data() {
    return {
      credits: [{
          title: "title 1",
          active: false,
        },
        {
          title: "title 2",
          active: false,
        },
        {
          title: "title 3",
          active: true,
        },
      ],
    };
  },
  methods: {
    showDetails(index) {
      this.credits[index].active = !this.credits[index].active;
    },
  },
});


app.mount('#app');
.active {
  transform: rotate(90deg);
}

.col {
  display: flex;
  align-items: center;
}
<script src="https://unpkg.com/vue@3.0.0-rc.11/dist/vue.global.prod.js"></script>

<div id="app">
  <div class="short-term__table" v-for="(credit, index) in credits" :key="index">
    <div class="row ribbon">

      <div class="col" @click="showDetails(index)">
        <h3>{{credit.title}}</h3>
        <i class="caret-right fas fa-caret-right" :class="credit.active ? 'active' : ''">
        >
        </i>

      </div>
    </div>
  </div>
</div>

但我建议将图标名称绑定到活动字段:

<i :class="`caret-${credit.active?'down':'right'} fas fa-caret-${credit.active?'down':'right'}`" >

【讨论】:

  • 不客气,你能分享一些运行代码来调试它吗?
【解决方案3】:

为了触发 vue 重新渲染,您必须使用 vuejs 中的 this.$set 方法。

将您的methods-block 更改为以下内容:

methods: {
   showDetails(index) {
     this.$set(this.credits[index], 'active', !this.credits[index].active);
   }
 }

【讨论】:

  • 我正在使用 vue 3,这样做会抛出 this.$set 不是函数
猜你喜欢
  • 2019-09-17
  • 1970-01-01
  • 2018-07-13
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-09
  • 1970-01-01
相关资源
最近更新 更多