6.1 KiB
6.1 KiB
name, description
| name | description |
|---|---|
| figma-to-landpage | 将 Figma 设计稿转换为 Vue 2 落地页组件。当用户提供 Figma 链接并要求生成落地页、实现设计稿、创建新模板时触发。适用于移动端和 PC 端落地页开发。 |
Figma 转落地页
将 Figma 设计稿翻译为本项目的 Vue 2 落地页组件,保持视觉还原度。
工作流程
第 1 步: 获取设计稿信息
从 Figma URL 中提取 fileKey 和 nodeId:
- URL 格式:
https://figma.com/design/:fileKey/:fileName?node-id=1-2 - 将
node-id中的-转为:
依次调用:
get_design_context(fileKey, nodeId)— 获取布局、颜色、字体等结构化数据get_screenshot(fileKey, nodeId)— 获取视觉截图作为还原参考
如果设计太复杂导致返回截断:
- 先调
get_metadata(fileKey, nodeId)获取节点树 - 对各子节点分别调
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 + scoped,px 值基于 375 设计稿 */
</style>
第 5 步: 样式转换要点
将 Figma 设计数据转为 SCSS 时注意:
- 尺寸: 基于 375px 设计稿直接写 px,px2rem 自动转换
- 颜色: 使用 Figma 给出的精确色值
- 图片: 大面积背景用 webp 格式,图标用 png
- 字体: Figma 字体映射到系统字体栈
- 布局: 优先 Flex 布局,配合
position: fixed实现吸顶/吸底 - Vant 组件覆写: 使用
::v-deep覆盖 Vant 默认样式 - 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: Npx 或 margin/padding |
| 透明度 | opacity 或 rgba() |