【问题标题】:Is it possible to point to a class?是否可以指向一个类?
【发布时间】:2018-12-15 21:49:17
【问题描述】:

我有一个 Vue 应用程序(一个包含多个子组件的包罗万象的元素),我想向其中添加夜间模式。我希望集中管理这种夜间模式,将相关样式应用于需要切换到夜间/白天模式的元素。

如果我有一个元素(它在 DOM 中作为组件的一部分已被渲染,因此不能直接用于父组件,因此不能通过 v-bind 绑定)

<div class="night-day">hello</div>

还有两个类

.night {
  background-color: black;
  color: red
}

.day {
  background-color: white;
  color: black
}  

是否可以让night-day 指向day 或night(取决于某些条件)?

【问题讨论】:

  • 这种情况会怎样?以及为什么不简单地根据这种情况在两个类之间切换
  • @TemaniAfif:条件将是一个setInterval(),它最终触发一条消息$emit 到公共Vue() 总线。我澄清了为什么直接绑定 (AFAICT) 是不可能的。

标签: css vue.js vuejs2


【解决方案1】:

您可以考虑使用您在 JS 代码中更改的 CSS 变量(setinterval)。基本上你会有这样的东西:

<div class="night-day">hello</div>


.night-day {
  background-color: var(--bc,black);
  color: var(--c,red)
}

在你的 JS 中你会有这样的东西:

var bc= ["black", "white"]
var c= ["red", "black"]

....
document.querySelector('.night-day').style.setProperty("--bc", bc[i]);
document.querySelector('.night-day').style.setProperty("--c",  c[i]);

...

其中i 是一个索引,您可以根据自己的条件进行更改:

【讨论】:

  • 谢谢。是的,这也是我正在考虑的事情,以一种可能更简单的形式:将所有颜色管理集中在一个地方,并通过它们的id 和document.getElementById() 处理这些元素。将有两个块,可通过if 获得。
【解决方案2】:

我认为解决多主题问题的最佳方法是在 body 标记和 CSS 中使用主题类修饰符,相应地修改子元素。这是一个澄清问题的示例。

<body class="dark-theme">
    <div class="container">
        Content...
    </div>
</body>

.container {
  background-color: white;
  color: black
}

.dark-theme .container {
  background-color: black;
  color: red
}

在body 上切换.dark-theme,在这种情况下,将在默认主题和深色主题之间切换。

【讨论】:

    【解决方案3】:

    你可以使用 vue 中的 v-bind:class (Class binding) 来实现这一点。 喜欢:

     <div class="static" v-bind:class="{ night: isNight, day: !isNight }"></div>
    

    【讨论】:

    • 请参阅我关于为什么我认为这在我的情况下不可行的说明
    • 好吧,也许你可以做一个顶级包装组件?否则我会选择 CSS 变量方法。
    【解决方案4】:

    使用事件总线

    您可以使用 class binding 将 CSS 类绑定到由事件处理程序控制的属性。

    // MyComponent.vue
    <template>
      <div class="daynightdemo" :class="{ night: isNight }">
        ...
      </div>
    </template>
    
    <script>
    import { eventBus } from '@/eventBus'
    
    export default {
      data() {
        return {
          isNight: false
        };
      },
      mounted() {
        this.setNightDay = value => {
          this.isNight = value === "night";
        };
        eventBus.$on("nightDay", this.setNightDay);
      },
      beforeDestroy() {
        eventBus.$off("nightDay", this.setNightDay);
      }
    }
    </script>
    

    您提到从setInterval 定期调用事件总线。在这个例子中,调用看起来像这样:

    // App.vue
    export default {
      mounted() {
        let isNight = true;
        setInterval(() => {
          eventBus.$emit("nightDay", isNight ? "night" : "day");
          isNight = !isNight;
        }, LONG_INTERVAL);
      }
    };
    

    demo with event bus

    使用 Vuex

    使用Vuex,样板文件会有所简化,无需事件回调注册和注销:

    // MyComponent.vue
    <template>
      <div class="daynightdemo" :class="{ night: $store.state.isNight }">
        <h1>isNight: {{ $store.state.isNight }}</h1>
      </div>
    </template>
    
    // App.vue
    export default {
      mounted() {
        setInterval(() => {
          this.$store.state.isNight = !this.$store.state.isNight;
        }, 2000);
      }
    }
    

    demo with Vuex

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-06
      • 2012-08-23
      • 1970-01-01
      • 2020-01-18
      • 1970-01-01
      • 2023-02-09
      • 2012-08-22
      • 2017-04-12
      相关资源
      最近更新 更多