Vue3模板中函数两次调用的原因及相关疑问
问题:模板中调用的函数为何执行两次?
最小复现代码
模板代码
<template> <span class='current-page'> {{ get_page_param('current') }} </span> </template>
脚本代码
const get_page_param = function(direction) { // TODO: need delete the comment console.log(`get_page_param(${direction}) is calling`); try { let url_string = null; switch (direction) { case 'next': url_string = info.value.next; break; case 'previous': url_string = info.value.previous; break; default: return route.query.page; } const url = new URL(url_string); return url.searchParams.get('page'); } catch (err) { console.log(err); } }; onBeforeMount(()=>{ console.log('before mounting'); axios .get('/api/article') .then(response => { info.value = response.data; }); }) onMounted(() => { console.log('mounted'); });
疑问
- 该函数为何会被调用两次?
- 若第一次调用是模板渲染导致,第二次调用的原因是什么?
已查阅Vue官方生命周期钩子文档,但仍未理解渲染过程中函数被两次执行的原因。
解答
- 第一次调用是因为Vue在挂载组件前会做首次模板渲染,模板里的
{{ get_page_param('current') }}属于模板表达式,渲染时必然会执行这个函数,对应你看到的挂载前的那次打印。 - 第二次调用的触发点是
onBeforeMount里的axios请求:请求完成后给响应式变量info.value赋值,这会触发Vue的响应式更新。虽然get_page_param('current')的逻辑没用到info,但因为这个函数在首次渲染时被执行过,Vue会把它纳入组件的渲染依赖中,当info更新时就会触发模板重新渲染,函数自然也就再次执行了。
提个实用建议:别在模板里直接调用函数,每次组件渲染(包括重新渲染)都会跑一遍这个函数,既浪费性能,还容易搞出这种让人困惑的情况。换成computed属性或者把计算结果存到响应式变量里才是更稳妥的做法——只有当依赖的数据变化时,才会重新计算。
内容的提问来源于stack exchange,提问作者shellRaining
相关产品推荐
相关产品推荐

