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>
posted @ 2021-08-13 21:01  KKKyrie  阅读(61)  评论(0编辑  收藏  举报