在vue.js组件中,如何使用css中的 prop ?

idv4meu8  于 2023-03-13  发布在  Vue.js
关注(0)|答案(9)|浏览(224)

我是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:中的 prop color(现在是?)。
谢谢。

6rqinv9w

6rqinv9w1#

你真的可以!
您应该在Computed属性中定义CSS变量,然后将computed属性作为样式属性调用到需要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

lvjbypge

lvjbypge2#

不需要,我们使用一个computed属性,然后使用prop返回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>
g9icjywg

g9icjywg3#

现在我们已经到了2020年,我建议使用css函数var来实现这个技巧

<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更新传递的值(例如当你应用hover事件时)。
credit

ui7jx7zq

ui7jx7zq4#

我知道我们在这里讨论的是vue 2,但是如果vue 3的任何人遇到这个问题(像我一样),vue 3引入了一个更干净的方法来做这个

<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

mkh04yzy

mkh04yzy5#

为什么不直接以这种方式使用:style prop:

<template>
  <div :style="{ backgroundColor: color }">
</template>

<script>
export default {
  props: {
    color: {
      type: String,
      default: ''
    }
  }
}
</script>

确保您以camelCase样式定义了css属性。

rqcrx0a6

rqcrx0a66#

如果你需要的css不能通过样式属性来应用,比如伪类或者媒体查询,我会做如下的事情:
在初始化Vue时创建一个全局可用的样式组件(您需要它,否则会遇到掉毛问题)。它创建一个样式标签,简单地呈现插槽中的内容:

只有当你确实需要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>

对我来说,这似乎有点笨拙,但它确实是它的工作,在某些情况下,我宁愿这样做,而不是必须为鼠标悬停或调整大小事件添加额外的JS,这些事件有很大的潜力降低应用程序的性能。

zynd9foi

zynd9foi7#

Vue 3增加了绑定样式的新方式,所以现在你可以很容易地将你的 prop 绑定到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>
mjqavswn

mjqavswn8#

您可以使用CSS var(--foo-bar)函数。如果您试图传递一个有自己的动态路径的资产,它也很有用,就像Shopify一样。
此方法还适用于:before:after元素的样式设置,因为它们引用应用于owner元素的样式。
使用原始post示例传递颜色:

<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

z6psavjg

z6psavjg9#

在Vue2中使用tag添加css样式的简单组件

<template>
    <span class="embed-style" style="display: none" v-html="cssText"></span>
</template>

<script>
export default {
    name: 'EmbedStyle',
    props: {
        rules: {
            type: Array,
            default() {
                return []
            }
        }
    },
    computed: {
        cssText() {
            let txt = ' ';
            this.rules.forEach(rule => {
                txt += `${rule.selector} { `;
                for (const prop in rule.props) {
                    txt += `${this.fromCamelCase(prop)}: ${rule.props[prop]}; `;
                }
                txt += ' } ';
            })
            return `<style>${txt}</style>`;
        }
    },
    methods: {
        fromCamelCase(str) {
            let newStr = '';
            for (let l = 0; l < str.length; l++) {
                if (/[A-Z]/.test(str.charAt(l))) {
                    const lower = str.charAt(l).toLowerCase();
                    newStr += `-${lower}`;
                } else {
                    newStr += str.charAt(l);
                }
            }
            return newStr;
        }
    }
}
</script>

那么我们用这样的方式:

<template>
  <embed-style :rules="[cssRules]" />
...
    
computed: {
        cssRules() {
            return {
                selector: '.toaster .toast',
                props: {
                    animationDuration: `${this.duration}ms !important`,
                    transitionDuration: `${this.duration}ms !important`
                }
            }
        }
}

相关问题