在vuejs模板中使用样式标签并从数据模型更新

时间:2018-03-27 15:04:42

标签: javascript vue.js vuejs2

我想动态更新样式inside样式标记。

但是,为Vue创建容器模型会删除style标记。 我知道样式标签应该属于页面的头部,但这只是为了易于使用。

所以我想要的是一个包含元素和样式标签的包装器:

<div class="setting">
  <style>
    .setting input {
      background: {{bgColor}};
    }
  </style>
  <input class="setting" type="text" v-model="bgColor">
</div>

输入的值应更新css样式的值。 每当使用简单的div元素时,这都有效,但样式标签似乎是一个问题

javascript设置如下:

new Vue({
    el: '.setting',
    data: {
      bgColor: 'red'
    }
});

但是,当样式标记具有特定ID时,这可能有效,但我无法将其绑定到输入字段。

<style id="setting">
  #blue {
    background: {{bg}}
  }
  #blue:hover {
    background: {{bgHover}}
  }
</style>

<div id="blue"></div>

和js:

new Vue({
    el: '#setting',
    data: {
      bg: 'blue',
      bgHover: 'red'
    }
});

有人可以帮助我理解如何在样式标签之间更新值。 jsfiddle set up

感谢。

2 个答案:

答案 0 :(得分:16)

我认为这是一个很好的解决方法/解决方案。

它只是一个自定义组件,因此它可以重复使用。所有Vue的商品如v-if都可以使用。

另一位专业人士认为,只要组件,生成的样式就会出现

&#13;
&#13;
Vue.component('v-style', {
  render: function (createElement) {
    return createElement('style', this.$slots.default)
  }
});


// demo usage, check the template
new Vue({
  el: '#app',
  data: {
    bgColor: 'red'
  }
})
&#13;
<script src="https://unpkg.com/vue"></script>

<div id="app" class="stuff">
  <v-style>
    .stuff input {
      background: {{bgColor}};
    }
  </v-style>

  Remove "red" and type "yellow":
  <input class="setting" type="text" v-model="bgColor">
</div>
&#13;
&#13;
&#13;

我看到的一个缺点是,由于标记的名称是<v-style>(或者您选择调用它的任何名称)而不是<style>,因此IDE可能不会很好地着色它。但除此之外它只是一个普通的<style>标签。

标准解决方案:使用v-bind:style

这不会修改style代码,但设置样式的标准方法是使用object style bindings

基本上,您使用:style属性并以对象的形式为其指定样式的CSS属性。下面的演示。

&#13;
&#13;
new Vue({
  el: '.setting',
  data: {
    bgColor: 'red'
  },
  computed: {
    inputStyles() {
      return {
        background: this.bgColor
      }
    }
  }
});
&#13;
<script src="https://unpkg.com/vue"></script>

<div class="setting">
  Remove "red" and type "yellow":
  <input class="setting" type="text" v-model="bgColor" :style="inputStyles">
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:5)

vue-loader(和Vue模板编译器Vue.compile(..))都会过滤掉generateViewId()中遇到的所有<style>标签。

要解决此问题,一个简单的方法是利用Vue内置的<component> component

template

需要唯一的ID(或其他一些数据属性)才能将样式“范围”到仅此组件。

这是一个不错的解决方案,因为您可以根据需要使用<template> <div> <component is="style"> .foo[data-id="{{ uniqueId }}"] { color: {{ color }}; } .foo[data-id="{{ uniqueId }}"] .bar { text-align: {{ align }} } </component> <div class="foo" :id="id" :data-id="uniqueId"> <div class="bar"> </div> </div> </div> </template> <script> export default { props: { id: { type: String, default: null } }, computed: { uniqueId() { // Note: this._uid is not considered SSR safe though, so you // may want to use some other ID/UUID generator that will // generate the same ID server side and client side. Or just // ensure you always provide a unique ID to the `id` prop return this.id || this._uid; }, color() { return someCondition ? 'red' : '#000'; }, align() { return someCondition ? 'left' : 'right'; } } } </script> 循环来生成样式内容(这可以对组件数据/道具/计算道具的变化做出反应)

v-for