Vue 的数据为什么频繁变化但只会更新一次?

Vue.js 使用了一种叫做批量异步更新的策略来处理数据变化和视图更新。

当你改变一个响应式数据时,Vue.js 不会立即更新视图,而是把这个组件标记为“脏的”,然后在事件循环的下一个“tick”中,一次性更新所有标记的组件。

这种策略的好处是,如果你在一个事件循环中多次改变同一个数据,Vue.js 只会更新一次视图,从而避免了不必要的计算和 DOM 操作,提高了性能。

这种策略是基于 JavaScript 的事件循环和 Vue.js 的依赖跟踪系统实现的。当一个数据变化时,Vue.js 会通知所有依赖这个数据的 watcher,然后这些 watcher 会把它们所在的组件添加到一个队列中。在下一个事件循环“tick”中,Vue.js 会遍历这个队列,更新所有的组件。

你可以使用 Vue.nextTick(callback) 方法来在下一个“tick”中执行一段代码。这个方法接受一个回调函数,这个函数会在 DOM 更新完成后被调用。

this.message = 'Hello Vue!'
Vue.nextTick(() => {
  // 这个回调函数会在 DOM 更新完成后被调用
  console.log(this.$el.textContent) // 'Hello Vue!'
})

在这个例子中,Vue.nextTick() 确保了我们的代码在 DOM 更新完成后才被执行。

### Vue 中 `onMounted` 钩子只触发一次的原因 在 Vue 的生命周期中,`onMounted` 是一个组合式 API,在组件挂载到 DOM 后会被调用。当用户从 A 页面跳转至 B 页面再返回 A 页面时,如果未重新创建该组件实例,则不会再次触发 `onMounted`[^1]。 这是因为 Vue 的路由机制默认会对相同组件进行复用。在这种情况下,即使导航离开并回到同一个组件,也不会销毁和重建它,而是保持其状态不变。因此,只有第一次渲染时才会调用 `onMounted`,后续切换时不满足条件就不会重复执行[^2]。 #### 解决方案一:使用 `onActivated` 对于需要每次进入页面都运行逻辑的情况,可以考虑替换为 `onActivated` 生命周期钩子。这个钩子会在组件激活(无论是初次访问还是通过缓存恢复)时触发,从而实现预期效果: ```javascript import { onActivated } from 'vue'; export default { setup() { onActivated(() => { console.log('Component is activated'); }); } }; ``` #### 解决方案二:监控路由变化 另一种方式是在现有代码基础上增加对路由参数改变的响应能力。利用 Vue Router 提供的功能配合 Composition API 实现动态更新功能[^4]: ```javascript import { useRoute, useRouter } from 'vue-router'; import { ref, onMounted, watch } from 'vue'; const route = useRoute(); let currentId = ref(null); onMounted(() => { currentId.value = route.params.id; }); watch( () => route.params, (toParams) => { currentId.value = toParams.id; fetchData(currentId.value); // 自定义的数据获取函数 } ); ``` 上述例子展示了如何监听路径中的参数变动,并及时作出反应来刷新视图或者加载新数据。 #### 方案三:强制禁用组件缓存 如果你希望彻底避免这种行为模式,可以通过设置 meta 字段或其他手段阻止特定组件被缓存下来。不过这种方法可能会影响性能表现以及用户体验,需谨慎评估适用场景后再决定采用与否[^3]。 综上所述,针对不同需求可以选择合适的策略应对 `onMounted` 不再频繁触发现象带来的挑战。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值