Vue3.3.2 – 是否可以在可组合函数内访问 useRoute?

huangapple go评论59阅读模式
英文:

Vue3.3.2 - Is it possible to access useRoute within a composable function?

问题

I'm trying to access useRoute from within a composable function. Starting with vue 3.3.2 & vue-route 4.2.0, I set up a test using npm init vue@latest with the router enabled. No problem accessing useRoute via the composition API within the 'script setup' tag:

App.vue

<script setup>
import { RouterLink, RouterView } from 'vue-router';

import { useRoute } from 'vue-router';
const route = useRoute();

import { computed } from 'vue';
const path = computed(() => {
  console.log('step 1');
  if (!route) {
    console.log('step 2');
    return;
  }
  if (!route.path) {
    console.log('step 3');
    return;
  }
  console.log('step 4');
  return route.path;
});
</script>

<template>
  <p>path = {{ path }}</p>
  <header>
    <nav>
      <RouterLink to="/">Home</RouterLink>
      <RouterLink to="/about">About</RouterLink>
    </nav>
  </header>

  <RouterView />
</template>

In the above code, the computed function is re-calculated each time the route changes, reaching step 1 then step 4 (success).

But when I move this code to a composable it breaks:

App.vue

<script setup>
import { RouterLink, RouterView } from 'vue-router';
import path from '@/composables/useRouteTest';
</script>

composables/useRouteTest.js

import { useRoute } from 'vue-router';
const route = useRoute();

import { computed } from 'vue';
const path = computed(() => {
  console.log('step 1');
  if (!route) {
    console.log('step 2');
    return;
  }
  if (!route.path) {
    console.log('step 3');
    return;
  }
  console.log('step 4');
  return route.path;
});

export default {
  path
};

Within the composable, the computed function never progresses beyond step 2, and is only called once, even when I navigate to different routes.

Does useRoute not work within composables?

I've spent many hours trying the following alternatives: different Vue versions; using watch instead of computed; 'useRouter' rather than 'useRoute'; using watch with async invocation (https://router.vuejs.org/guide/advanced/composition-api.html). Always the same result.

英文:

I'm trying to access useRoute from within a composable function. Starting with vue 3.3.2 & vue-route 4.2.0, I set up a test using npm init vue@latest with the router enabled. No problem accessing useRoute via the composition API within the 'script setup' tag:

App.vue

&lt;script setup&gt;
import { RouterLink, RouterView } from &#39;vue-router&#39;

import { useRoute } from &#39;vue-router&#39;
const route = useRoute()

import { computed } from &#39;vue&#39;
const path = computed(() =&gt; {
  console.log(`step 1`)
  if (!route) {
    console.log(`step 2`)
    return
  }
  if (!route.path) {
    console.log(`step 3`)
    return
  }
  console.log(`step 4`)
  return route.path
})
&lt;/script&gt;

&lt;template&gt;
  &lt;p&gt;path = {{ path }}&lt;/p&gt;
  &lt;header&gt;
    &lt;nav&gt;
      &lt;RouterLink to=&quot;/&quot;&gt;Home&lt;/RouterLink&gt;
      &lt;RouterLink to=&quot;/about&quot;&gt;About&lt;/RouterLink&gt;
    &lt;/nav&gt;
  &lt;/header&gt;

  &lt;RouterView /&gt;
&lt;/template&gt;

In the above code, the computed function is re-calculated each times the route changes, reaching step 1 then step 4 (success).

But when I move this code to a composable it breaks:

App.vue

&lt;script setup&gt;
import { RouterLink, RouterView } from &#39;vue-router&#39;
import path from &#39;@/composables/useRouteTest&#39;
&lt;/script&gt;

composables/useRouteTest.js

import { useRoute } from &#39;vue-router&#39;
const route = useRoute()

import { computed } from &#39;vue&#39;
const path = computed(() =&gt; {
  console.log(`step 1`)
  if (!route) {
    console.log(`step 2`)
    return
  }
  if (!route.path) {
    console.log(`step 3`)
    return
  }
  console.log(`step 4`)
  return route.path
})

export default {
  path
}

Within the composable, the computed function never progresses beyond step 2, and is only called once, even when I navigate to different routes.

Does useRoute not work within composables?

I've spend many hours trying the following alternatives: different Vue versions; using watch instead of computed; 'useRouter' rather than 'useRoute'; using watch with async invocation (https://router.vuejs.org/guide/advanced/composition-api.html). Always the same result.

答案1

得分: 1

import { useRoute } from 'vue-router'
import { computed } from 'vue'

export function useRouteTest() {
  const route = useRoute()

  const path = computed(() => {
    console.log(`step 1`)
    if (!route) {
      console.log(`step 2`)
      return
    }
    if (!route.path) {
      console.log(`step 3`)
      return
    }
    return route.path
  })

  return {
    path
  }
}
英文:

useRoute is only available for use inside script setup. What you can do in the composable is wrap its usage in a function then import and call the function from your component. This is the recommended way to make most composables so they can share the context of the component they're called from.

composables/useRouteTest.js

import { useRoute } from &#39;vue-router&#39;
import { computed } from &#39;vue&#39;

export function useRouteTest() {
  const route = useRoute()

  const path = computed(() =&gt; {
    console.log(`step 1`)
    if (!route) {
      console.log(`step 2`)
      return
    }
    if (!route.path) {
      console.log(`step 3`)
      return
    }
    return route.path
  })

  return {
    path
  }
}

App.vue

&lt;script setup&gt;
import { useRouteTest } from &#39;@/composables/useRouteTest&#39;

const { path } = useRouteTest()
&lt;/script&gt;

huangapple
  • 本文由 发表于 2023年5月15日 12:17:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76250855.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定