javascript 在 vuejs 模板中使用样式标签并从数据模型更新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49516424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use style tags inside vuejs template and update from data model
提问by ForDev
I would like to dynamically update styles insidestyle tags.
我想动态更新样式inside样式标签。
However creating a container model for Vue, removes the styletags.
I know style tags should belong in the head of the page, but this is just for the sake of ease of use.
但是,为 Vue 创建容器模型会删除style标签。我知道样式标签应该属于页面的头部,但这只是为了方便使用。
So what I would like to have is a wrapper with an element and style tags inside:
所以我想要的是一个带有元素和样式标签的包装器:
<div class="setting">
<style>
.setting input {
background: {{bgColor}};
}
</style>
<input class="setting" type="text" v-model="bgColor">
</div>
The value from the input should update the value of the css style. Whenever done with simple div elements this works, but style tags seem to be a problem
来自输入的值应该更新 css 样式的值。每当使用简单的 div 元素完成这工作,但样式标签似乎是一个问题
The javascript set up is the following:
javascript设置如下:
new Vue({
el: '.setting',
data: {
bgColor: 'red'
}
});
However when the style tags have a specific id, this could work, but I can't bind it to an input field.
但是,当样式标签具有特定 id 时,这可以工作,但我无法将其绑定到输入字段。
<style id="setting">
#blue {
background: {{bg}}
}
#blue:hover {
background: {{bgHover}}
}
</style>
<div id="blue"></div>
and the js:
和js:
new Vue({
el: '#setting',
data: {
bg: 'blue',
bgHover: 'red'
}
});
Can someone help me understand how I can achieve updating values between style tags. jsfiddle set up
有人可以帮助我了解如何在样式标签之间更新值。 jsfiddle 设置
Thanks.
谢谢。
回答by acdcjunior
Here's what I think is a good workaround/solution.
这是我认为是一个很好的解决方法/解决方案。
It is just a custom component, so it's as reusable as it gets. All of Vue's goods like v-ifcan all be used.
它只是一个自定义组件,因此可以尽可能地重复使用。Vue的所有商品likev-if都可以用。
Another pro is that the styles generated will be there only as long as the component is!
另一个优点是,生成的样式只会在组件存在时才存在!
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>
The one drawback I see is that since the name of the tag is <v-style>(or whatever you chose to call it) and not <style>, the IDEs may not color it nicely. But otherwise it'll just be like a regular <style>tag.
我看到的一个缺点是,由于标签的名称是<v-style>(或您选择的任何名称)而不是<style>,IDE 可能无法很好地为其着色。但否则它就像一个普通的<style>标签。
Standard solution: using v-bind:style
标准解决方案:使用 v-bind:style
This doesn't modify styletags, but the standard way of setting styles is using object style bindings.
这不会修改style标签,但设置样式的标准方法是使用对象样式绑定。
Basically you'd use a :styleattribute and assign to it the CSS properties of the style in the form of an object. Demo below.
基本上,您将使用一个:style属性并以对象的形式为其分配样式的 CSS 属性。下面演示。
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>
回答by Troy Morehouse
vue-loader (and Vue template compiler Vue.compile(..)) both will filter out any <style>tags that are encountered in the template.
vue-loader(和 Vue 模板编译器Vue.compile(..))都会过滤掉<style>在template.
A simple solution to get around this, is to take advantage of Vue's built-in<component>component.
解决这个问题的一个简单解决方案是利用 Vue 的内置<component>组件。
<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>
A unique ID (or some other data-attribute) is required to "scope" the styles to just this component.
需要一个唯一的 ID(或其他一些数据属性)来将样式“范围”到这个组件。
This is a nice solution as you can use v-forloops to generate the style content if required (which can be reactive to changes in your components data/props/computed props)
这是一个很好的解决方案,因为您可以v-for根据需要使用循环来生成样式内容(这可以对组件数据/道具/计算道具的变化做出反应)
<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>

