Vue中watch使用是否正确?点击两次<li>才获取数据问题排查
问题分析与解决方案
你的watch用法逻辑上是正确的,但出现点击两次才生效的问题,大概率是以下几个原因:
1. 初始状态未触发数据请求
watch只会在month_id发生变化时执行,组件首次挂载时如果month_id已有初始值,watch不会自动触发。这会导致第一次点击只是更新了month_id,但请求没执行;第二次点击再次更新month_id,watch才触发请求。
解决方法:给watch添加immediate: true选项,让它在组件初始化时自动执行一次,或者在mounted钩子中主动调用请求。示例如下:
export default { props: ['mosque_id', 'month_id'], data(){ return { prayer_times: [], } }, watch: { month_id: { handler() { this.getPrayerTime(); }, immediate: true // 初始化时立即执行一次 } }, methods:{ getPrayerTime() { axios.get(`/api/v1/getPrayerTime/${this.mosque_id}/${this.month_id}`) .then(response => { // 用箭头函数替代bind(this),更简洁 this.prayer_times = response.data; }) .catch(error => { // 建议添加错误捕获,方便排查问题 console.error('获取祈祷时间失败:', error); }); } }, }
2. 父组件传递month_id的更新延迟
检查父组件中month_id的更新逻辑,确保点击<li>时是同步更新month_id值,而非异步操作导致子组件接收值延迟。比如父组件如果是通过异步请求更新month_id,要确保请求完成后再传递给子组件。
3. 特殊场景:month_id为引用类型
如果month_id是对象这类引用类型,默认watch只会监听引用地址变化,不会监听内部属性。这种情况需要开启深度监听:
watch: { month_id: { handler() { this.getPrayerTime(); }, immediate: true, deep: true // 深度监听引用类型内部变化 } }
额外优化建议
- 用ES6模板字符串拼接API地址,比传统字符串拼接更易读
- 给axios请求添加
catch分支,避免请求失败时无反馈
内容的提问来源于stack exchange,提问作者abu abu
相关产品推荐
相关产品推荐

