Vue3模板中函数的生命周期

cnjp1d6j  于 2023-01-02  发布在  Vue.js
关注(0)|答案(1)|浏览(155)

这可能是我的问题的最小再现

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

当我运行这段代码时,我看到get_page_param(current) is calling在浏览器的控制台中被打印了两次,这两次打印都发生在挂载之前,第二次打印是在挂载之后

我的问题是
1.为什么此函数调用两次
1.如果第一个调用是用于呈现模板,那么第二个调用的原因是什么
我查了Vue关于生命周期钩子的官方文档https://cn.vuejs.org/api/composition-api-lifecycle.html#onupdated,还是不明白为什么页面在渲染过程中会执行两次该函数,我想可能是前端相关知识,但我没理解

brgchamk

brgchamk1#

渲染被调用两次的原因与vue组件的生命周期有关。当一个React值改变时,Vue总是渲染组件。当你在模板中使用一个函数时,它将在组件的每个渲染周期被调用。在你的例子中,info.value更新将触发一个重新渲染。同样,如果使用一个函数,如果你改变任何React值,vue需要总是触发一个重新渲染。
这也是为什么你不应该在模板内部使用函数。只要有可能,你应该使用计算属性,并在模板内部应用它。优点是,vue将在内部缓存计算属性的值,只有当你在内部使用的一些值被更新时,才会更新组件。
您应该确保了解vue lifecycle的工作原理。
更好的方法是使用在模板内呈现的计算属性。下面显示了一个可能适合您的示例。

const direction = ref('');

const pageParam = computed(() => {
  try {
    let url_string = null;
    switch (direction.value) {
      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);
    return '1'; // you need to return the fallback page
  }
});

在您使用的模板中

<template>
  <span class='current-page'>
    {{ pageParam }}
  </span>
</template>

相关问题