]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
refactor(link): useLink
authorEduardo San Martin Morote <posva13@gmail.com>
Fri, 24 Jan 2020 17:20:22 +0000 (18:20 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Fri, 24 Jan 2020 17:20:22 +0000 (18:20 +0100)
__tests__/RouterLink.spec.ts
playground/index.html
src/components/Link.ts

index 5200cbf56e80a60899ac586fdb28cee2c444f27f..79db8357e4c0ca6566d2c318052807a714085917 100644 (file)
@@ -10,7 +10,7 @@ import {
 } from '../src/types'
 import { createMemoryHistory } from '../src'
 import { mount, tick } from './mount'
-import { ref, markNonReactive } from 'vue'
+import { ref, markNonReactive, isRef } from 'vue'
 
 const locations: Record<
   string,
@@ -34,6 +34,20 @@ const locations: Record<
       name: undefined,
     },
   },
+  foo: {
+    string: '/foo',
+    // toResolve: { path: '/home', fullPath: '/home', undefined, query: {}, hash: '' },
+    normalized: {
+      fullPath: '/foo',
+      path: '/foo',
+      params: {},
+      meta: {},
+      query: {},
+      hash: '',
+      matched: [],
+      name: undefined,
+    },
+  },
   withQuery: {
     string: '/home?foo=a&bar=b',
     // toResolve: { path: '/home', fullPath: '/home', undefined, query: {}, hash: '' },
@@ -72,7 +86,7 @@ describe('RouterLink', () => {
       template: `<RouterLink :to="to">a link</RouterLink>`,
       components: { RouterLink } as any,
       setup() {
-        const to = ref(propsData.to)
+        const to = isRef(propsData.to) ? propsData.to : ref(propsData.to)
 
         return { to }
       },
@@ -90,6 +104,20 @@ describe('RouterLink', () => {
     expect(el.innerHTML).toBe('<a class="" href="/home">a link</a>')
   })
 
+  it('can change the value', async () => {
+    const to = ref(locations.basic.string)
+    const { el, router } = factory(
+      START_LOCATION_NORMALIZED,
+      { to },
+      locations.basic.normalized
+    )
+    expect(el.innerHTML).toBe('<a class="" href="/home">a link</a>')
+    router.resolve.mockReturnValueOnce(locations.foo.normalized)
+    to.value = locations.foo.string
+    await tick()
+    expect(el.innerHTML).toBe('<a class="" href="/foo">a link</a>')
+  })
+
   it('displays a link with an object with path prop', () => {
     const { el } = factory(
       START_LOCATION_NORMALIZED,
index 058156a11defec784cc849c03d7767d85c88f049..1362b64cb61fb075f32b42222eec7744615c66f7 100644 (file)
@@ -8,6 +8,9 @@
     <script src="https://polyfill.io/v3/polyfill.min.js?features=default%2Ces2015"></script>
 
     <style>
+      .router-link-active {
+        color: red;
+      }
       .long {
         background-color: lightgray;
         height: 3000px;
index a07cebce922378bc9ca37a8fb7442fde6ecaae71..166b0e28f2dde025039b8ef2d1ead8908e96af6b 100644 (file)
@@ -2,10 +2,17 @@ import { defineComponent, h, PropType, inject } from '@vue/runtime-core'
 import { computed, reactive, isRef, Ref } from '@vue/reactivity'
 import { RouteLocation } from '../types'
 
-export function useLink(to: Ref<RouteLocation> | RouteLocation) {
+interface UseLinkProps {
+  to: Ref<RouteLocation> | RouteLocation
+  replace?: Ref<boolean> | boolean
+}
+
+export function useLink(props: UseLinkProps) {
   const router = inject('router')
 
-  const route = computed(() => router.resolve(isRef(to) ? to.value : to))
+  const route = computed(() =>
+    router.resolve(isRef(props.to) ? props.to.value : props.to)
+  )
   const href = computed(() => router.createHref(route.value))
   const isActive = computed<boolean>(
     () => router.currentRoute.value.path.indexOf(route.value.path) === 0
@@ -13,7 +20,7 @@ export function useLink(to: Ref<RouteLocation> | RouteLocation) {
 
   // TODO: handle replace prop
 
-  function navigate(e: MouseEvent) {
+  function navigate(e: MouseEvent = {} as MouseEvent) {
     // TODO: handle navigate with empty parameters for scoped slot and composition api
     if (guardEvent(e)) router.push(route.value)
   }
@@ -36,7 +43,7 @@ const Link = defineComponent({
   },
 
   setup(props, { slots, attrs }) {
-    const { route, isActive, href, navigate } = useLink(props.to)
+    const { route, isActive, href, navigate } = useLink(props)
 
     const elClass = computed(() => ({
       'router-link-active': isActive.value,