1. 程式人生 > 其它 >class與style繫結

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>