class與style繫結
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>