Nuxt Link动态to属性添加UTM参数后相对链接异常问题
问题
我开发了ArticleLink组件用来给所有Nuxt链接自动添加UTM追踪参数,但使用相对链接时,渲染出的href会把当前路径和计算后的完整URL拼接在一起,出现异常。不过console.log和Vue DevTools里显示的to属性是正确的。
组件代码如下:
<template> <nuxt-link :to="url" :target="$attrs.target"><slot></slot></nuxt-link> </template> <script lang="ts"> import Vue from 'vue'; export default Vue.extend({ name: 'ArticleLink', props: { to: { type: String, required: true, }, date: { type: Number, required: true, }, }, computed: { url(): string { const url = this.to.startsWith('/') ? `${process.env.VUE_APP_ORIGIN}${this.to}` : this.to; const urlObject = new URL(url); urlObject.searchParams.append('utm_source', 'article'); urlObject.searchParams.append('date', this.date); console.log(this.to, urlObject.href); return urlObject.href; }, }, }); </script>
使用示例:
<article-link date="20221109" to="/">link</article-link>
异常渲染结果:
http://localhost:3000/current/path/http://localhost:3000/?utm_source=article&date=20221109
解决方案
问题根源是你给nuxt-link的:to传了带域名的完整URL,而nuxt-link会把完整URL当作相对路径处理,导致和当前页面路径拼接。
提供两种修复方式:
方式一:区分内部/外部链接处理
利用nuxt-link的特性,内部链接传路由对象,外部链接传完整URL:
<template> <nuxt-link v-bind="linkProps" :target="$attrs.target"><slot></slot></nuxt-link> </template> <script lang="ts"> import Vue from 'vue'; export default Vue.extend({ name: 'ArticleLink', props: { to: { type: String, required: true, }, date: { type: Number, required: true, }, }, computed: { linkProps() { // 处理内部相对链接 if (this.to.startsWith('/')) { const [path, existingQuery] = this.to.split('?'); const queryParams = new URLSearchParams(existingQuery); queryParams.append('utm_source', 'article'); queryParams.append('date', this.date); return { path, query: Object.fromEntries(queryParams) }; } // 处理外部链接 const urlObject = new URL(this.to); urlObject.searchParams.append('utm_source', 'article'); urlObject.searchParams.append('date', this.date); return { href: urlObject.href }; } }, }); </script>
方式二:仅给相对链接添加参数(不拼接域名)
直接处理相对路径的查询参数,返回带参数的相对路径给nuxt-link:
<script lang="ts"> // ... 其他代码不变 computed: { url(): string { if (this.to.startsWith('/')) { // 拆分路径和已有查询参数 const [path, existingQuery] = this.to.split('?'); const queryParams = new URLSearchParams(existingQuery); queryParams.append('utm_source', 'article'); queryParams.append('date', this.date); // 返回带参数的相对路径 return `${path}?${queryParams.toString()}`; } // 外部链接仍按原逻辑处理 const urlObject = new URL(this.to); urlObject.searchParams.append('utm_source', 'article'); urlObject.searchParams.append('date', this.date); return urlObject.href; }, } </script>
内容的提问来源于stack exchange,提问作者d-_-b
相关产品推荐
相关产品推荐

