Vue中控制样式变化的几种常用方法
一.使用class绑定
<!-- 通过布尔值控制类名 -->
<view class="tab-item" :class="{'active': isActive}">
<!-- 多个条件类名 -->
<view class="btn" :class="{
'active': isActive,
'disabled': isDisabled,
'highlight': isHighlight
}">
二、使用style样式绑定
class绑定有的时候会失效,这个时候使用style样式绑定
<!-- 直接绑定样式对象 -->
<view :style="{
background: isActive ? '#1296DB' : '#CCCCCC',
color: isDisabled ? '#999' : '#333'
}">
<!-- 通过计算属性返回样式对象 -->
<view :style="buttonStyle">
computed: {
buttonStyle() {
return {
background: this.isActive ? '#1296DB' : '#CCCCCC',
opacity: this.isDisabled ? 0.5 : 1
}
}
}
三、使用计算属性返回类名
<view :class="tabClass">
computed: {
tabClass() {
return {
'tab-item': true,
'active': this.currentTab === 'menu',
'disabled': this.isDisabled
}
}
}
四、通过数据状态控制样式(比如购物车)
<!-- 通过count值控制显示不同的按钮 -->
<view class="quantity-control" v-if="item.count > 0">
<view class="minus-btn">-</view>
<text>{{item.count}}</text>
<view class="add-btn">+</view>
</view>
<view class="add-btn" v-else>+</view>
五、使用CSS变量动态改变样式
<template>
<view :style="{'--theme-color': themeColor}">
</template>
<style>
.button {
background: var(--theme-color);
}
</style>
<script>
data() {
return {
themeColor: '#1296DB'
}
}
</script>
六、条件渲染不同的组件样式
<template>
<view class="price-info">
<text v-if="totalPrice > 0" class="total-price">¥{{totalPrice}}</text>
<text v-else class="empty-tip">未选购商品</text>
</view>
</template>
七、例子与总结
<template>
<view class="food-detail">
<!-- 顶部导航栏 -->
<view class="header">
<view class="nav-bar">
<view class="back" @click="goBack">
<u-icon name="arrow-left" color="#FFFFFF" size="20"></u-icon>
</view>
<view class="search-box" @click="goToSearch">
<u-search
v-model="keyword"
:show-action="false"
placeholder="看看想吃什么"
disabled
height="64rpx"
></u-search>
</view>
<view class="right-icons">
<u-icon name="more-dot-fill" color="#FFFFFF" size="20"></u-icon>
</view>
</view>
</view>
<!-- 顶部广告轮播图 -->
<swiper class="banner" :indicator-dots="true" :autoplay="true" interval="3000" duration="1000">
<swiper-item>
<image src="/static/food/banner.jpg" mode="aspectFill" class="banner-image"></image>
</swiper-item>
</swiper>
<!-- 店铺基本信息 -->
<view class="shop-info">
<view class="shop-basic">
<image class="shop-logo" src="/static/food/hotpot.jpg" mode="aspectFill"></image>
<view class="shop-content">
<view class="shop-name">超级好吃的火锅</view>
<view class="shop-meta">
<text>月售400+</text>
<text class="divider">|</text>
<text>商家自配</text>
<text class="divider">|</text>
<text>约99分钟</text>
</view>
<view class="shop-rank">好评榜第1名</view>
</view>
</view>
</view>
<!-- 配送方式 -->
<view class="delivery-btns">
<view class="btn-left active">外送</view>
<view class="btn-right">
<text>自取</text>
<text class="distance">距您6m</text>
</view>
</view>
<!-- 菜单内容区 -->
<view class="menu-container">
<!-- 顶部导航标签 -->
<view class="menu-tabs">
<view class="tab-item active">
<text>点餐</text>
<view class="tab-line"></view>
</view>
<view class="tab-item">评价 99+</view>
<view class="tab-item">商家公益商家</view>
</view>
<!-- 内容区域 -->
<view class="menu-content">
<!-- 左侧分类列表 -->
<scroll-view class="category-list" scroll-y>
<view class="category-item active">
<u-icon name="checkmark-circle" color="#4CD964" size="16"></u-icon>
<text>推荐</text>
</view>
<view class="category-item">
<view class="fire-wrapper">
<text class="fire">🔥</text>
<text class="fire">🔥</text>
<text class="fire">🔥</text>
</view>
<text>超值套餐</text>
</view>
</scroll-view>
<!-- 右侧商品列表 -->
<scroll-view class="goods-list" scroll-y>
<view class="goods-item" v-for="(item, index) in menuList" :key="index">
<image class="goods-image" :src="item.image" mode="aspectFill"></image>
<view class="goods-info">
<view class="goods-name">{{item.name}}</view>
<view class="goods-sales">月售99+</view>
<view class="goods-price">
<text class="price">¥{{item.price}}</text>
<view class="quantity-control" v-if="item.count > 0">
<view class="minus-btn" @click="decreaseCount(index)">-</view>
<text class="count">{{item.count}}</text>
<view class="add-btn" @click="increaseCount(index)">+</view>
</view>
<view class="add-btn" v-else @click="increaseCount(index)">+</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
<!-- 底部购物车栏 -->
<view class="cart-bar">
<view class="cart-info">
<view class="cart-icon">
<u-icon name="shopping-cart" color="#FFFFFF" size="40"></u-icon>
<view class="cart-badge" v-if="totalCount > 0">{{totalCount}}</view>
</view>
<view class="price-info">
<text class="total-price" v-if="totalPrice > 0">¥{{totalPrice}}</text>
<text class="empty-tip" v-else>未选购商品</text>
</view>
</view>
<view
class="checkout-btn"
:style="totalPrice > 0 ? 'background: #1296DB;' : 'background: #CCCCCC;'"
@click="goToCheckout"
>
去下单
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
id: null,
currentTab: 'menu',
keyword: '', // 添加搜索关键词
menuList: [
{
name: '超值套餐A',
desc: '含:火锅底料、肥牛、虾滑、青菜',
price: '0.99',
image: '/static/food/hotpot.jpg',
count: 0
},
{
name: '超值套餐B',
desc: '含:火锅底料、毛肚、虾滑、青菜',
price: '0.99',
image: '/static/food/hotpot.jpg',
count: 0
},
{
name: '超值套餐C',
desc: '含:火锅底料、羊肉、虾滑、青菜',
price: '0.99',
image: '/static/food/hotpot.jpg',
count: 0
}
]
}
},
computed: {
totalCount() {
return this.menuList.reduce((sum, item) => sum + (item.count || 0), 0)
},
totalPrice() {
return this.menuList.reduce((sum, item) => sum + item.price * (item.count || 0), 0).toFixed(2)
}
},
onLoad(options) {
if (options.id) {
this.id = options.id;
this.getDetailData();
}
},
methods: {
goBack() {
uni.navigateBack()
},
switchTab(tab) {
this.currentTab = tab
},
getDetailData() {
console.log('获取详情数据,id:', this.id);
},
goToSearch() {
uni.navigateTo({
url: '/pages/food/foodSearch'
})
},
increaseCount(index) {
if (typeof this.menuList[index].count === 'undefined') {
this.$set(this.menuList[index], 'count', 0);
}
this.menuList[index].count++;
},
decreaseCount(index) {
if (this.menuList[index].count > 0) {
this.menuList[index].count--;
}
},
goToCheckout() {
if (this.totalPrice > 0) {
uni.navigateTo({
url: '/pages/order/checkout'
})
}
}
}
}
</script>
<style scoped>
.food-detail {
min-height: 100vh;
background: #F5F5F5;
padding-top: 180rpx;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 99;
background: #1296DB;
padding-top: 120rpx;
}
.nav-bar {
display: flex;
align-items: center;
padding: 20rpx 30rpx;
}
.back {
margin-right: 20rpx;
}
.search-box {
flex: 1;
margin: 0 20rpx;
}
.right-icons {
margin-left: 20rpx;
}
.shop-info {
background: #FFFFFF;
padding: 30rpx;
}
.shop-basic {
display: flex;
align-items: flex-start;
}
.shop-logo {
width: 120rpx;
height: 120rpx;
border-radius: 8rpx;
margin-right: 20rpx;
}
.shop-content {
flex: 1;
}
.shop-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.shop-meta {
font-size: 24rpx;
color: #666;
margin-bottom: 8rpx;
}
.divider {
margin: 0 10rpx;
color: #EEEEEE;
}
.shop-rank {
font-size: 24rpx;
color: #FF6B00;
}
.delivery-btns {
display: flex;
height: 88rpx;
margin: 20rpx;
border-radius: 44rpx;
overflow: hidden;
background: #469FFF;
}
.btn-left, .btn-right {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #1b1313;
background: #DEEEFF;
}
.btn-left {
border-top-left-radius: 44rpx;
border-bottom-left-radius: 44rpx;
}
.btn-right {
border-top-right-radius: 44rpx;
border-bottom-right-radius: 44rpx;
display: flex;
flex-direction: column;
gap: 4rpx;
}
.btn-left.active {
background: #1296DB;
color: #FFFFFF;
}
.distance {
font-size: 24rpx;
color: #999;
}
.menu-container {
display: flex;
flex-direction: column;
height: calc(100vh - 400rpx);
background: #FFFFFF;
}
.menu-tabs {
display: flex;
height: 88rpx;
background: #FFFFFF;
border-bottom: 1rpx solid #EEEEEE;
}
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #666;
position: relative;
background: transparent !important;
}
.tab-item.active {
color: #333;
background: #F5F5F5;
background: transparent !important;
}
.tab-line {
position: absolute;
bottom: 0;
width: 40rpx;
height: 4rpx;
background: #1296DB;
border-radius: 2rpx;
}
.menu-content {
flex: 1;
display: flex;
}
.category-list {
width: 160rpx;
background: #F5F5F5;
}
.category-item {
padding: 20rpx;
font-size: 28rpx;
color: #666;
display: flex;
flex-direction: column;
align-items: center;
gap: 8rpx;
background: transparent !important;
}
.category-item.active {
color: #333;
background: transparent !important;
}
.fire-wrapper {
display: flex;
}
.fire {
font-size: 24rpx;
}
.goods-list {
flex: 1;
background: #FFFFFF;
padding: 20rpx;
}
.goods-item {
padding: 20rpx;
display: flex;
border-bottom: 1rpx solid #EEEEEE;
}
.goods-image {
width: 140rpx;
height: 140rpx;
border-radius: 8rpx;
margin-right: 20rpx;
}
.goods-info {
flex: 1;
}
.goods-name {
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
}
.goods-sales {
font-size: 24rpx;
color: #999;
margin-bottom: 20rpx;
}
.goods-price {
display: flex;
justify-content: space-between;
align-items: center;
}
.price {
font-size: 32rpx;
color: #FF6B00;
}
.quantity-control {
display: flex;
align-items: center;
}
.minus-btn, .add-btn {
width: 44rpx;
height: 44rpx;
background: #1296DB;
border-radius: 50%;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
}
.count {
margin: 0 20rpx;
font-size: 28rpx;
color: #333;
}
.banner {
width: 100%;
height: 300rpx;
}
.banner-image {
width: 100%;
height: 100%;
}
.cart-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100rpx;
background: #FFFFFF;
display: flex;
align-items: center;
padding: 0 30rpx;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.cart-info {
flex: 1;
display: flex;
align-items: center;
}
.cart-icon {
width: 80rpx;
height: 80rpx;
background: #1296DB;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
margin-right: 20rpx;
}
.cart-badge {
position: absolute;
top: -8rpx;
right: -8rpx;
background: #FF6B00;
color: #FFFFFF;
font-size: 24rpx;
padding: 0 12rpx;
border-radius: 20rpx;
min-width: 32rpx;
text-align: center;
}
.price-info {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.total-price {
font-size: 36rpx;
color: #FF6B00;
font-weight: bold;
}
.empty-tip {
font-size: 28rpx;
color: #999;
}
.checkout-btn {
width: 200rpx;
height: 80rpx;
color: #FFFFFF;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
}
</style>
购物车按钮使用了style绑定控制背景色
商品数量使用了条件渲染显示不同的按钮组合
标签页使用了class绑定控制选中状态
价格显示使用了条件渲染显示不同的文本样式
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员小刘
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果