web-dev-qa-db-fra.com

Utiliser des balises de style dans le modèle vuejs et mettre à jour à partir du modèle de données

Je souhaite mettre à jour dynamiquement les balises de style inside.

Cependant, la création d'un modèle de conteneur pour Vue supprime les balises style. Je sais que les balises de style doivent appartenir en tête de page, mais c'est juste pour des raisons de facilité d'utilisation.

Donc, ce que j'aimerais avoir, c'est un wrapper avec un élément et des balises de style à l'intérieur:

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

La valeur de l'entrée doit mettre à jour la valeur du style css. Chaque fois que cela est fait avec des éléments div simples, cela fonctionne, mais les balises de style semblent être un problème

La configuration javascript est la suivante:

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

Cependant, lorsque les balises de style ont un identifiant spécifique, cela peut fonctionner, mais je ne peux pas le lier à un champ de saisie.

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

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

et les js:

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

Quelqu'un peut-il m'aider à comprendre comment je peux mettre à jour les valeurs entre les balises de style? configuration jsfiddle

Merci.

11
ForDev

Voici ce que je pense être une bonne solution de contournement.

Ce n'est qu'un composant personnalisé, il est donc aussi réutilisable que possible. Tous les produits de Vue comme v-if peut tous être utilisés.

Un autre avantage est que les styles générés ne seront là que tant que le composant sera !

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'
  }
})
<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>

Le seul inconvénient que je vois est que, puisque le nom de la balise est <v-style> (ou peu importe comment vous l'appelez) et non <style>, les IDE peuvent ne pas bien colorer. Mais sinon, ce sera comme un _ <style> tag.


Solution standard: en utilisant v-bind:style

Cela ne modifie pas les balises style, mais la manière standard de définir les styles utilise les liaisons de style d'objet .

Fondamentalement, vous utiliseriez un :style attribuer et lui affecter les propriétés CSS du style sous la forme d'un objet. Démo ci-dessous.

new Vue({
  el: '.setting',
  data: {
    bgColor: 'red'
  },
  computed: {
    inputStyles() {
      return {
        background: this.bgColor
      }
    }
  }
});
<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>
20
acdcjunior

vue-loader (et Vue compilateur de modèles Vue.compile(..) ) les deux filtreront tout <style> balises rencontrées.

Une solution simple pour contourner ce problème consiste à tirer parti de la fonction intégrée de Vue <component> composant .

<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>

Un ID unique (ou un autre attribut de données) est requis pour "étendre" les styles à ce composant uniquement.

Ceci est une bonne solution car vous pouvez utiliser v-for boucles pour générer le contenu de style si nécessaire (qui peut être réactif aux changements dans vos données de composants/accessoires/accessoires calculés)

<component is="style" type="text/css">
  <template v-for="item in items">
    [data-id="{{ uniqueId }}"] div.bar[data-div-id="item.id"]::before {
      content: "{{ item.content }}";
      color: {{ item.color }};
    }
  </template>
</component>
3
Troy Morehouse