Files
huangguo_landpage/.cursor/skills/figma-to-landpage/SKILL.md
T
2026-09-15 15:46:36 +07:00

6.1 KiB
Raw Blame History

name, description
name description
figma-to-landpage 将 Figma 设计稿转换为 Vue 2 落地页组件。当用户提供 Figma 链接并要求生成落地页、实现设计稿、创建新模板时触发。适用于移动端和 PC 端落地页开发。

Figma 转落地页

将 Figma 设计稿翻译为本项目的 Vue 2 落地页组件,保持视觉还原度。

工作流程

第 1 步: 获取设计稿信息

从 Figma URL 中提取 fileKeynodeId:

  • URL 格式: https://figma.com/design/:fileKey/:fileName?node-id=1-2
  • node-id 中的 - 转为 :

依次调用:

  1. get_design_context(fileKey, nodeId) — 获取布局、颜色、字体等结构化数据
  2. get_screenshot(fileKey, nodeId) — 获取视觉截图作为还原参考

如果设计太复杂导致返回截断:

  1. 先调 get_metadata(fileKey, nodeId) 获取节点树
  2. 对各子节点分别调 get_design_context

第 2 步: 确定模板编号

查看 src/views/land/components/ 下已有的模板文件:

  • 移动端: mobile1.vue, mobile2.vue, ...
  • PC 端: pc1.vue, pc2.vue, ...

新模板使用下一个序号。

第 3 步: 下载资源

将设计稿中的图片、图标导出并放入:

src/assets/images/{templateName}/

例如 mobile3 模板的资源放在 src/assets/images/mobile3/

Figma MCP 返回的 localhost 资源链接可直接下载使用。

第 4 步: 创建组件文件

src/views/land/components/ 下创建新的 .vue 文件。

必须遵循的组件结构:

<template>
  <div class="mobilePage" @click="pageClick">
    <!-- 顶部固定区域 -->
    <div class="headerBox" @click.stop="getApkInfo(os.isPhone && switchData.shopIosDownUrl ? 'shopIos' : true, $event)">
      <div class="header-bg"></div>
    </div>

    <!-- 主体内容区 -->
    <div class="main">
      <!-- Figma 设计内容转换到这里 -->
    </div>

    <!-- 社交浮窗 -->
    <div class="floatingBox" v-if="configs && configs.length">
      <div class="telegram" v-if="cTg" @click="jumpUrl(cTg)"></div>
      <div class="potato" v-if="cPotato" @click="jumpUrl(cPotato)"></div>
      <div class="business" v-if="cBusiness" @click="jumpUrl(cBusiness)"></div>
      <div class="channel" v-if="cChannel" @click="jumpUrl(cChannel)"></div>
    </div>

    <!-- 下载按钮区 -->
    <div class="bottomBox" @click.stop="getApkInfo(true, $event)"></div>

    <!-- 安卓/iOS 提示弹窗 -->
    <van-overlay :show="androidPromptShow" z-index="999" class="androidOverlay">
      <!-- ... -->
    </van-overlay>
    <van-overlay :show="iosPromptShow" z-index="999" class="iosOverlay">
      <!-- ... -->
    </van-overlay>
  </div>
</template>

<script>
import { landingPageClick } from "@/utils/eventTracker";
export default {
  props: ["os", "configs", "switchData"],
  data() {
    return {
      androidPromptShow: false,
      iosPromptShow: false,
      showTip: false,
      currUrl: window.location.href,
      cTg: "",
      cPotato: "",
      cBusiness: "",
      cChannel: "",
      showIosTip: true,
    };
  },
  watch: {
    configs(configs) {
      configs.forEach((item) => {
        if (item.configType === "tg_group") this.cTg = item.link;
        else if (item.configType === "potato_group") this.cPotato = item.link;
        else if (item.configType === "sw_cooperate") this.cBusiness = item.link;
        else if (item.configType === "qd_cooperate") this.cChannel = item.link;
      });
    },
  },
  methods: {
    pageClick(event) {
      landingPageClick(this, {
        tab_key: "main",
        tab_name: "主页",
        click_coordinates_x: event.clientX,
        click_coordinates_y: event.clientY,
      });
    },
    doCopy() {
      this.$copyText(this.currUrl).then(() => { this.showTip = false; });
    },
    async showInstallTutorial(type) {
      if (type === "ios") this.iosPromptShow = true;
      else this.androidPromptShow = true;
    },
    async getApkInfo(flag, event) {
      let type = this.os.isPhone ? "ios" : "android";
      if (flag === "shopIos") type = "shopIos";
      if (flag === "androidSpare") type = "androidSpare";
      if (flag && flag !== "shopIos") await this.showInstallTutorial(type);
      this.$emit("recordClick", type);
      setTimeout(() => { this.$emit("getApkInfo", type); }, 500);
      landingPageClick(this, {
        tab_name: "下载按钮",
        tab_key: "download",
        click_coordinates_x: event.clientX,
        click_coordinates_y: event.clientY,
      });
    },
    jumpUrl(url) { window.open(url); },
  },
};
</script>

<style lang="scss" scoped>
/* 样式使用 SCSS + scopedpx 值基于 375 设计稿 */
</style>

第 5 步: 样式转换要点

将 Figma 设计数据转为 SCSS 时注意:

  1. 尺寸: 基于 375px 设计稿直接写 pxpx2rem 自动转换
  2. 颜色: 使用 Figma 给出的精确色值
  3. 图片: 大面积背景用 webp 格式,图标用 png
  4. 字体: Figma 字体映射到系统字体栈
  5. 布局: 优先 Flex 布局,配合 position: fixed 实现吸顶/吸底
  6. Vant 组件覆写: 使用 ::v-deep 覆盖 Vant 默认样式
  7. PC 端样式: 选择器加 pcm 前缀以避免 px2rem 转换

第 6 步: 注册组件

src/views/land/index.vue 中导入并注册新模板:

import mobileN from "./components/mobileN";
// 在 components 中注册

并在模板切换逻辑中添加对应条件。

第 7 步: 验证

  • 视觉与 Figma 截图对比一致
  • 移动端/PC 端分别测试
  • 下载按钮、社交链接、弹窗功能正常
  • 事件追踪正常上报
  • 图片资源加载无误

Figma 到 Vue 映射参考

Figma 属性 Vue/SCSS 对应
Auto Layout (横向) display: flex
Auto Layout (纵向) display: flex; flex-direction: column
Fill 颜色 background-color: #xxx
图片 Fill background: url("...") no-repeat; background-size: 100% 100%
固定位置 position: fixed
圆角 border-radius: Npx
文字样式 font-size, font-weight, line-height, color
阴影 box-shadow
间距 (Gap) gap: Npxmargin/padding
透明度 opacityrgba()