操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute,所以我们可以用 v-bind
处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
简而言之,就是我们可以给 HTML DOM 元素绑定类似 :class="{}" 这种格式的数据,然后经过 Vue 的渲染,就会渲染成多个类名了。
同样,我们在 src/views/TemplateM.vue
:
<template>
<div class="template-m-wrap">
<div class="static" :class="{'active': isActive, 'danger': isDanger}">
默认样式
</div>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
isActive: true, // active 样式
isDanger: false, // 警告样式
};
},
};
</script>
<style lang="scss" scoped>
.active {
color: aqua;
}
.danger {
color: red;
}
</style>
我们还是查看 http://localhost:8080/template_m
:
渲染的结果和上面一样。我们也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:
<template>
<div class="template-m-wrap">
<div class="static" :class="classObj">默认样式</div>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
isActive: true, // active 样式
isDanger: false, // 警告样式
};
},
computed: {
classObj() {
return { active: this.isActive, danger: this.isDanger };
},
},
};
</script>
<style scoped>
.active {
color: aqua;
}
.danger {
color: red;
}
</style>
还是访问 http://localhost:8080/template_m
,我们看到还是同样的效果:
我们可以把一个数组传给 :class
,以应用一个 class 列表:
<template>
<div class="template-m-wrap">
<div class="static" :class="['active', 'danger']">默认样式</div>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
isActive: true, // active 样式
isDanger: false, // 警告样式
};
},
computed: {
},
};
</script>
<style scoped>
.active {
color: aqua;
}
.danger {
color: red;
}
</style>
还是访问 http://localhost:8080/template_m
,我们看到还是同样的效果:
我们同样可以使用三元运算符来绑定 class:
<template>
<div class="template-m-wrap">
<div class="static" :class="[isActive ? 'active' : '', isDanger ? 'danger' : '']">默认样式</div>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
isActive: true, // active 样式
isDanger: false, // 警告样式
};
},
computed: {},
};
</script>
<style scoped>
.active {
color: aqua;
}
.danger {
color: red;
}
</style>
还是访问 http://localhost:8080/template_m
,我们看到还是同样的效果:
我们同样可以使用计算属性来绑定 class:
<template>
<div class="template-m-wrap">
<div class="static" :class="classArr">默认样式</div>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
isActive: true, // active 样式
isDanger: false, // 警告样式
};
},
computed: {
classArr() {
return [
this.isActive ? "active" : "",
this.isDanger ? "danger" : "",
{ danger: this.isDanger },
];
},
},
};
</script>
<style scoped>
.active {
color: aqua;
}
.danger {
color: red;
}
</style>
还是访问 http://localhost:8080/template_m
,我们看到还是同样的效果:
:style
的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:
<template>
<div class="template-m-wrap">
<div class="static" :class="classArr" :style="{'color': activeColor, 'font-size': fontSize + 'px'}">默认样式</div>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
isActive: true, // active 样式
isDanger: false, // 警告样式
activeColor: "red",
fontSize: 30,
};
},
computed: {
classArr() {
return [
this.isActive ? "active" : "",
this.isDanger ? "danger" : "",
{ danger: this.isDanger },
];
},
},
};
</script>
<style scoped>
.active {
color: aqua;
}
.danger {
color: red;
}
</style>
还是访问 http://localhost:8080/template_m
,我们看到字体大小变大了,颜色还是红色:
同样可以绑定一个对象:
<template>
<div class="template-m-wrap">
<div class="static" :class="classArr" :style="styleObj">默认样式</div>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
isActive: true, // active 样式
isDanger: false, // 警告样式
activeColor: "red",
fontSize: 30,
};
},
computed: {
classArr() {
return [
this.isActive ? "active" : "",
this.isDanger ? "danger" : "",
{ danger: this.isDanger },
];
},
styleObj() {
return { color: this.activeColor, "font-size": this.fontSize + "px" };
},
},
};
</script>
<style scoped>
.active {
color: aqua;
}
.danger {
color: red;
}
</style>
还是访问 http://localhost:8080/template_m
,我们看到字体大小变大了,颜色还是红色:
:style
的数组语法可以将多个样式对象应用到同一个元素上:
<template>
<div class="template-m-wrap">
<div class="static" :class="classArr" :style="styleArr">默认样式</div>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
isActive: true, // active 样式
isDanger: false, // 警告样式
activeColor: "red",
fontSize: 30,
};
},
computed: {
classArr() {
return [
this.isActive ? "active" : "",
this.isDanger ? "danger" : "",
{ danger: this.isDanger },
];
},
styleArr() {
return [{ color: this.activeColor }, { "font-size": this.fontSize + "px" }];
},
},
};
</script>
<style scoped>
.active {
color: aqua;
}
.danger {
color: red;
}
</style>
还是访问 http://localhost:8080/template_m
,我们看到字体大小变大了,颜色还是红色:
可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:
<template>
<div class="template-m-wrap">
<div class="static" :class="classArr" :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">默认样式</div>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
isActive: true, // active 样式
isDanger: false, // 警告样式
activeColor: "red",
fontSize: 30,
};
},
computed: {
classArr() {
return [
this.isActive ? "active" : "",
this.isDanger ? "danger" : "",
{ danger: this.isDanger },
];
},
},
};
</script>
<style scoped>
.active {
color: aqua;
}
.danger {
color: red;
}
</style>
这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex
。