元素样式绑定
在HTML中,定义DOM元素的样式可以使用class属性和style属性。在Vue.js中,对元素样式的绑定实际上就是对元素的class和style属性进行操作,class属性用于定义元素的类名列表,style属性用于定义元素的内联样式。使用v-bind指令可以对这两个属性进行数据绑定。在将v-bind用于class和style时,相比于HTML,Vue.js为这两个属性做了增强处理。除了字符串,表达式的结果类型还可以是对象或数组。本章主要讲解Vue.js中的样式绑定,包括class属性绑定和内联样式绑定。
1、class绑定
在HTML中,为元素设置样式时使用较多的是class属性。在样式绑定中,对元素的class属性进行绑定,绑定的数据可以是对象或数组。下面分别介绍这两种语法。
1.1、对象语法
使用v-bind对元素的class属性进行绑定,最常用的是将绑定的数据设置为一个对象,这样可以动态地切换元素的class。将元素的class属性绑定为对象主要有以下三种形式。
1.1.1、内联绑定
这种形式是将元素的class属性直接绑定为一个对象,代码如下:
html
<div v-bind:class="{active : isActive}"></div>
上述代码中,active是元素的class类名,isActive是data选项中的属性,它是一个布尔值。如果该值为true,就表示元素使用类名为active的样式,否则就不使用。
例如,为div元素绑定class属性,将字体粗细设置为粗体,字体大小设置为26像素,文字颜色设置为红色,代码如下:
html
<style>
.active{
font-weight: bold;
font-size: 26px;
color: red;
}
</style>
<div id="app">
<div v-bind:class="{active: isActive}">有志者事竟成</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
isActive: true
}
},
}).mount('#app');
</script>

示例:为书名添加颜色。
在图书列表中,为书名"JavaScript精彩编程200例"和"HTML5+CSS3精彩编程200例"添加文字样式,实现步骤如下。
- 编写CSS代码,为页面元素设置样式。其中的active类名选择器用于设置书名"JavaScript精彩编程200例"和"HTML5+CSS3精彩编程200例"的文字样式,代码如下:
css
<style>
body{
font-family: 微软雅黑;
}
.item{
width: 350px;
height: 100px;
line-height: 100px;
border-bottom: 1px solid #000000;
}
.item img{
width: 100px;
float: left;
}
.active{
font-weight: bolder;
color: #FF0000;
}
</style>
- 创建根组件实例,定义图书信息数组,为用于显示书名的span元素绑定class属性,代码如下:
html
<div id="app">
<div>
<div class="item" v-for="book in books">
<img v-bind:src="book.image">
<span v-bind:class="{active: book.active}">{{book.title}}</span>
</div>
</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
books: [
{
title: 'Java',
image: 'images/1.jpg',
active: false
},
{
title: 'C++',
image: 'images/2.jpg',
active: true
},
{
title: 'Node.js',
image: 'images/3.jpg',
active: false
},
{
title: 'Go',
image: 'images/4.jpg',
active: true
},
]
}
},
}).mount('#app');
</script>

在元素的class属性绑定的对象中可以传入多个属性,这样可以动态切换元素的多个class。另外,对元素绑定class属性的同时也可以为元素添加静态的class属性。示例代码如下
html
<style>
.bold{
font-weight: bold;
}
.shadow{
text-shadow: 2px 2px 3px #0000FF;
}
.default{
font-size: 24px;
color: blue;
letter-spacing: 5px;
}
</style>
<div id="app">
<div class="default" v-bind:class="{bold: isBold, shadow: isShadow}">坚持就是胜利</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
isBold: true,
isShadow: true
}
},
}).mount('#app');
</script>

上述代码中,由于isBold和isShadow属性的值都为true,因此结果渲染为:
html
<div class="default bold shadow">坚持就是胜利 </div>
当isBold或者isShadow的属性值发生变化时,元素的class列表也会相应进行更新。例如,将isBold属性值设置为false,则元素的class列表将变为"defaultshadow"。
1.1.2、内联绑定
非内联绑定的形式是将元素的class属性绑定的对象定义在data选项中。例如,将上一个示例中绑定的对象定义在data选项中,代码如下:
html
<style>
.bold{
font-weight: bold;
}
.shadow{
text-shadow: 2px 2px 3px #0000FF;
}
.default{
font-size: 24px;
color: blue;
letter-spacing: 5px;
}
</style>
<div id="app">
<div class="default" v-bind:class="classObject">坚持就是胜利</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
classObject: {
bold: true,
shadow: true
}
}
},
}).mount('#app');
</script>

1.1.3、绑定为一个计算属性
这种形式是将元素的class属性绑定为一个返回对象的计算属性。这是一种常用且强大的模式。例如,将上一个示例中的class属性绑定为一个计算属性,代码如下:
html
<style>
.bold{
font-weight: bold;
}
.shadow{
text-shadow: 2px 2px 3px #0000FF;
}
.default{
font-size: 24px;
color: blue;
letter-spacing: 5px;
}
</style>
<div id="app">
<div class="default" v-bind:class="setStyle">坚持就是胜利</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
isBold: true,
isShadow: true
}
},
computed: {
setStyle() {
return {
bold: this.isBold,
shadow: this.isShadow
}
}
}
}).mount('#app');
</script>
</body>
</html>

示例:竖向导航菜单。
在页面中输出一个竖向的导航菜单。将定义菜单和菜单项的元素的class属性绑定为定义的计算属性。实现步骤如下。
- 编写CSS代码,为页面元素设置样式。定义3个类名选择器menu、menuli和menua,代码如下:
css
<style>
.memu{
width: 200px;
list-style: none;
position: fixed;
top: 20px;
left: 30px;
}
.menuli{
margin-top: 10px;
}
.menua{
display: block;
background: blue;
width: 120px;
font-size: 14px;
text-decoration: none;
color: white;
padding: 10px 15px 10px 12px;
-webkit-border-top-right-radius: 10px;
-webkit-border-bottom-right-radius: 10px;
}
</style>
- 创建根组件实例,定义导航菜单项数组,分别将ul元素、li元素和a元素的class属性绑定为一个计算属性,代码如下:
html
<div id="app">
<ul v-bind:class="liObj" v-for="item in items">
<a href="javascript:void(0)" v-bind:class="aObj">{{item}}</a>
</ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
items: [
'食品/酒类/生鲜',
'大家电/小家电',
'家具/家具/出具',
'艺术/鲜花/礼品',
'手机/电脑/数码',
'男鞋/运动/户外'
],
isMenu: true,
isMenuli: true,
isMenua: true
}
},
computed: {
ulObj: function() {
return {menu:this.isMenu};
},
liObj: function() {
return {munuli: this.isMenuli};
},
aObj: function() {
return {menua: this.isMenua};
}
}
}).mount('#app');
</script>

1.2、数组语法
使用v-bind对元素的class属性进行绑定,还可以将绑定的数据设置为一个数组的形式,这样可以为元素应用一个class列表。将元素的class属性绑定为数组同样有以下三种形式。
1.2.1、直接绑定为数组
这种形式是将元素的class属性直接绑定为一个数组,格式如下:
html
<div v-bind:class="[element1, element2]"></div>
上述代码中,element1和element2为data选项中的属性,它们的值为class列表中的类名。
例如,应用数组的形式为div元素绑定class属性,为文字设置大小、颜色和阴影效果,代码如下:
html
<style>
.size{
font-size: 26px;
}
.color{
color: purple;
}
.shadow{
text-shadow: 2px 2px 2px #00FFFF;
}
</style>
<div id="app">
<div :class="[sizeClass, colorClass, shadowClass]">自我控制是最强者的本能</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
sizeClass: 'size',
colorClass: 'color',
shadowClass: 'shadow'
}
},
}).mount('#app');
</script>

1.2.2、使用条件运算符
使用数组形式绑定元素的class属性时,可以在数组中使用条件运算符来判断是否使用列表中的某个class。示例代码如下:
html
<style>
.size{
font-size: 26px;
}
.color{
color: purple;
}
.shadow{
text-shadow: 2px 2px 2px #00FFFF;
}
</style>
<div id="app">
<div :class="[sizeClass, colorClass, isShadow ? 'shadow' : '']">自我控制是最强者的本能</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
sizeClass: 'size',
colorClass: 'color',
isShadow: true
}
},
}).mount('#app');
</script>

1.2.3、使用对象
如果在数组中使用多个条件运算符切换元素列表中的class,这种写法就会比较烦琐。这时,可以在数组中使用对象来更新元素的class列表。
例如,将上一个示例中应用的条件运算符表达式更改为对象的形式,代码如下:
html
<style>
.size{
font-size: 26px;
}
.color{
color: purple;
}
.shadow{
text-shadow: 2px 2px 2px #00FFFF;
}
</style>
<div id="app">
<div :class="[sizeClass, colorClass, {shadow: isShadow}]">自我控制是最强者的本能</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
sizeClass: 'size',
colorClass: 'color',
isShadow: true
}
},
}).mount('#app');
</script>

2、style绑定
在样式绑定中,除了可以绑定元素的class属性,还可以绑定元素的style属性,这种形式是对元素的内联样式进行绑定,绑定的数据可以是对象或数组。下面分别介绍这两种语法。
2.1、对象语法
使用v-bind对元素的style属性进行绑定,最常用的是将绑定的数据设置为一个对象。这种对象语法看起来比较直观。对象中的CSS属性名可以用驼峰式(camelCase)或短横线分隔(kebab-case,需用单引号括起来)的形式命名。将元素的style属性绑定为对象主要有以下三种形式。
2.1.1、内联绑定
这种形式是将元素的style属性直接绑定为一个对象,对象的键是CSS属性名,对象的值是data选项中的属性值。例如,应用对象的形式为div元素绑定style属性,设置文字的大小、粗细和阴影效果,代码如下:
html
<div id="app">
<div :style="{fontWeight: weight, textShadow: shadow, 'font-size': size + 'px'}">书是人类进步的阶梯</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
weight: 'bold',
shadow: '2px 2px 1px gray',
size: 20
}
},
}).mount('#app');
</script>

2.1.2、非内联绑定
这种形式是将元素的style属性绑定的对象直接定义在data选项中,这样可以使模板看起来更清晰。例如,将上一个示例中绑定的对象直接定义在data选项中,代码如下:
html
<div id="app">
<div :style="styleObject">书是人类进步的阶梯</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
styleObject: {
fontWeight: 'bold',
textShadow: '2px 2px 1px gray',
'font-size': '20px'
}
}
},
}).mount('#app');
</script>

示例:为搜索框绑定样式。
使用非内联绑定的形式为电子商城中的搜索框绑定样式,将绑定的样式对象定义在data选项中。代码如下:
html
<div id="app">
<div>
<form :style="form">
<input :style="input" type="text" placeholder="请输入搜索内容">
<input :style="button" type="submit" value="搜索">
</form>
</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
form: {
border: '2px solid blue',
'max-width': '360px'
},
input: {
'padding-left': '5px',
height: '50px',
width: '76%',
outline: 'none',
'font-size': '16px',
border: 'none'
},
button: {
height: '50px',
width: '22%',
float: 'right',
background: 'blue',
color: '#F6F6F6',
'font-size': '18px',
cursor: 'ponter',
border: 'none'
}
}
},
}).mount('#app');
</script>

2.1.3、绑定为一个计算属性
在绑定style属性的对象语法中,还可以将元素的style属性绑定为一个返回对象的计算属性。例如,将上一个示例中的style属性绑定为一个计算属性,代码如下:
html
<div id="app">
<div :style="setStyle">书是人类进步的阶梯</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
weight: 'bold',
shadow: '2px 2px 1px gray',
size: 20
}
},
computed: {
setStyle() {
return {
fontWeight: this.weight,
textShadow: this.shadow,
'font-size': this.size + 'px'
}
}
}
}).mount('#app');
</script>

2.2、数组语法
在对元素的style属性进行绑定时,可以将多个样式对象放在一个数组里。使用数组的形式绑定元素的style属性,可以有以下几种形式。
第一种形式是直接在元素中绑定样式对象。示例代码如下:
html
<div id="app">
<div :style="[{color: 'blue'}, {fontSize: '26px'}, {'font-weight': 'bold'}]">天生我材必有用</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {}
},
}).mount('#app');
</script>

第二种形式是将样式对象数组定义在data选项中。示例代码如下:
html
<div id="app">
<div :style="arrStyle">天生我材必有用</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
arrStyle: [
{color: 'blue'},
{fontSize: '26px'},
{'font-weight': 'bold'}
]
}
},
}).mount('#app');
</script>

第三种形式是以对象数组的形式进行绑定。示例代码如下:
html
<div id="app">
<div :style="[color, size, weight]">天生我材必有用</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
const vm = Vue.createApp({
data() {
return {
color: {color: 'blue'},
size: {fontSize: '26px'},
weight: {'font-weight': 'bold'}
}
},
}).mount('#app');
</script>

当v-bind:style使用需要特定前缀的CSS属性(如transform)时,Vue.js会自动侦测并添加相应的前缀。