【问题标题】:In vue.js component, how to use props in css?在 vue.js 组件中,如何在 css 中使用 props?
【发布时间】:2017-08-09 20:46:58
【问题描述】:

我是 vue.js 的新手。这是我的问题:

在这样的 *.vue 文件中:

<template>
  <div id="a">
  </div>
</template>

<script>
  export default {
    name: 'SquareButton',
    props: ['color']
  }
</script>

<style scoped>
    #a {
      background-color: ?
    }
<style>

如何在background-color: 中使用道具color(现在是?)。

谢谢。

【问题讨论】:

    标签: css vue.js vuejs2 vue-component


    【解决方案1】:

    你真的可以!

    您应该在计算属性中定义 CSS 变量,然后将计算属性调用为需要 CSS 变量的元素的样式属性,最后您可以在文档底部的标签中使用该变量。

    new Vue({
      el: '#app',
      data: function() {
        return {
          baseFontSize: 1,
          bgHoverColor: "#00cc00",
          hoverContent: "Hovering!"
        }
      },
      computed: {
        cssProps() {
          return {
            '--hover-font-size': (this.baseFontSize * 2) + "em",
            '--bg-hover-color': this.bgHoverColor,
            '--hover-content': JSON.stringify(this.hoverContent)
          }
        }
      }
    })
    div {
      margin: 1em;
    }
    
    div.test:hover {
      background-color: var(--bg-hover-color);
      font-size: var(--hover-font-size);
    }
    
    div.test:hover::after {
      margin-left: 1em;
      content: var(--hover-content);
    }
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    
    <div id="app" :style="cssProps">
    
      <div>Hover text: <input type="text" v-model="hoverContent"></div>
      <div>Hover color: <input type="color" v-model="bgHoverColor"></div>
    
      <div class="test">Hover over me</div>
    </div>

    或者看看这里:https://codepen.io/richardtallent/pen/yvpERW/
    在这里:https://github.com/vuejs/vue/issues/7346

    【讨论】:

    • 将您的代码放在 SO 上将使这成为一个更好、更完整的答案。
    • 我发现这无论如何都是最好的答案,即使您在您的 css 中需要动态值和无法应用于样式属性的 css 功能 @gwildu 强调这是使用他的答案的唯一原因。在我看来,这似乎是最简洁的解决方案,实际上是在 vue 中实现它的正确方法。
    • 这是 2021 年的最佳答案,并按照 Vue 喜欢的方式进行。
    【解决方案2】:

    你没有。您使用计算属性,然后使用道具返回 div 的样式,如下所示:

    <template>
      <div id="a" :style="style" @mouseover="mouseOver()">
      </div>
    </template>
    
    <script>
      export default {
        name: 'SquareButton',
        props: ['color'],
        computed: {
          style () {
            return 'background-color: ' + this.hovering ? this.color: 'red';
          }
        },
        data () {
          return {
            hovering: false
          }
        },
        methods: {
          mouseOver () {
           this.hovering = !this.hovering
          }
        }
      }
    </script>
    
    <style scoped>
    <style>
    

    【讨论】:

    • 感谢您的回答。如果我想使用 css 伪类,比如:hover,我该怎么办?谢谢。
    • 您可以使用鼠标悬停事件来触发数据更改,并在样式计算属性中使用该数据属性。我编辑了这个例子,所以你可以看到一个例子(虽然它没有经过测试,所以也许有一些需要修复的地方,但我认为你可以理解)
    • 如果我使用 vuetify 并且元素是动态创建的,我无法绑定到模板标记中没有明确写入的元素?
    • 返回的样式是否也有作用域,还是会泄漏到子元素? (我的猜测是它是全局的,因为转换需要 PostCSS。有什么方法可以确定它的范围吗?)
    • 如何处理 css 路径?例如,如果我想计算一个通常为background-image: url('~@/path/to.image') 的背景图像属性,如果我按照你的方式进行操作,它会以实际前端站点上的路径结束,并且不起作用
    【解决方案3】:

    现在是 2020 年,我建议将此技巧与名为 var 的 css 函数一起使用

    <template>
        <div id="a" :style="cssVars"></div>
    </template>
    
    <script>
    export default {
        props: ['color'],
        computed: {
          cssVars () {
            return{
              /* variables you want to pass to css */
              '--color': this.color,
            }
        }
    }
    <script>
    
    <style scoped>
    #a{
        background-color: var(--color);
    }
    </style>
    

    此方法非常有用,因为它允许您稍后通过 css 更新传递的值(例如,当您应用悬停事件时)。

    credit

    【讨论】:

    • @Geniusintrouble ~95% caniuse.com/css-variables
    • 这太棒了。如果我之前不知道关键的“背景颜色”怎么办?假设我想为悬停传递一组效果?
    【解决方案4】:

    如果您需要样式属性(如伪类或媒体查询)无法应用的 css,我的做法如下:

    在初始化 Vue 时创建一个全局可用的样式组件(你需要它,否则你会遇到 linting 问题)。它创建一个样式标签,简单地呈现插槽中的内容:

    只有在您确实需要 css 中的动态值和无法应用于样式属性的 css 功能时,我才会使用它。

    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    
    Vue.config.productionTip = false
    Vue.component('v-style', {
      render: function(createElement) {
        return createElement('style', this.$slots.default)
      }
    })
    
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    

    然后像这样在模板的顶部使用它,您将获得组件的完整 JavaScript 范围和完整的 css 语法组合:

    <template>
      <v-style>
        @media screen and (max-width: 820px) {
          .gwi-text-media-{{ this.id }} {
            background-image: url({{ mobileThumb }});
          }
        }
      </v-style>
    </template>
    

    对我来说这似乎有点 hacky,但它确实有效,在某些情况下我宁愿这样做,而不是为鼠标悬停或调整可能会降低应用程序性能的事件添加额外的 JS .

    【讨论】:

    • 这是最好的答案
    • 有趣的想法。谢谢。
    • 在这种情况下不需要自定义组件。你可以做&lt;component :is="'style'"&gt;&lt;/component&gt;
    【解决方案5】:

    为什么不直接用:style这个属性:

    <template>
      <div :style="{ backgroundColor: color }">
    </template>
    
    <script>
    export default {
      props: {
        color: {
          type: String,
          default: ''
        }
      }
    }
    </script>
    

    确保您以驼峰式风格定义 css 属性。

    【讨论】:

    • 这个答案最好地回答了 OP 的问题。
    • 那不是完全覆盖样式吗?
    【解决方案6】:

    您可以使用 CSS var(--foo-bar) 函数。如果您尝试传递具有自己的动态路径的资产(如 Shopify),它也很有用。

    此方法也适用于设置 :before:after 元素的样式,因为它们引用了应用于所有者元素的样式。

    使用原始帖子示例传递颜色:

    <template>
      <div
        id="a"
        :style="{ '--colour': color }">
      </div>
    </template>
    
    <script>
      export default {
        name: 'SquareButton',
        props: ['color']
      }
    </script>
    
    <style scoped>
      #a {
        background-color: var(--colour);
      }
    <style>
    

    使用原始帖子示例传递 URL:

    <template>
      <div
        id="a"
        :style="{ '--image-url': 'url(' + image + ')' }">
      </div>
    </template>
    
    <script>
      export default {
        name: 'SquareButton',
        props: ['image']
      }
    </script>
    
    <style scoped>
      #a {
        background-url: var(--image-url);
      }
    <style>
    

    Source

    【讨论】:

      【解决方案7】:

      Vue 3 添加了新的绑定样式方式,因此现在您可以轻松地将道具绑定到 css 属性。

      阅读来源: https://learnvue.co/2021/05/how-to-use-vue-css-variables-reactive-styles-rfc/

      <template>
        <div>
          <div class="text">hello</div>
        </div>
      </template>
      
      <script>
        export default {
          data() {
              return {
                  color: 'red',
              }
          }
        }
      </script>
      
      <style>
        .text {
          color: v-bind(color);
        }
      </style>
      

      【讨论】:

        【解决方案8】:

        我知道我们在这里讨论的是 vue 2,但是如果来自 vue 3 的任何人都回答了这个问题(就像我一样),vue 3 引入了一种更简洁的方法:: p>

        <template>
          <div id="a">
          </div>
        </template>
        
        <script>
          export default {
            name: 'SquareButton',
            props: ['color']
          }
        </script>
        
        <style scoped>
            #a {
              background-color: v-bind(color);
            }
        <style>
        

        Vue 在幕后所做的实际上是相同的“通过组件的样式过程引入 css 变量”,但现在看起来确实好多了。

        文档来源:https://v3.vuejs.org/api/sfc-style.html#state-driven-dynamic-css

        【讨论】:

        • 啊。他们当然做到了......为什么我们不能在 vue 2 中得到那种爱:(
        猜你喜欢
        • 2018-06-08
        • 2019-03-05
        • 2022-11-03
        • 2020-09-16
        • 1970-01-01
        • 2016-12-30
        • 2018-06-21
        • 2019-05-19
        • 2018-02-14
        相关资源
        最近更新 更多