Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何在Vue中动态添加类名 #188

Open
husky-dot opened this issue Feb 7, 2020 · 0 comments
Open

如何在Vue中动态添加类名 #188

husky-dot opened this issue Feb 7, 2020 · 0 comments

Comments

@husky-dot
Copy link
Owner

husky-dot commented Feb 7, 2020

作者:Michael Thiessen
译者:前端小智
来源:forum.vuejs.org/

能够向组件添加动态类名是非常强大的功能。它使我们可以更轻松地编写自定义主题,根据组件的状态添加类,还可以编写依赖于样式的组件的不同变体。

添加动态类名与在组件中添加 prop :class="classname"一样简单。无论classname的计算结果是什么,都将是添加到组件中的类名。

当然,对于Vue中的动态类,我们可以做的还有很多。在本文中,我们将讨论很多内容:

  • 在 Vue 中使用静态和动态类
  • 如何使用常规的 JS 表达式来计算我们的类
  • 动态类名的数组语法
  • 对象语法
  • 快速生成类名
  • 如何在自定义组件上使用动态类名

静态和动态类

在Vue中,我们可以向组件添加静态类和动态类。

静态类是那些永远不会改变的乏味类,它们将始终出现在组件中。另一方面,我们可以在应用程序中添加和删除动态类。

添加静态类与在常规HTML中所做的是完全相同的

<template>
  <span class="description">
    This is how you add static classes in Vue.
  </span>
</template>

动态类非常类似,但是我们必须使用Vue的特殊属性语法v-bind,以便将 JS 表达式绑定到我们的类:

<template>
  <span v-bind:class="'description'">
    This is how you add static classes in Vue.
  </span>
</template>

这里你会注意到,我们必须在动态类名周围添加额外的引号。

这是因为v-bind语法接受我们作为 JS 值传递的任何内容。添加引号可以确保Vue将其视为字符串。

Vue还有一个v-bind的简写语法:

<template>
  <span :class="'description'">
    This is how you add static classes in Vue.
  </span>
</template>

真正奇妙的是,您甚至可以在同一个组件上同时拥有静态类和动态类。静态类用于我们知道不会更改的内容,比如定位和布局,动态类用于主题之类的:

<template>
  <span
    class="description"
    :class="theme"
  >
    This is how you add static classes in Vue.
  </span>
</template>

export default {
  data() {
    return {
      theme: 'blue-theme',
    };
  }
};
----------------------------------------
.blue-theme {
  color: navy;
  background: white;
}

在本例中,theme是包含我们将应用的类名的变量。

有条件的类名

由于v-bind可以接受任何 JS 表达式,因此我们可以用它做一些非常酷的事情。我最喜欢的是在模板中使用三元表达式,它往往是非常干净和可读的。

<template>
  <span
    class="description"
    :class="darkMode ? 'dark-theme' : 'light-theme'"
  >
    This is how you add dynamic classes in Vue.
  </span>
</template>

如果darkModetrue,则将dark-theme用作我们的类名。 否则,我们选择light-theme

使用数组语法

如果需要动态添加许多不同的类,可以使用数组或对象。这两种方法都很有用,我们先来看数组方式。

因为我们只是在计算一个 JS 表达式,所以可以将我们刚刚学到的表达式与数组语法结合起来

<template>
  <span
    class="description"
    :class="[
      fontTheme,
      darkMode ? 'dark-theme' : 'light-theme',
    ]"
  >
    This is how you add dynamic classes in Vue.
  </span>
</template>

我们使用数组在这个元素上设置两个动态类名。fontTheme的值是一个类名,它将改变字体的外观。在前面的例子中,我们仍然可以使用darkMode变量在dark-themelight-theme之间切换。

使用对象语法

我们甚至可以使用对象来定义动态类的列表,这给了我们更多的灵活性。

对于任何值为真的键/值对,它将把键用作类名。让我们看一个对象语法的例子:

<template>
  <span
    class="description"
    :class="{
      'dark-theme': darkMode,
      'light-theme': !darkMode,
    ]"
  >
    This is how you add dynamic classes in Vue.
  </span>
</template>

我们的对象包含两个键:dark-themelight-theme。与我们之前实现的逻辑类似,我们希望基于darkMode的值在这些主题之间切换。

darkModetrue 时,会把dark-theme作为一个动态类名应用于我们的元素。但是light-them不会被应用,因为!darkMode 值为false

现在我们已经介绍了向Vue组件动态添加类的基础知识。那么如何使用自己的自定义组件来做到这一点?

与自定义组件一起使用

假设我们在 app 中有一个自定义组件

<template>
  <MovieList
    :movies="movies"
    :genre="genre"
  />
</template>

如果我们要动态添加一个将更改主题的类,我们该怎么办?其实很简单。

我们只需要像以前那样添加:class属性

<template>
  <MovieList
    :movies="movies"
    :genre="genre"
    :class="darkMode ? 'dark-theme' : 'light-theme'"
  />
</template>

之所以起作用,是因为Vue直接在MovieList的根元素上设置类。

在组件上设置props时,Vue会将这些props与组件在其props部分中指定的props进行比较。 如果有匹配项,它将作为常规props传递。 否则,Vue会将其添加到根DOM元素中。

在这里,由于MovieList没有指定class属性,因此Vue知道应该在根元素上进行设置。

不过,我们可以用动态类名做一些更高级的事情。

快速生成类名

我们已经介绍了许多动态添加或删除类名的不同方法。但是动态生成类名本身又如何呢?

假设有一个Button组件,它为所有不同类型的按钮提供20种不同的CSS样式。

你可能不想花一整天的时间把每一项都写出来,也不想把开关的逻辑都写出来。相反,我们将动态生成要应用的类的名称。

<template>
  <span
    class="description"
    :class="theme"
  >
    This is how you add static classes in Vue.
  </span>
</template>


export default {
  data() {
    return {
      theme: 'blue-theme',
    };
  }
};

.blue-theme {
  color: navy;
  background: white;
}

我们可以设置一个变量来包含我们想要的任何类名的字符串。如果我们想对Button组件执行此操作,则可以执行以下简单操作:

<template>
  <button
    @click="$emit('click')"
    class="button"
    :class="theme"
  >
    {{ text }}
  </button>
</template>

export default {
  props: {
    theme: {
      type: String,
      default: 'default',
    }
  }
};

.default {}

.primary {}

.danger {}

现在,使用Button组件的任何人都可以将theme属性设置为他们想要使用的任何主题。

如果没有设置任何类,它将添加.default类。如果将其设置为primary,则会添加.primary类。

使用计算属性来简化类

最终,模板中的表达式将变得过于复杂,并将开始变得非常混乱和难以理解。幸运的是,我们有一个简单的解决方案,就是使用计算民属性:

<template>
  <MovieList
    :movies="movies"
    :genre="genre"
    :class="class"
  />
</template>

export default {
  computed: {
    class() {
      return darkMode ? 'dark-theme' : 'light-theme';
    }
  }
};

这不仅易于阅读,而且还可以轻松添加新功能并在将来进行重构。


代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

原文:https://forum.vuejs.org/t/add-a-dynamically-generated-class-name-to-components-class-attribute-from-mixin/27626


交流

干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。

https://github.com/qq449245884/xiaozhi

我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,即可看到福利,你懂的。

clipboard.png

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant