class与style绑定
绑定HTML class
对象语法
可以给v-bind:class传递一个对象,以动态切换class:
<style>
.active {
width:100px;
height:100px;
background:green;
}
</style>
<div id=‘app‘>
<div v-bind:class="{active:isActive}"></div>
</div>
<script>
const vm = Vue.createApp({
data() {
return {
isActive:true
}
}
}).mount(‘#app‘);
</script>
v-bind:class指令也可以和普通的class属性一起使用:
<style>
.static {
border:solid 2px black;
}
.active {
width:100px;
height:100px;
background:green;
}
.text-danger {
background:red;
}
</style>
<div id=‘app‘>
<div class=‘static‘ v-bind:class="{active:isActive,‘text-danger‘:hasError}"></div>
</div>
<script>
const vm = Vue.createApp({
data() {
return {
isActive:true,
hasError:false
}
}
}).mount(‘#app‘);
</script>
绑定的数据对象如果较为复杂,可以在数据属性中单独定义一个对象,然后绑定它。例如:
<div id=‘app‘>
<div v-bind:class="classObject"></div>
</div>
<script>
const vm = Vue.createApp({
data() {
return {
classObject:{
active:true,
‘text-danger‘:false
}
}
}
}).mount(‘#app‘);
</script>
当然,也可以考虑绑定一个返回对象的计算属性,这是一个非常强大的模式:
<div v-bind:class="classObject"></div>
<script>
const vm = Vue.createApp({
data() {
return {
active:true,
error:null
}
},
computed:{
classObject(){
return {
active:this.isActive && !this.error,
‘text-danger‘:this.error && this.error.type === ‘fatal‘
}
}
}
}).mount(‘#app‘);
</script>
数组语法
除了给v-bind:class传递对象外,也可以传递一个数组,应用一个class列表,例如:
<style>
.active {
width:100px;
height:100px;
background:green;
}
.text-danger {
background:red;
}
</style>
<div id=‘app‘>
<div v-bind:class="[activeClass,errorClass]"></div>
</div>
<script>
const vm = Vue.createApp({
data() {
return {
activeClass:‘active‘,
errorClass:‘text-danger‘
}
}
}).mount(‘#app‘);
</script>
也可以用三元表达式根据条件切换class:
<div v-bind:class="[isActive ? activeClass: ‘‘,errorClass]"></div>
</div>
<script>
const vm = Vue.createApp({
data() {
return {
activeClass:‘active‘,
errorClass:‘text-danger‘,
isActive:true
}
}
}).mount(‘#app‘);
</script>
当class属性的表达式中有多个条件这样写比较烦琐,因而可以在数组语法中使用对象语法来简化表达式:
<div v-bind:clas=‘[{active:isActive},errorClass]‘></div>
在组件上使用class属性
当在一个具有单个根元素的自定义组件上使用class属性时,这些class将被添加到该组件的根元素上。这个元素上已经存在的class不会被覆盖。
例如,声明了以下组件:
const app = Vue.createApp({})
app.component(‘my-component‘,{
template:`<p class="foo bar">Hi!</p>`
})
然后在使用该组件时添加一些class:
<my-component class="baz boo"></my-component>
HTML将被渲染为:
<p class="foo bar baz boo">Hi</p>
对于带数据绑定class也适用:
<my-component v-bind:class=‘{active:isActive}‘></my-component>
如果组件有多个根元素,则需要定义哪个根元素来接收这个class,这是通过使用$attrs组件属性来指定的。
<div id=‘app‘>
<my-component class="baz"></my-component>
</div>
const app = Vue.createApp({})
app.component(‘my-component‘,{
template:`
<p class="$attrs.class">Hi!</p>
<span>This is a child component</span>`
})
绑定内联样式
对象语法
v-bind:style的对象语法非常像HTML的内联css样式,但其实是一个js对象。
<div id=‘app‘>
<div v-bind:style=‘{color:activeColor,fontSize:fontSize+"px"}‘>aaaaa</div>
</div>
<script>
const vm = Vue.createApp({
data() {
return {
activeColor:‘red‘,
fontSize:30
}
}
}).mount(‘#app‘);
</script>
显然直接以对象字面量的方式设置css样式代码冗长,可以定义一个样式对象:
<div id=‘app‘>
<div v-bind:style=‘styleObject‘>aaaaa</div>
</div>
<script>
const vm = Vue.createApp({
data() {
return {
styleObject:{
color:‘red‘,
fontSize:‘30px‘
}
}
}
}).mount(‘#app‘);
</script>
数组语法
<div id=‘app‘>
<div v-bind:style=‘[baseStyles,moreStyles]‘>aaaaa</div>
</div>
<script>
const vm = Vue.createApp({
data() {
return {
baseStyles:{
border:‘solid 2px black‘
}
moreStyles:{
color:‘red‘,
fontSize:‘30px‘
}
}
}
}).mount(‘#app‘);
</script>
多重值
可以为绑定的style属性提供一个包含多个值的数组,这常用于提供多个带前缀的值。
<div :style="{ display:[‘-webkit-box‘,‘-ms-flexbox‘,‘flex‘]}"></div>
这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的flexbox,那么就只会渲染display:flex。
实例:表格奇偶行应用不同的样式
首先定义一个针对偶数行的样式规则:
.even {
background-color:#cdcdcd;
}
表格数据采用v-for指令循环输出,v-for指令可以带一个索引参数,因此可以根据这个索引参数判断奇偶行,循环索引是从0开始,对应的是第一行,为了判断简便,将其加1后再进行判断。判断规则为(index+1)%2===0:
<tr v-for="(book,index) in books" :key="book.id" :class="{even:(index+1)%2===0}">...</tr>
全部的代码:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
body {
width: 600px;
}
table {
border: 1px solid black;
}
table {
width: 100%;
}
th {
height: 50px;
}
th, td {
border-bottom: 1px solid #ddd;
text-align: center;
}
[v-cloak] {
display: none;
}
.even {
background-color: #cdcdcd;
}
</style>
</head>
<body>
<div id = "app" v-cloak>
<table>
<tr>
<th>序号</th>
<th>书名</th>
<th>作者</th>
<th>价格</th>
<th>操作</th>
</tr>
<tr v-for="(book, index) in books"
:key="book.id" :class="{even : (index+1) % 2 === 0}">
<td>{{ book.id }}</td>
<td>{{ book.title }}</td>
<td>{{ book.author }}</td>
<td>{{ book.price }}</td>
<td>
<button @click="deleteItem(index)">删除</button>
</td>
</tr>
</table>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const vm = Vue.createApp({
data() {
return {
books: [
{
id: 1,
title: ‘Java无难事‘,
author: ‘孙鑫‘,
price: 188
},
{
id: 2,
title: ‘VC++深入详解‘,
author: ‘孙鑫‘,
price: 168
},
{
id: 3,
title: ‘Servlet/JSP深入详解‘,
author: ‘孙鑫‘,
price: 139
},
{
id: 4,
title: ‘Vue.js从入门到实战‘,
author: ‘孙鑫‘,
price: 89.8
}
]
}
},
methods: {
deleteItem(index){
this.books.splice(index, 1);
}
}
}).mount(‘#app‘);
</script>
</body>
</html>