You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 01:25:39