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

如何自定义Nuxt Content v1的Markdown代码块:添加复制按钮与标题

为Nuxt Content v1的代码块添加自定义标题与复制按钮

1. 解析代码块元数据并修改渲染结构

Nuxt Content v1基于markdown-it,我们可以通过扩展markdown-it来解析代码块的自定义标题,并重写代码块的渲染逻辑。在nuxt.config.js中配置content.markdown.extend:

export default {
  content: {
    markdown: {
      extend: (md) => {
        // 保存默认代码块渲染器
        const defaultFenceRenderer = md.renderer.rules.fence;
        // 重写代码块渲染规则
        md.renderer.rules.fence = (tokens, idx, options, env, self) => {
          const token = tokens[idx];
          // 解析代码块末尾的元数据(如 {title="示例代码"})
          const metaStr = token.info.replace(/^[a-z]+\s*/, '');
          let titleHtml = '';
          if (metaStr) {
            const titleMatch = metaStr.match(/title="([^"]+)"/);
            if (titleMatch) {
              titleHtml = `<div class="code-block-title">${titleMatch[1]}</div>`;
            }
          }
          // 获取默认渲染的代码块HTML
          const codeContent = defaultFenceRenderer(tokens, idx, options, env, self);
          // 拼接带标题和复制按钮的容器HTML
          return `
            <div class="code-block-wrapper">
              ${titleHtml}
              <div class="code-block-actions">
                <button class="copy-btn" data-code="${encodeURIComponent(token.content)}">复制</button>
              </div>
              ${codeContent}
            </div>
          `;
        };
      }
    }
  }
}

2. 实现复制按钮功能

创建Nuxt客户端插件处理复制逻辑,新建plugins/code-copy.js:

export default ({ app }) => {
  if (process.client) {
    // 路由切换后重新绑定复制事件
    app.router.afterEach(() => {
      setTimeout(() => {
        document.querySelectorAll('.copy-btn').forEach(btn => {
          // 先移除旧事件避免重复绑定
          btn.removeEventListener('click', copyHandler);
          btn.addEventListener('click', copyHandler);
        });
      }, 100);
    });

    async function copyHandler(e) {
      const code = decodeURIComponent(e.target.dataset.code);
      try {
        await navigator.clipboard.writeText(code);
        e.target.textContent = '已复制';
      } catch (err) {
        e.target.textContent = '复制失败';
        console.error('复制出错:', err);
      }
      // 2秒后恢复按钮文字
      setTimeout(() => e.target.textContent = '复制', 2000);
    }
  }
}

在nuxt.config.js中注册该插件:

export default {
  plugins: ['~/plugins/code-copy.js'],
  // 其他配置...
}

3. 添加样式美化

在全局CSS文件(如assets/css/main.css)中添加代码块样式:

.code-block-wrapper {
  position: relative;
  margin: 1.5rem 0;
  border-radius: 4px;
  overflow: hidden;
}

.code-block-title {
  padding: 0.5rem 1rem;
  background-color: #2d3748;
  color: #fff;
  font-size: 0.9rem;
  border-bottom: 1px solid #4a5568;
}

.code-block-actions {
  position: absolute;
  top: 0.5rem;
  right: 1rem;
}

.copy-btn {
  background-color: #4a5568;
  color: #fff;
  border: none;
  padding: 0.25rem 0.75rem;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.8rem;
  transition: background-color 0.2s;
}

.copy-btn:hover {
  background-color: #2d3748;
}

.code-block-wrapper pre {
  margin: 0;
  border-radius: 0;
}

4. 实际使用示例

在Markdown文件中按以下格式编写代码块:

console.log('Hello Nuxt Content v1!');

渲染后会显示带自定义标题的代码块,右上角的复制按钮可一键复制代码内容。


内容的提问来源于stack exchange,提问作者Mimayuki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:50:34