一、Vue样式绑定
在Vue中,我们可以通过多种方式动态地绑定样式,让界面根据数据状态变化而自动更新样式。
1. class样式绑定
(1) 字符串写法
适用场景:样式的类名不确定,需要动态指定
<template>
<div>
<!-- 绑定class样式--字符串写法 -->
<div class="basic" v-bind:class="styleDyn" @click="changeStyle">{{name}}</div>
</div>
</template>
<script>
export default {
data() {
return {
name: 'Vue样式绑定示例',
styleDyn: 'normal'
}
},
methods: {
changeStyle() {
this.styleDyn = this.styleDyn === 'normal' ? 'active' : 'normal';
}
}
}
</script>
<style>
.basic {
width: 200px;
height: 50px;
line-height: 50px;
text-align: center;
border: 1px solid #ccc;
margin-bottom: 10px;
}
.normal {
background-color: #f5f5f5;
color: #333;
}
.active {
background-color: #42b983;
color: white;
font-weight: bold;
}
</style>
解析:
通过
v-bind:class
(可简写为:class
)绑定一个字符串变量点击div时,
changeStyle
方法会切换styleDyn
的值样式会在'normal'和'active'之间切换
(2) 数组写法
适用场景:要绑定的样式的个数不确定,名字也不确定
<template>
<div>
<!-- 绑定class样式--数组写法 -->
<div class="basic" :class="arr1">{{name}}</div>
<button @click="addClass">添加样式</button>
<button @click="removeClass">移除样式</button>
</div>
</template>
<script>
export default {
data() {
return {
name: '数组写法示例',
arr1: ['style1', 'style2']
}
},
methods: {
addClass() {
this.arr1.push('style' + (this.arr1.length + 1));
},
removeClass() {
this.arr1.pop();
}
}
}
</script>
<style>
.style1 {
border-radius: 5px;
}
.style2 {
box-shadow: 0 0 5px #999;
}
.style3 {
transform: rotate(5deg);
}
.style4 {
background: linear-gradient(to right, #ff9966, #ff5e62);
}
</style>
解析:
通过数组可以动态添加/移除多个class
点击按钮可以动态修改数组内容,从而改变应用的样式
(3) 对象写法
适用场景:要绑定的样式的个数确定,名字也确定,但要动态决定是否使用
<template>
<div>
<!-- 绑定class样式--对象写法 -->
<div class="basic" :class="obj">{{name}}</div>
<button @click="toggleBold">切换加粗</button>
<button @click="toggleItalic">切换斜体</button>
</div>
</template>
<script>
export default {
data() {
return {
name: '对象写法示例',
obj: {
bold: false,
italic: true,
underline: true
}
}
},
methods: {
toggleBold() {
this.obj.bold = !this.obj.bold;
},
toggleItalic() {
this.obj.italic = !this.obj.italic;
}
}
}
</script>
<style>
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
.underline {
text-decoration: underline;
}
</style>
解析:
对象写法的键是class名,值是布尔值,决定是否应用该class
可以通过修改对象的属性值来动态切换样式
2. 内联样式绑定
(1) 对象写法
<template>
<div>
<!-- 绑定内联style样式--对象写法 -->
<div class="basic" :style="styleObj">{{name}}</div>
<button @click="changeColor">改变颜色</button>
</div>
</template>
<script>
export default {
data() {
return {
name: '内联样式对象写法',
styleObj: {
color: 'blue',
fontSize: '20px',
backgroundColor: '#f0f0f0'
}
}
},
methods: {
changeColor() {
const colors = ['red', 'green', 'blue', 'orange', 'purple'];
this.styleObj.color = colors[Math.floor(Math.random() * colors.length)];
}
}
}
</script>
解析:
样式属性名需要使用驼峰命名法(如
fontSize
而不是font-size
)可以动态修改样式对象的属性值来改变元素样式
(2) 数组写法
<template>
<div>
<!-- 绑定内联style样式--数组写法 -->
<div class="basic" :style="styleArr">{{name}}</div>
</div>
</template>
<script>
export default {
data() {
return {
name: '内联样式数组写法',
styleArr: [
{ color: 'red', fontSize: '18px' },
{ backgroundColor: '#eee', padding: '10px' }
]
}
}
}
</script>
解析:
数组中可以包含多个样式对象,它们会被合并后应用到元素上
适用于需要组合多个样式对象的场景
二、条件渲染
Vue提供了两种条件渲染的方式:v-if
和v-show
1. v-if 系列指令
<template>
<div>
<h2>v-if示例</h2>
<button @click="toggleShow">切换显示</button>
<p v-if="show">这是v-if控制的内容</p>
<p v-else-if="show === null">这是v-else-if控制的内容</p>
<p v-else>这是v-else控制的内容</p>
<template v-if="loginType === 'username'">
<label>用户名</label>
<input placeholder="请输入用户名" key="username-input">
</template>
<template v-else>
<label>邮箱</label>
<input placeholder="请输入邮箱" key="email-input">
</template>
<button @click="toggleLoginType">切换登录方式</button>
</div>
</template>
<script>
export default {
data() {
return {
show: true,
loginType: 'username'
}
},
methods: {
toggleShow() {
if (this.show === true) {
this.show = null;
} else if (this.show === null) {
this.show = false;
} else {
this.show = true;
}
},
toggleLoginType() {
this.loginType = this.loginType === 'username' ? 'email' : 'username';
}
}
}
</script>
特点:
v-if
是真正的条件渲染,元素会被完全销毁和重建v-if
是惰性的,初始条件为假时什么也不做,直到条件变为真才会渲染v-if
可以和v-else-if
、v-else
一起使用,但必须保持结构连续使用
key
可以管理可复用的元素,避免Vue高效复用元素带来的问题
2. v-show 指令
<template>
<div>
<h2>v-show示例</h2>
<button @click="toggleVisible">切换显示</button>
<p v-show="visible">这是v-show控制的内容</p>
<!-- v-show不支持template语法 -->
<div v-show="visible">
<p>v-show只是简单地切换CSS的display属性</p>
<p>无论条件如何,元素始终会被渲染并保留在DOM中</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
visible: true
}
},
methods: {
toggleVisible() {
this.visible = !this.visible;
}
}
}
</script>
特点:
v-show
只是简单地切换元素的display
CSS属性无论初始条件如何,元素始终会被渲染并保留在DOM中
v-show
不支持<template>
元素,也不能和v-else
配合使用
3. v-if vs v-show 对比
特性 | v-if | v-show |
---|---|---|
渲染方式 | 条件为假时不渲染DOM | 总是渲染,只是切换display |
切换开销 | 高(销毁/重建) | 低(只是CSS切换) |
初始渲染开销 | 低(条件为假时) | 高(总是会渲染) |
适用场景 | 切换不频繁 | 频繁切换 |
支持语法 | 支持template和v-else | 不支持template |
选择建议:
如果需要非常频繁地切换,使用
v-show
更好如果在运行时条件很少改变,使用
v-if
更好如果涉及权限控制等一次性判断,优先使用
v-if
三、综合实战示例
<template>
<div>
<h1>Vue样式与条件渲染综合示例</h1>
<!-- 样式绑定 -->
<div class="panel" :class="panelClasses">
<h2>用户信息</h2>
<div v-if="userLoggedIn" class="user-info">
<p>用户名: {{user.name}}</p>
<p>会员等级: {{user.level}}</p>
</div>
<div v-else class="login-prompt">
<p>请先登录查看用户信息</p>
<button @click="login">登录</button>
</div>
</div>
<!-- 条件渲染 -->
<div class="control-panel">
<button @click="toggleTheme">切换主题</button>
<button @click="toggleLoginStatus">切换登录状态</button>
<button @click="toggleWarning">切换警告状态</button>
</div>
<!-- 动态样式 -->
<div :style="warningStyle" v-show="showWarning">
警告:这是一条重要提示信息!
</div>
</div>
</template>
<script>
export default {
data() {
return {
userLoggedIn: false,
showWarning: false,
darkTheme: false,
user: {
name: '张三',
level: '黄金会员'
},
warningStyle: {
padding: '10px',
margin: '10px 0',
borderRadius: '4px',
color: 'white'
}
}
},
computed: {
panelClasses() {
return {
'dark-theme': this.darkTheme,
'logged-in': this.userLoggedIn,
'warning-active': this.showWarning
}
}
},
methods: {
login() {
this.userLoggedIn = true;
this.showWarning = false;
},
toggleTheme() {
this.darkTheme = !this.darkTheme;
this.warningStyle.backgroundColor = this.darkTheme ? '#ff7043' : '#f44336';
},
toggleLoginStatus() {
this.userLoggedIn = !this.userLoggedIn;
},
toggleWarning() {
this.showWarning = !this.showWarning;
}
}
}
</script>
<style>
.panel {
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
margin-bottom: 20px;
transition: all 0.3s ease;
}
.dark-theme {
background-color: #333;
color: #fff;
border-color: #555;
}
.logged-in .user-info {
background-color: #e8f5e9;
padding: 10px;
border-radius: 4px;
}
.dark-theme.logged-in .user-info {
background-color: #1b5e20;
}
.login-prompt {
text-align: center;
padding: 20px;
}
.login-prompt button {
padding: 5px 15px;
background-color: #42b983;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
}
.control-panel {
margin-bottom: 20px;
}
.control-panel button {
margin-right: 10px;
padding: 5px 10px;
cursor: pointer;
}
.warning-active {
border-left: 4px solid #f44336;
}
</style>
解析:
综合使用了class的对象绑定语法,根据多个条件计算class
使用v-if和v-else实现条件渲染
使用v-show控制警告信息的显示/隐藏
动态修改内联样式
展示了不同场景下样式和条件渲染的应用
通过这个综合示例,我们可以看到Vue的样式绑定和条件渲染如何协同工作,创建出动态、响应式的用户界面。