You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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');
});

疑问

  1. 该函数为何会被调用两次?
  2. 若第一次调用是模板渲染导致,第二次调用的原因是什么?

已查阅Vue官方生命周期钩子文档,但仍未理解渲染过程中函数被两次执行的原因。


解答

  • 第一次调用是因为Vue在挂载组件前会做首次模板渲染,模板里的{{ get_page_param('current') }}属于模板表达式,渲染时必然会执行这个函数,对应你看到的挂载前的那次打印。
  • 第二次调用的触发点是onBeforeMount里的axios请求:请求完成后给响应式变量info.value赋值,这会触发Vue的响应式更新。虽然get_page_param('current')的逻辑没用到info,但因为这个函数在首次渲染时被执行过,Vue会把它纳入组件的渲染依赖中,当info更新时就会触发模板重新渲染,函数自然也就再次执行了。

提个实用建议:别在模板里直接调用函数,每次组件渲染(包括重新渲染)都会跑一遍这个函数,既浪费性能,还容易搞出这种让人困惑的情况。换成computed属性或者把计算结果存到响应式变量里才是更稳妥的做法——只有当依赖的数据变化时,才会重新计算。

内容的提问来源于stack exchange,提问作者shellRaining

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 10:55:14