Featured image of post Nuxt2のnuxt-linkでaria-currentの属性が設定されなかった問題について

Nuxt2のnuxt-linkでaria-currentの属性が設定されなかった問題について

Twitter ツイート Hatena Bookmark ブックマーク

同じURIのリンクなのに aria-currentの属性がつく場合とつかない場合があって結構悩んだのでそのメモ。

どのような問題が発生していたのか?

よくあるページネーションの実装で、1ページ目の/hoge?page=1はクエリを削除してリンクを表示していた。 ページ番号を削除したNuxtLinkにおいて aria-current の属性がつく場合とつかない場合があって謎の挙動をしていた…。

ページクエリを削除するために以下のような処理をしてNuxtLinkの to属性に渡している

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
      if (page == 1) {
        const nextQuery = Object.assign({}, this.route.query, {
          [this.pageQueryName]: undefined
        })
      }

      return {
        path: this.route.path,
        params: this.route.params,
        query: nextQuery ? nextQuery : this.router.query
      }

NuxtLinkは独自のコンポーネントのかと思ったら、vue-routerのRouterLinkを継承していた。 そもそも aria-current の出し分けはRouterLinkの方の処理だった。

aria-currentを表示するかしないかのコードについて

該当箇所が以下の通り。

1
2
3
4
5
6
    classes[exactActiveClass] = isSameRoute(current, compareTarget, this.exactPath);
    classes[activeClass] = this.exact || this.exactPath
      ? classes[exactActiveClass]
      : isIncludedRoute(current, compareTarget);

    var ariaCurrentValue = classes[exactActiveClass] ? this.ariaCurrentValue : null;

ここではvar ariaCurrentValueがaria-currentに入る中身になっていて、this.ariaCurrentValue はデフォルト値になっている。 つまり、isSameRouteの関数の判定によって変わってくる。

isSameRouteの関数について

該当コードは以下の通り

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
function isSameRoute (a, b, onlyPath) {
  if (b === START) {
    return a === b
  } else if (!b) {
    return false
  } else if (a.path && b.path) {
    return a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') && (onlyPath ||
      a.hash === b.hash &&
      isObjectEqual(a.query, b.query))
  } else if (a.name && b.name) {
    return (
      a.name === b.name &&
      (onlyPath || (
        a.hash === b.hash &&
      isObjectEqual(a.query, b.query) &&
      isObjectEqual(a.params, b.params))
      )
    )
  } else {
    return false
  }
}

単純なfullPathを使った判定をしているのかと、pathが一緒の場合はQueryの通り。

何が問題だったのか?

問題はページクエリの削除のしかたに問題があった。

1
query = { page: undefined }

とすると最終的に生成されるURLとしては page クエリが削除された状態で生成される。 しかし isSameRoute では queryパラメータも完全に同一かどうかチェックしていた。

そのため、 同じ /hoge URLにアクセスした場合でも、queryパラメータをundefinedを使って削除しているNuxtLinkの場合は isSameRoute が falseになり aria-current の属性が付与されなかった。

つまり以下の書き方のように直せば意図通りに isSameRoute の判定がされた。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
      if (page == 1) {
        const { page, ...queryParameters } = this.route.query
        const nextQuery = Object.assign({}, queryParameters)
      }

      return {
        path: this.route.path,
        params: this.route.params,
        query: nextQuery ? nextQuery : this.router.query
      }

参考

Vue Routerでquery書き換えができなかった(凡ミス)

comments powered by Disqus
Built with Hugo
テーマ StackJimmy によって設計されています。