一.使用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绑定控制选中状态

  • 价格显示使用了条件渲染显示不同的文本样式