普通视图

发现新文章,点击刷新页面。
今天 — 2026年4月20日首页

英特尔14A工艺整装待发,瑞银猜测其客户或包括英伟达及苹果等

2026年4月20日 15:23
有消息称,英特尔即将推出的14A工艺技术,将在今年年底吸引一些知名企业客户的加入。瑞银猜测,英特尔新技术的客户将包括英伟达、苹果、谷歌和AMD。瑞银还强调了英特尔与马斯克Terafab项目相关的另一种发展可能。英特尔有可能将其位于俄亥俄州的晶圆厂与Terafab合并,此举将进一步提升英特尔的晶圆代工声誉。(新浪财经)

机构:2026年Q1 RGB-Mini LED电视月销增2倍

2026年4月20日 15:20
36氪获悉,据奥维云网(AVC)全渠道最新监测数据显示,2026年一季度,国内RGB-Mini LED电视迎来爆发式增长,月均销量达到2025年3月后月均销量的329%。其中,海信销量份额为79.4%。

华友钴业陈红良:企业已拿到精矿出口相关批文,在途周期约3个月

2026年4月20日 15:17
在华友钴业2025年度暨2026年第一季度业绩暨现金分红说明会上,公司总裁陈红良表示,目前各家在津巴布韦布局锂资源的企业拿到了锂精矿出口相关批文,具体都在走流程中。华友钴业在津巴布韦主要有锂精矿、硫酸锂两类产品。出口程序全部完整后,到国内周期约需3个月。公司广西碳酸锂原料可能面临短缺,主要是物流情况,但不会造成重大影响。(财联社)

北京一季度GDP同比增长5.9%

2026年4月20日 15:16
2026年一季度北京经济运行情况新闻发布会召开,北京市统计局、国家统计局北京调查总队亮出一季度北京经济成绩单。按不变价格计算,一季度,北京市地区生产总值同比增长5.9%,经济实现良好开局。(财联社)

uni-app 全能日历组件,支持农历、酒店预订、打卡签到、价格日历多种场景

2026年4月20日 15:15

一、uView Pro 的 Calendar 组件

在 uni-app 开发中,日期选择是一个高频需求场景。无论是酒店预订的入住离店时间选择、电商平台的商品预约、还是日常应用的打卡签到,一个功能完善、体验优秀的日历组件都是必不可少的。

uView Pro 作为 uni-app 生态中备受关注的 Vue3 组件库,其 Calendar 日历组件 经过了多个版本的迭代优化,从最初的基础日期选择,逐步演进为支持农历显示、打卡签到、节假日标记、自定义价格日历等丰富功能的综合型组件。

本文将深入解析 uView Pro Calendar 组件的核心特性、实现原理以及实际应用场景,帮助你快速掌握这个强大的日期选择利器。

二、组件概览:功能特性总览

0.png

uView Pro 的 Calendar 日历组件具有以下核心特性:

基础功能

  • ✅ 支持单日期选择和日期范围选择两种模式
  • ✅ 底部弹窗和页面嵌入两种展示方式
  • ✅ 年月切换导航,支持自定义年份范围
  • ✅ 日期范围限制,防止选择无效日期

进阶功能

  • ✅ 农历显示支持,自动计算农历日期
  • ✅ 打卡签到模式,支持已打卡/未打卡状态展示
  • ✅ 节假日和加班日标记,显示"休"/"班"标识
  • ✅ 内置中国传统节日,支持自定义节日配置
  • ✅ 自定义日期内容插槽,适用于价格日历等场景

交互优化

  • ✅ 默认选中今天,支持指定默认日期
  • ✅ 只读模式,禁止日期选择
  • ✅ 选中效果可配置,适应不同视觉需求

三、基础使用:快速上手

3.1 单日期选择模式

单日期选择是最常用的场景,比如选择生日、预约日期等。

1.png

<template>
    <view>
        <u-calendar v-model="show" mode="date" @change="onChange"></u-calendar>
        <u-button @click="show = true">选择日期</u-button>
    </view>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import type { CalendarChangeDate } from 'uview-pro/types/global'

const show = ref(false)

function onChange(e: CalendarChangeDate) {
    console.log('选择的日期:', e.result)
    console.log('星期:', e.week)
    console.log('是否今天:', e.isToday)
}
</script>

回调参数说明:

属性 说明 类型
year 选择的年份 number
month 选择的月份 number
day 选择的日期 number
result 格式化的日期字符串,如 "2024-06-15" string
week 星期文字,如 "星期六" string
isToday 是否选择了今天 boolean

3.2 日期范围选择模式

范围选择适用于酒店预订、行程规划等需要起止时间的场景。

2.png

<template>
    <u-calendar 
        v-model="show" 
        mode="range" 
        start-text="入住"
        end-text="离店"
        @change="onRangeChange"
    >
        <template #tooltip>
            <view class="tip">请选择入住和离店时间</view>
        </template>
    </u-calendar>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import type { CalendarChangeRange } from 'uview-pro/types/global'

const show = ref(false)

function onRangeChange(e: CalendarChangeRange) {
    console.log('入住日期:', e.startDate)
    console.log('离店日期:', e.endDate)
    console.log('共', e.endDay - e.startDay + 1, '晚')
}
</script>

范围模式回调参数:

属性 说明
startDate / endDate 起始/结束日期字符串
startYear / endYear 起始/结束年份
startMonth / endMonth 起始/结束月份
startDay / endDay 起始/结束日期
startWeek / endWeek 起始/结束星期

四、进阶功能详解

4.1 农历显示

Calendar 组件内置了农历计算功能,开启后会自动显示农历日期。

6.png

<u-calendar 
    v-model="show" 
    mode="date" 
    :show-lunar="true"
    @change="onLunarChange"
></u-calendar>

开启农历后,回调参数会增加 lunar 对象:

{
    day: 15,
    month: 6,
    result: "2024-06-15",
    lunar: {
        dayCn: '初十',      // 农历日
        monthCn: '五月',    // 农历月
        year: 2024,         // 农历年
        weekCn: "星期六"    // 农历星期
    }
}

农历显示会自动处理闰月、大小月等复杂逻辑,无需开发者关心底层实现。

4.2 页面嵌入模式

除了弹窗模式,组件还支持直接嵌入页面显示,适用于需要常驻展示日历的场景。

<template>
    <view class="calendar-page">
        <u-calendar 
            :is-page="true" 
            mode="date"
            @change="onChange"
        ></u-calendar>
    </view>
</template>

页面模式的特点:

  • 不显示弹窗和确定按钮
  • 选择日期后自动触发 change 事件
  • 支持所有其他功能(农历、打卡、节假日等)

7.png

4.3 打卡签到模式

打卡签到日历也是近期咨询我比较多的功能,Calendar 组件专门为此设计了打卡模式。

3.png

<template>
    <u-calendar
        :is-page="true"
        :checkin-mode="true"
        :checked-dates="checkedDates"
        :today-checked="todayChecked"
    ></u-calendar>
</template>

<script setup>
import { ref } from 'vue'

// 已打卡日期列表
const checkedDates = ref([
    '2024-01-01', 
    '2024-01-02', 
    '2024-01-03',
    '2024-01-05'
])

// 今日打卡状态(优先级高于自动判断)
const todayChecked = ref(true)
</script>

打卡模式的显示规则:

  1. 今日已打卡:绿色圆形背景,显示白色对勾
  2. 其他已打卡日期:橙色圆形背景,显示日期
  3. 未打卡日期checkin-mode 为 true 时):灰色圆形背景

颜色自定义:

属性 说明 默认值
checked-bg-color 已打卡日期背景色 橙色(warning)
today-checked-bg-color 今日已打卡背景色 绿色(success)
unchecked-bg-color 未打卡日期背景色 灰色(light)

4.4 节假日与加班日标记

组件支持显示节假日和加班日标记,方便用户了解日期属性。

<template>
    <u-calendar
        :is-page="true"
        :holidays="holidays"
        :workdays="workdays"
    ></u-calendar>
</template>

<script setup>
import { ref } from 'vue'

// 节假日(元旦假期)
const holidays = ref(['2024-01-01', '2024-01-02'])

// 加班日(调休上班)
const workdays = ref(['2024-01-06', '2024-01-07'])
</script>

显示效果:

  • 节假日:日期右上角显示红色"休"字
  • 加班日:日期右上角显示蓝色"班"字
  • 选中状态下,"休"/"班"字变为白色

4.png

4.5 节日显示

组件内置了中国传统节日,同时支持自定义节日配置。

内置节日(show-festival 为 true 时自动显示):

  • 元旦(1月1日)
  • 情人节(2月14日)
  • 妇女节(3月8日)
  • 植树节(3月12日)
  • 愚人节(4月1日)
  • 劳动节(5月1日)
  • 青年节(5月4日)
  • 儿童节(6月1日)
  • 建党节(7月1日)
  • 建军节(8月1日)
  • 教师节(9月10日)
  • 国庆节(10月1日)
  • 光棍节(11月11日)
  • 圣诞节(12月25日)

自定义节日:

<template>
    <u-calendar
        :is-page="true"
        :show-festival="true"
        :festivals="customFestivals"
    ></u-calendar>
</template>

<script setup>
import { ref } from 'vue'

const customFestivals = ref({
    // 每年固定节日(MM-DD 格式)
    '04-04': '清明节',
    '05-05': '端午节',
    '08-15': '中秋节',
    
    // 特定年份节日(YYYY-MM-DD 格式)- 优先级更高
    '2025-04-04': '清明节(2025)',
    
    // 覆盖内置节日(传入空字符串不显示)
    '02-14': '',
})
</script>

优先级规则:

  1. 特定年份格式(YYYY-MM-DD)优先级最高
  2. 每年固定格式(MM-DD)次之
  3. 内置节日优先级最低

4.6 自定义日期内容:价格日历

通过 date 插槽,可以完全自定义每个日期的显示内容,常用于电商价格日历场景。

5.png

<template>
    <u-calendar 
        :is-page="true" 
        mode="date"
        :use-date-slot="true"
    >
        <template #date="{ date }">
            <text :class="getPriceClass(date)">
                {{ getPriceText(date) }}
            </text>
        </template>
    </u-calendar>
</template>

<script setup>
import { ref } from 'vue'

// 价格数据
const priceMap = ref({
    '2024-01-01': 299,
    '2024-01-02': 399,
    '2024-01-03': 359,
    // ...
})

function getPriceText(date) {
    if (date.isToday) return '今天'
    const price = priceMap.value[date.date]
    return price ? ${price}` : ''
}

function getPriceClass(date) {
    if (date.isSelected) return 'price-selected'
    if (date.isToday) return 'price-today'
    return 'price-normal'
}
</script>

<style scoped>
.price-today {
    color: #19be6b;
    font-weight: bold;
}
.price-normal {
    color: #909399;
    font-size: 22rpx;
}
.price-selected {
    color: #ffffff;
}
</style>

插槽作用域参数:

属性 说明 类型
date.year 年份 number
date.month 月份 number
date.day 日期 number
date.date 完整日期字符串 string
date.week 星期文字 string
date.isToday 是否今天 boolean
date.isHoliday 是否节假日 boolean
date.isWorkday 是否加班日 boolean
date.isChecked 是否已打卡 boolean
date.isSelected 是否选中 boolean
date.lunar 农历信息 object

五、核心实现原理浅析

5.1 日历渲染逻辑

Calendar 组件的日历渲染基于以下核心算法:

// 获取某月天数
function getMonthDay(year: number, month: number) {
    return new Date(year, month, 0).getDate()
}

// 获取某月第一天星期几(0-6)
function getWeekday(year: number, month: number) {
    let date = new Date(`${year}/${month}/01 00:00:00`)
    return date.getDay()
}

渲染流程:

  1. 计算当月第一天是星期几,生成前置空白格子
  2. 计算当月总天数,生成日期格子
  3. 根据选中状态计算每个格子的样式
  4. 如果有农历,调用农历转换库计算农历日期

5.2 农历计算

组件使用了独立的农历计算工具 Calendar.solar2lunar,将公历日期转换为农历:

function getLunar(year: any, month: any, day: any) {
    const val = Calendar.solar2lunar(year, month, day)
    return {
        dayCn: val.IDayCn,      // 农历日(初十、廿三等)
        monthCn: val.IMonthCn,  // 农历月(正月、五月等)
        weekCn: val.ncWeek,     // 农历星期
        day: val.lDay,          // 农历日数字
        month: val.lMonth,      // 农历月数字
        year: val.lYear         // 农历年
    }
}

5.3 范围选择逻辑

范围选择采用两次点击确定起止时间的交互方式:

function dateClick(dayIdx: number) {
    const d = dayIdx + 1
    const date = `${year.value}-${month.value}-${d}`
    
    if (props.mode == 'range') {
        // 判断是设置开始日期还是结束日期
        const compare = new Date(date).getTime() < new Date(startDate.value).getTime()
        
        if (isStart.value || compare) {
            // 设置开始日期
            startDate.value = date
            isStart.value = false
        } else {
            // 设置结束日期
            endDate.value = date
            isStart.value = true
            // 触发回调
            if (props.isPage) btnFix(true)
        }
    }
}

六、实际应用场景

6.1 酒店预订日历

<u-calendar 
    v-model="show" 
    mode="range"
    start-text="入住"
    end-text="离店"
    :min-date="minDate"
    :max-date="maxDate"
    @change="onDateChange"
>
    <template #tooltip>
        <view class="hotel-tip">
            <text>请选择入住和离店日期</text>
            <text class="sub">入住时间14:00后,离店时间12:00前</text>
        </view>
    </template>
</u-calendar>

6.2 健身打卡应用

<u-calendar
    :is-page="true"
    :checkin-mode="true"
    :checked-dates="monthCheckins"
    :today-checked="todayChecked"
    :show-lunar="true"
    @change="onCheckin"
></u-calendar>

6.3 航班价格日历

<u-calendar 
    :is-page="true"
    mode="date"
    :use-date-slot="true"
    :default-select-today="false"
    :is-active-current="false"
>
    <template #date="{ date }">
        <view class="flight-price">
            <text class="day">{{ date.day }}</text>
            <text class="price" v-if="getPrice(date.date)">
                ¥{{ getPrice(date.date) }}
            </text>
        </view>
    </template>
</u-calendar>

6.4 日程管理应用

<u-calendar
    :is-page="true"
    :show-festival="true"
    :festivals="customFestivals"
    :holidays="holidays"
    :workdays="workdays"
    :default-date="selectedDate"
    @change="onSelectDate"
></u-calendar>

七、API 完整参考

Props 属性

参数 说明 类型 默认值
v-model 控制弹窗显示/隐藏 boolean false
mode 选择模式:date 单选 / range 范围 string date
is-page 是否在页面中直接显示 boolean false
show-lunar 是否显示农历 boolean false
readonly 是否只读 boolean false
default-date 默认选中日期(单选模式) string -
start-date 默认开始日期(范围模式) string -
end-date 默认结束日期(范围模式) string -
default-select-today 默认选中今天 boolean true
min-date 最小可选日期 string 1950-01-01
max-date 最大可选日期 string 今天
min-year 最小可选年份 number/string 1950
max-year 最大可选年份 number/string 2050
change-year 是否显示年份切换按钮 boolean true
change-month 是否显示月份切换按钮 boolean true
active-bg-color 选中日期背景色 string 主题色
active-color 选中日期文字颜色 string 白色
range-bg-color 范围内日期背景色 string 主题色浅
range-color 范围内日期文字颜色 string 主题色
start-text 开始日期提示文字 string 开始
end-text 结束日期提示文字 string 结束
tool-tip 顶部提示文字 string 选择日期
closeable 是否显示关闭图标 boolean true
mask-close-able 点击遮罩是否关闭 boolean true
safe-area-inset-bottom 底部安全区适配 boolean false
border-radius 弹窗圆角 number/string 20
z-index 弹窗层级 number/string 10075
is-active-current 选中日期是否高亮 boolean true
checkin-mode 是否启用打卡模式 boolean false
checked-dates 已打卡日期列表 array []
today-checked 今日是否已打卡 boolean false
checked-bg-color 已打卡背景色 string 橙色
today-checked-bg-color 今日已打卡背景色 string 绿色
unchecked-bg-color 未打卡背景色 string 灰色
holidays 节假日列表 array []
workdays 加班日列表 array []
holiday-color 节假日文字颜色 string 红色
workday-color 加班日文字颜色 string 蓝色
show-festival 是否显示内置节日 boolean false
festivals 自定义节日配置 object {}
festival-color 节日文字颜色 string 主题色
use-date-slot 是否启用日期插槽 boolean false

Events 事件

事件名 说明 回调参数
change 日期选择完成时触发 CalendarChangeDate / CalendarChangeRange

Slots 插槽

名称 说明
tooltip 自定义顶部提示内容
date 自定义日期内容(作用域插槽)

更多功能及用法参考 uView Pro 官方文档 uviewpro.cn

八、总结

uView Pro 的 Calendar 日历组件是一个功能全面、设计精良的日期选择解决方案。从基础的单日期选择到复杂的打卡签到、价格日历,这些都能轻松应对。

使用建议:

  1. 选择合适的展示模式:弹窗模式适合临时选择,页面模式适合常驻展示
  2. 合理利用默认选中:通过 default-datedefault-select-today 提升用户体验
  3. 注意日期格式:所有日期参数统一使用 YYYY-MM-DD 格式
  4. 自定义插槽优先级:使用 date 插槽时会覆盖农历、节日等默认显示
  5. 打卡模式注意today-checked 优先级高于 checkedDates 的自动判断

功能使用建议:

  • 如需农历功能,请确保使用支持该功能的版本
  • 如需打卡签到、节假日、自定义插槽等高级功能,请使用最新版本

如果你正在开发 uni-app 项目,需要一个功能强大、易于定制的日历组件,uView Pro 的 Calendar 值得一试,快来体验一下。

九、资源

  • 📚 uView Pro 官方文档:uviewpro.cn
  • 📦 开源地址:GithubGitee,欢迎 Star
  • 💬 技术交流:如有问题欢迎在评论区留言讨论

本文基于 uView Pro v0.5.17 版本编写,部分功能可能需要更新版本支持。

3月份民航旅客运输量同比增长12.1%

2026年4月20日 15:11
记者20日从中国民航局获悉,今年3月份,民航旅客运输量6663.2万人次,同比增长12.1%。中国民航局当日公布民航3月份主要生产指标统计数据。数据显示,3月份,民航国内航线旅客运输量5951.1万人次,同比增长11.5%;国际航线旅客运输量712.1万人次,同比增长17%。货邮运输方面,3月份,民航货邮运输量85.1万吨,同比增长4.2%。其中,国内航线货邮运输量45.8万吨,同比增长1.3%;国际航线货邮运输量39.3万吨,同比增长7.8%。(央视新闻)

问界在北京成立汽车销售服务公司

2026年4月20日 15:09
36氪获悉,爱企查App显示,近日,北京赛力斯问界汽车销售服务有限公司成立,法定代表人为李守忠,注册资本500万元人民币,经营范围包括汽车销售、摩托车及零配件零售、机械电气设备销售、五金产品零售等。股东信息显示,该公司由重庆问界汽车销售有限公司全资持股。

启明头条 | 连接世界级的科学与顶级的投资者,首届S2S中国研讨会创业提案第二次征集进行中

2026年4月20日 15:01

由全球顶尖的风险投资机构RA Capital Management与启明创投联合主办的首届S2S(Science2Startup)中国研讨会将于2026年10月15日在浙江杭州隆重举行。作为生物科技领域的顶级创业赛事,日前,首届S2S中国研讨会面向中国顶尖高校及研究机构的创业提案的第二次征集(https://www.s2schina.com/)已进入倒计时(截止日期:2026年4月30日)。ATLATL飞镖加速器作为首选合作伙伴,动脉网、医学界·药创新、医药魔方为媒体战略合作伙伴,将全程助力和支持本次S2S研讨会在中国成功举办。

S2S(Science2Startup)是全球知名的生命科学创业孵化平台,起源于2018年,由F-Prime Capital、SV Health 和Atlas Venture共同创立,现已发展成为全球生物科技创新的核心引擎。S2S中国由RA Capital Management和启明创投共同发起。RA Capital Management是全球生命科学与医疗健康领域最活跃的资产管理公司之一,启明创投在医疗创新领域的投资具有前瞻性和引领性,全球排名持续保持在TOP5以内。双方强强联手,旨在通过S2S平台,加速中国生物医药技术的商业化及全球化进程。

S2S研讨会是一个展示精选科学家研究成果的平台。这是一个邀请制的研讨会,顶尖科学家可在研讨会上展示其创业理念,并能与顶尖的生物科技投资者进行交流。

 继成功孵化超过14家初创企业,并于2024年成功举办S2S日本站研讨会之后,S2S正式将目光投向中国科学界。首届S2S中国研讨会旨在搭建一座连接中国世界级科研成果与全球顶级生物医药资本的桥梁。致力于释放中国学术界的生命科学潜力,为尚未获得A轮融资、甚至尚未成立法人实体的早期科研项目提供展示舞台。

此次提案征集,S2S中国希望寻找处于概念验证阶段的突破性技术。理想的候选项目需具备以下特征:——治疗领域内的新型专有学术技术——距离临床应用小于4-5年,拥有关键数据支持——相较于现有疗法具有显著优势(如更好地满足未满足的临床需求)

不同于普通的路演,S2S采用独特的“导师制”方式连接入选科学家与风投机构导师——双方将进行一对一合作,从新颖性、治疗潜力及商业化路径等方面,深度打磨创业理念与演示文稿;入选的科学家将有机会与全球顶尖投资机构与行业高管直接交流沟通,挖掘潜在投资机会,这些顶尖投资机构包括RA Capital、启明创投、F-Prime、Atlas Venture、Foresite Capital、礼来亚洲基金以及高瓴等;入选科学家不仅能够获得潜在投资机会,更有机会建立跨境合作关系。此外,S2S中国将为决赛选手提供差旅资助,确保创意无障碍展示。这是一个直达全球顶尖投资网络的稀缺机会。我们诚邀顶尖科学家即刻访问S2SChina官网提交提案,踏上从实验室到创业的加速之路。2026年10月15日,杭州见!

A股三大指数收盘涨跌不一,中国卫星涨停

2026年4月20日 15:01
36氪获悉,A股三大指数收盘涨跌不一,沪指涨0.76%,深成指涨0.55%,创业板指跌0.02%;化纤、培育钻石、卫星互联网概念领涨,新乡化纤、中国卫星涨停,力量钻石涨超6%;盐湖提锂、房地产、仿制药概念跌幅居前,蓝晓科技跌超12%,城建发展、信立泰跌超4%。

宁德时代“超级科技日”计划发布钠电、快充等相关技术产品

2026年4月20日 14:59
宁德时代计划于明日举办的“超级科技日”上,发布钠电、凝聚态、快充等相关技术产品。4月15日,在宁德时代2026年一季度财报上,该公司确认将于4月21日举办2026年“超级科技日”发布会,主题为“极域之约”。彼时,宁德时代方面表示,这是成立以来技术密度最高的一场发布会,届时将带来全新的技术、产品和生态,每一个都指向行业最关注的问题。(财联社)

锦鸡股份股债再度下跌,公司回应:提前赎回可转债是为了降低成本

2026年4月20日 14:45
继上周五遭遇股债双杀后,4月20日,锦鸡股份股债再度下跌。锦鸡股份方面回应记者,提前赎回可转债,下跌是正常市场现象。触发有条件赎回条款后,上市公司可以选择提前赎回,也可以选择到期兑付。公司考虑到价格比较高,如果到期兑付需要支付成本较高,而提前赎回可以降低成本,所以选择提前赎回。(中证报)

“智能派”完成数亿元B+轮融资

2026年4月20日 14:40
36氪获悉,“智能派”已完成数亿元B+轮融资。由美团领投,深创投、高瓴、银泰、国策、明荟致远、高新投等联合注资。本轮融资距离上一次大疆参与的轮次不到半年。

“灵机天赐”完成两轮数千万元人民币融资

2026年4月20日 14:38
36氪获悉,“灵机天赐”于过去一年内完成两轮数千万元人民币融资,天使轮由德联资本领投,小恐龙基金和瑞昇基金跟投,Pre-A轮由Implic Capital领投,两轮融资均由探奇资本担任公司独家财务顾问。

阿里发布语音识别大模型Fun-ASR1.5

2026年4月20日 14:34
36氪获悉,4月20日,阿里巴巴发布端到端语音识别大模型Fun-ASR1.5 ,无需预设语种标签,单一模型即可高精度识别30种语言。此前,Fun-ASR1.0已用于钉钉AI听记、DingTalk A1录音机等智能硬件。全新升级的1.5版本覆盖中文七大方言体系及二十余种地方口音,并强化古诗词诵读的专项识别,将应用场景拓宽至跨国企业、国际会议、多语直播、县域政务服务以及古诗词教育等。

Vue 3 Composition API 最佳实践:从项目实战中汲取的经验

作者 果然123
2026年4月20日 14:30

Vue 3 Composition API 最佳实践:从项目实战中汲取的经验

前言

随着 Vue 3 的发布,Composition API(组合式 API)已成为现代 Vue 开发的核心特性。它提供了更好的代码组织、可复用性和类型推断支持。然而,在实际项目中,许多开发者仍面临如何高效使用 Composition API 的挑战。本文基于我在市场监督 Vue 项目中的实战经验,分享一些 Composition API 的最佳实践,帮助你避免常见坑点,提升代码质量。

目录

  • Composition API 基础回顾
  • 最佳实践 1:逻辑复用与 composables
  • 最佳实践 2:响应式数据管理
  • 最佳实践 3:生命周期与副作用处理
  • 最佳实践 4:类型安全与 TypeScript 集成
  • 性能优化技巧
  • 总结

Composition API 基础回顾

Composition API 允许我们将组件的逻辑按功能分组,而不是按选项分组。核心函数包括 refreactivecomputedwatch 等。与 Options API 相比,它更灵活,适合大型应用。

// 基础示例
import { ref, computed } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const doubleCount = computed(() => count.value * 2)
    
    return { count, doubleCount }
  }
}

最佳实践 1:逻辑复用与 composables

在项目中,我们经常需要复用逻辑,如数据获取、表单验证。Composition API 通过 composables(组合函数)实现这一点。

实践建议:

  • 将可复用逻辑提取到独立的 composables 文件中。
  • 使用 use 前缀命名,如 useFetchData
  • 避免在 composables 中直接操作 DOM,确保纯逻辑。
// composables/useFetchData.js
import { ref, onMounted } from 'vue'
import axios from 'axios'

export function useFetchData(url) {
  const data = ref(null)
  const loading = ref(false)
  const error = ref(null)

  const fetchData = async () => {
    loading.value = true
    try {
      const response = await axios.get(url)
      data.value = response.data
    } catch (err) {
      error.value = err
    } finally {
      loading.value = false
    }
  }

  onMounted(fetchData)

  return { data, loading, error, refetch: fetchData }
}

在组件中使用:

// components/DataList.vue
import { useFetchData } from '@/composables/useFetchData'

export default {
  setup() {
    const { data, loading, error } = useFetchData('/api/data')
    return { data, loading, error }
  }
}

经验分享: 在市场监督项目中,我们将 API 调用逻辑抽象为 composables,大大减少了重复代码。记得处理错误边界,避免 composables 耦合过多。

最佳实践 2:响应式数据管理

响应式是 Vue 的核心。Composition API 提供了 refreactive,选择取决于数据结构。

实践建议:

  • 对于基本类型使用 ref,对象使用 reactive
  • 避免深层嵌套响应式对象,使用 shallowRefshallowReactive 优化性能。
  • 使用 toRefs 将 reactive 对象解构为 ref,避免丢失响应性。
import { reactive, toRefs } from 'vue'

export default {
  setup() {
    const state = reactive({
      user: { name: 'John', age: 30 },
      settings: { theme: 'dark' }
    })

    // 正确解构
    return { ...toRefs(state) }
  }
}

坑点提醒: 直接解构 reactive 对象会丢失响应性。项目中曾因忘记 toRefs 导致数据不更新,调试了半天。

最佳实践 3:生命周期与副作用处理

Composition API 使用 onMountedonUnmounted 等钩子管理生命周期。

实践建议:

  • 将副作用逻辑(如定时器、事件监听)封装在 composables 中。
  • 使用 onBeforeUnmount 清理资源,防止内存泄漏。
  • 对于异步操作,使用 watchEffectwatch 监听依赖。
import { ref, onMounted, onUnmounted } from 'vue'

export function useInterval(callback, delay) {
  const intervalId = ref(null)

  onMounted(() => {
    intervalId.value = setInterval(callback, delay)
  })

  onUnmounted(() => {
    if (intervalId.value) {
      clearInterval(intervalId.value)
    }
  })

  return { intervalId }
}

经验分享: 在实时监控页面,我们用这个 composable 管理数据轮询。记得在组件销毁时清理,避免后台运行。

最佳实践 4:类型安全与 TypeScript 集成

TypeScript 与 Composition API 完美配合,提供更好的开发体验。

实践建议:

  • 为 composables 定义接口。
  • 使用 Ref<T>ComputedRef<T> 类型。
  • 利用 Vue 3 的类型推断,减少显式类型声明。
import { ref, computed, type Ref } from 'vue'

interface User {
  id: number
  name: string
}

export function useUser(): { user: Ref<User | null>, isLoggedIn: ComputedRef<boolean> } {
  const user = ref<User | null>(null)
  const isLoggedIn = computed(() => !!user.value)

  return { user, isLoggedIn }
}

经验分享: 项目中引入 TypeScript 后,IDE 提示更准确,减少了运行时错误。建议从核心 composables 开始逐步迁移。

性能优化技巧

  • 使用 shallowRefshallowReactive:对于大型对象,避免深层响应式。
  • 合理使用 computed:缓存计算结果,避免重复计算。
  • 拆分大型组件:将逻辑拆分为多个 composables,减少单个 setup 函数的复杂度。
  • 使用 nextTick:在 DOM 更新后执行逻辑。
import { nextTick } from 'vue'

// 示例:等待 DOM 更新后聚焦输入框
await nextTick()
inputRef.value.focus()

总结

Composition API 让 Vue 开发更现代化,但需要良好的架构思维。通过 composables 复用逻辑、正确管理响应式和生命周期,我们可以写出更可维护的代码。在市场监督项目中,这些实践帮助我们从 2.x 顺利迁移到 3.x,提升了开发效率。

希望这篇文章对你有帮助!如果你有其他 Vue 3 经验,欢迎在评论区分享。代码示例可在 GitHub 上找到完整项目。

第六届消博会期间,海南离岛免税购物金额达4.7亿元

2026年4月20日 14:30
第六届中国国际消费品博览会(以下简称“消博会”)于2026年4月13日—18日在海南举办。据海口海关统计,第六届消博会期间,海口海关共监管离岛免税购物金额4.7亿元,购物人次8.5万人次,购物件数40.3万件,消费热度持续攀升。(央视新闻)

北京具身势能联合上海计算机研究所成立具身智能实验室

2026年4月20日 14:26
36氪获悉,近日,北京具身势能和上海计算机研究所发起具身智能生态联盟,并成立具身智能联合创新实验室。联合实验室将围绕多模态大模型、机器人控制、Sim2Real等核心技术攻关,打造“研发—验证—落地—孵化”一体化创新平台。目前,联合实验室已同博天环境、天际氢能、河南汉海教育达成战略签约,包括与博天环境推进环保场景机器人落地;与天际氢能研发全球首款氢动力具身智能机器人;与汉海教育共建人才基地。
❌
❌