1 Class 与 Style
在使用组件的时候,不可避免的要去使用内联的 style
属性去设置标签样式,按照常规的使用,style
只能是一些属性列表组合成的字符串;这限制了在使用组件时可以自定义或者动态改变样式,而 Vue
对标签的 style
属性进行了优化,从而使其可以支持对象/字符串/数组形式的赋值。
2 v-bind:class
的应用
使用时取值可以是普通的样式名作为 key
和真假值组成的对象,也可以使用计算属性
2.1 绑定字面量对象
除了可以使用原生的 class
类属性之外,vue
提供了 v-bind:class
来使用类样式
比如:改变 div 的背景色,给 div 绑定到 class: active
// div 样式
<style>
#test { width: 100px; height: 100px; }
.test { background-color: gray; }
.active { background-color: red; }
</style>
这里样式定义的时候需要注意,如果 .test
是固定样式,.active
是可变样式,那么两者样式声明的先后顺序就是 .test -> .active
,否则不论怎么使用 v-bind:class
,并且后续改变 {active: true}
的值都无法改变背景,因为从优先级上来说,都被后面声明的 .test
给覆盖了。
// vue 域
<div id="app">
<div id="test" class="test" v-bind:class="{ active: isActive }"><h1>{{message}}</h1></div>
</div>
数据:
// Vue 组件
var vm = new Vue({
el: '#app',
data: {
message: 'hello vue !',
isActive: true,
}
})
结果为:通过修改 isActive
的值来决定是否添加样式:.active
如果将 .test
和 .active
样式声明顺序调转一下,现象如下:
无论如何修改isActive
的值都无法使 .active
的样式生效
2.2 绑定普通对象
修改点1: 将绑定内容修改成 data
中定义的数据对象 generalClsObj
,该对象包含了类似上面字面量写法的对象,比如:{a:true, b:false}
<div id="app">
<div id="test" class="test" v-bind:class="generalClsObj"><h1>{{message}}</h1></div>
</div>
修改点2: data
数据中添加类样式绑定的对象
data: {
// 普通对象
generalClsObj: {
active: true,
'text-danger': false
}
}
这里 generalClsObj
对象里面的成员值也可以使用 data
数据内的属性
增加样式:
.text-danger { color: blue; }
效果如下:
2.3 绑定计算属性
计算属性特性:只有被绑定的状态值发生变化时,则计算属性的值才会重新计算得出最新结果,因为计算属性会缓存计算结果。
修改点1:把绑定内容改成计算属性
<div id="test" class="test" v-bind:class="computedClsObj"><h1>{{message}}</h1></div>
修改点2:数据中添加计算属性绑定的状态值
data: {
isActive: true,
error: null,
}
修改点3:添加计算属性
computed: {
computedClsObj: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal',
};
}
}
测试结果:控制台修改 this.isActive
和 this.error
值
修改 this.error = {type: 'fatal'};
表示出现错误,错误类型为 fatal
,背景会还原,文字颜色为 text-danger
的蓝色;
强制修改 isActive
为 true
,背景会变红;
由此可见,通过修改计算属性 computedClsObj
绑定的状态值,可以触发计算属性重新计算值,从而触发 UI 更新显示。
2.4 绑定数组
绑定数组的时候,数组元素可以是普通类型,如果需要绑定状态值来决定是否使用样式,则可以用三元符表达式最后取结果的值,也可以直接指定元素为对象;
-
数组元素为普通类型
为普通类型的时候,需要在组件模型
data: {}
中定义,比如:activeCls
和textDangerCls
data: { activeCls: 'active', textDangerCls: 'text-danger' }
然后就可以直接使用了,如下
v-bind:class="[activeCls, textDangerCls]"
渲染后的结果是:
-
数组元素为三元符形式
使用方式:
<div id="test" class="test" v-bind:class="[ isActive ? activeCls : '', textDangerCls]"><h1>{{message}}</h1></div>
渲染后的结果,将是
div#test
的样式会有三个:test active text-danger
修改
isActive
为false
,active
样式会被删除,只剩下test text-danger
-
数组元素为对象形式
由于需要使用条件判断,或者需要将样式绑定到状态值,或者可以当作是三元符的一种简化方式,可以使用对象形式作为数组元素来处理样式
<div id="test" class="test" v-bind:class="[ {active: isActive}, textDangerCls]"><h1>{{message}}</h1></div>
修改后的效果同三元符,不做赘述。
<div id="test" class="test" v-bind:class="[ {active: isActive, 'text-danger': error} ]"><h1>{{message}}</h1></div>
其实这种使用方式和完全用对象形式差不多,只是使用数组的时候可以考虑更多的情况。
对象形式:
v-bind:class="{active: isActive, 'text-danger': error}"
3 组件样式
组件样式:定义在自定义组件上的样式,使用 class=
或者 v-bind:class=
形式均可。
组件样式最终会被应用到该组件的顶级标签上(即:最外层标签)
比如:
-
普通类样式:
class=
自定义组件:
Vue.component('my-component', { template: '<div id="my-comp" class="red big">my component</div>' });
样式:
.red { background-color: red; } .big { font-size: 32px; } .tall { height: 100px; } .short { width: 200px; } .wide { width: 300px; }
组件模版中只有
red big
,在使用的时候通过class="tall wide
属性给组件添加样式,最后添加到的标签为最外层标签,即id="my-comp"
的div
标签上面。有子标签的渲染结果:
-
v-bind:class=
绑定类样式修改组件内绑定样式:
<my-component v-bind:class="{tall: true, wide: true}"></my-component>
渲染结果同上。
关于组件上的绑定样式使用和普通标签的使用方式是一样的,具体可参考上面的章节。
此处省略……。
4 绑定内联样式
内联样式的使用是通过 style
属性定义。
使用方式:v-bind:style="value"
,与 v-bind:class
同样,value
的值也可以是对象,数组。
以下分别针对对象和数组形式的样式来说明:
4.1 内联样式对象类型
语法: v-bind:style={ color: 'red', 'font-size': '32px' }
对象内的关键字与普通 css
样式对应,同时也可以是驼峰式
写法,比如上面的可以写成:{color: 'red', fontSize: '32px'}
在使用对象类型的时候,推荐使用data:{}
中声明方式,然后通过 v-bind:style=
直接绑定数据。
data: {
styleObj: {
color: 'red',
fontSize: '32px'
}
}
使用:
<div v-bind:style="styleObj"></div>
尝试使用计算属性
data: {
fontColor: 'blue',
fontSize: '32px',
},
computed: {
computedStyleObj: function () {
return {
color: this.fontColor,
fontSize: this.fontSize,
}
},
}
然后修改成: <div v-bind:style="computedStyleObj"></div>
结果OK:
4.2 绑定数组内联样式
数组内联样式,通过 v-bind:style=[]
指定,数组内的元素可以是普通的 css
样式
例如:
<div v-bind:style="{background: 'red', fontSize: '22px', color: 'white'}">我是内联样式:数组格式</div>
也可以是对象数组:
<div v-bind:style="[{background: 'red'}, {color: 'white'}, {fontSize: '22px'}]">我是内联样式:数组格式</div>
为了简便易读,最好采用数据属性方式:即在 data
中声明,v-bind:style=
中使用
data: {
arrStyle: [
{background: 'red'},
{ color: 'white' },
{ fontSize: '22px' }
]
}
然后使用: <div v-bind:style="arrStyle">我是内联样式:数组格式</div>
还可以对象数组形式:
<div v-bind:style="[bgStyle, colorStyle, fontStyle]">我是内联样式:数组格式</div>
data: {
bgStyle: { background: 'red' },
colorStyle: { color: 'white' },
fontStyle: { fontSize: '22px' }
}
5 样式自动前缀
与样式有关的还有这个,在有多个浏览器前缀的样式,vue
会自动为该属性添加前缀。
<h3>自动前缀</h3>
<div v-bind:class="['rect', 'red']" v-bind:style="transformStyle">transform 自动前缀</div>
transform 样式数据:
data: {
transformStyle: {
transform: 'rotate(7deg)'
}
}
从渲染结果中元素的style 中看,貌似并没有多个前缀的样式出现。
找了下,貌似没找到比较实际有用的关于 vue
自身的自动前缀的问题,到时看到个通过 webpack
打包配置来实现自动前缀的问题,在这里贴下:
test: /.vue$/,
loader: 'vue-loader',
options: {
// vue-loader options go here
postcss: [require('autoprefixer')({ browsers: ['last 10 Chrome versions', 'last 5 Firefox versions', 'Safari >= 6', 'ie > 8'] })]
这里是 autoprefixer
插件的地址和介绍。
6 多重值
-
多重值问题不是很明白,也没搜出什么结果,暂时先做遗留。
7 总结
本篇记录了官网学习的一些关于标签或组件的样式,包括类样式,绑定类样式,绑定行内样式等内容。
绑定类样式方式: v-bind:class=“styleClsName"
这种方式是基于类样式名称上的,具体的值可以是
- 类名:
v-bind:class="focus"
- 类名数组:
v-bind:class="['focus', 'shine']"
- 样式对象:
v-bind:classs="{'focus': true/false, 'shine': true/flase }"
,这种方式会根据样式名作为键的值来决定是否采用,如果值为:false
,则不采用该样式,否则应用该样式。 - 对象数组:
v-bind:class="[{'focus': true}, {'shine': false}]"
并且类名样式的值还可以绑定数据,用数据来控制样式,从而可以使用响应式样式。
绑定行内样式对象:v-bind:style="styleObj"
绑定内联样式对象,这里不再是直接使用类名,而是直接使用 css
属性,需要注意的是这里需要的数据类型为:对象或者对象数组
比如:
对象形式:v-bind:style="{background:'red'}"
数组形式: v-bind:style="[{background: 'red'}, {fontSize: '22px'}]"
原文:https://blog.csdn.net/gccll/article/details/71814685