V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kongkongye
V2EX  ›  程序员

AI 生成前端组件的动手尝试💪

  •  1
     
  •   kongkongye ·
    kongkongye · 297 天前 · 3689 次点击
    这是一个创建于 297 天前的主题,其中的信息可能已经有所发展或是发生改变。

    上次帖子: AI 生成前端组件的价值思考🤔️

    目标

    1. 简单快速:比如你要亲自告诉 AI ,登录按钮设置成圆角,蓝色,那一点都不快速,有这时间样式代码都写好了。
    2. 可控:比如你直接跟 AI 说,请生成一个登录框,要好看大气,你提供的信息只有这么多,那 AI 生成出来的变数自然会很大,如果你是对结果有要求,那肯定不符合你的预期。

    整体设计思路

    1. 提供信息:比如组件名,描述,还有组件内有哪些元素,提供的信息完整了,AI 才能生成我们想要的组件。
    2. 预览结构:我叫它“渐进式”生成,即先让 AI 描绘一下即将生成的组件结构,然后我们在这基础上微调结构,再生成。要求一是格式简单,可读性强,修改起来容易;二是方便 AI 理解,不要引入过多新概念名词,综合考虑后发现 markdown 多级列表格式比较合适。
    3. 生成结果:组装提示词,让 AI 生成组件。

    如何变得更简单快速

    这是目标之一,我们让 AI 生成组件,是为了提高效率,但如果要提供的描述很多很精确,又很费时间。

    所以这里采取的一种解决办法就是让 AI 生成一些选项,我们再修改,这样就快多了,将题目从“思考题”变成了“选择题”😊。

    如何查看生成的组件

    生成代码后,如果要复制到自己项目里,改改代码才能用,那操作上就比较繁琐,所以想着自己在网页上集成个前端沙盒,可以查看生成的组件结果。

    另外再提供个模板项目,可以方便查看生成的组件。

    实践碰到的一些问题

    示例值问题,比如用户资料组件,要展示头像,名词,简介等信息,这些示例值可以手输也可以让 AI 生成,方便查看实际的效果。

    图片问题,如果我们不限制,AI 可能会生成一些不存在的图片链接,导致图片无法显示,所以我们可以让 AI 使用固定的图片地址来替代。

    图标问题,AI 可以生成 svg 内容,但那样太大了,会占用太多 token ,费用更高,而且容易导致生成因 token 限制而中断,所以我们可以让 AI 使用固定的图标组件来代替。此外,openai 的训练数据里也包括了热门的图标库,所以我们也可以让 AI 自己选取热门图标库里的图标来代替生成 svg 图标。

    生成的组件不符合要求怎么办

    这个要多方面考虑

    1. 如果是一些细节上的问题,可以直接改生成的代码
    2. 如果有异常无法运行,可以考虑重新生成,或者如果问题比较小就直接改代码
    3. 如果生成的布局结构不符合预期,可以调整第二步预览步骤里的结构描述
    4. 如果问题过大,可以考虑调整描述或不使用 AI 生成

    AI 适合生成哪些组件

    1. ❌基础组件,如输入框,按钮,下拉框等,这种一般使用 UI 库,而且 AI 也无法生成复杂的动效等。
    2. ✅高阶组件,这类组件一般由若干内容组装而成,像搭乐高积木一样,如登录表单,用户资料卡片,文章卡片等,这种是最适合的。
    3. ❌整个页面,如果你让 AI 直接生成整个页面,那 AI 会将页面内每个组件都给你生成了,这样不仅 token 消耗大,容易达到上限,而且组件的封装不好,每个组件可控性也会降低,所以还是让 AI 生成组件后,再自行拼凑在一起吧。

    实践展示

    提供信息

    1. 输入组件名:"a blog card"
    2. 让 AI 推荐业务对象字段,然后删掉不需要的
    3. 让 AI 生成示例值,不用改什么
    4. 让 AI 推荐组件内的元素(指按钮,链接之类的,业务对象外的),然后删掉不需要的

    预览结构

    1. 让 AI 生成预览结构,然后看看结构是否符合预期

    生成结果

    1. 可以看到,AI 按照预览结构来生成组件
    2. 组件内容展示了我们提供的示例值
    3. 我指定了图标库,AI 自动选取了图标

    生成的代码如下:

    为了方便使用,我将业务对象接口定义,示例值都塞组件代码里了。

    import React from 'react';
    import { FiShare2, FiHeart } from 'react-icons/fi';
    
    interface BlogCardProps {
      data: BlogCard;
    }
    
    export interface BlogCard {
      title: string;
      author: string;
      date: string;
      image: string;
      description: string;
      tags: string[];
    }
    
    export const Example: BlogCard = {
      "title": "📚 My Journey into Programming",
      "author": "👩‍💻 Jane Doe",
      "date": "📅 September 15, 2022",
      "image": "/avatar.png",
      "description": "📝 In this blog post, I will share my personal journey into programming and how it has changed my life. From my first line of code to becoming a professional developer, I will discuss the challenges, triumphs, and lessons learned along the way.",
      "tags": ["✨ Programming", "🌟 Career", "💡 Personal Development"]
    }
    
    const BlogCardComp: React.FC<BlogCardProps> = ({ data }) => {
      return (
        <article className="bg-white dark:bg-gray-800 rounded-lg shadow-md">
          <div className="relative">
            <img src={data.image} alt={data.title} className="w-full h-48 object-cover rounded-t-lg" />
          </div>
          <div className="p-4">
            <h3 className="text-xl font-semibold mb-2">{data.title}</h3>
            <div className="flex items-center mb-2">
              <span className="text-gray-600 dark:text-gray-400">{data.author}</span>
              <span className="mx-2 text-gray-400 dark:text-gray-600">|</span>
              <span className="text-gray-600 dark:text-gray-400">{data.date}</span>
            </div>
            <p className="text-gray-600 dark:text-gray-400">{data.description}</p>
            <div className="flex mt-4">
              {data.tags.map((tag, index) => (
                <span key={index} className="mr-2 text-gray-600 dark:text-gray-400">
                  {tag}
                </span>
              ))}
            </div>
          </div>
          <div className="flex justify-between items-center p-4">
            <a href="#" className="text-blue-500 hover:underline">
              Read More
            </a>
            <button className="text-gray-600 dark:text-gray-400">
              <FiShare2 className="w-4 h-4" />
            </button>
            <button className="text-gray-600 dark:text-gray-400">
              <FiHeart className="w-4 h-4" />
            </button>
          </div>
        </article>
      );
    };
    
    export default BlogCardComp;
    

    其他例子

    28 条回复    2023-08-09 14:26:28 +08:00
    xkongstore
        1
    xkongstore  
       297 天前 via Android
    可以看看对话吗🤔
    EthanLiu1993
        2
    EthanLiu1993  
       297 天前
    厉害了,现在有 demo 吗,想尝试一下
    lujiaosama
        3
    lujiaosama  
       297 天前
    能够指定组件库么, 比如 element-plus, antd-design 这种.
    gaobh
        4
    gaobh  
       297 天前 via iPhone
    我觉得用文生图再转组件比较简单哈哈
    luchenwei9266
        5
    luchenwei9266  
       297 天前
    @lujiaosama 外挂一个知识库?好像可以.....
    把一个框架塞进去,然后 prompt 告诉它,使用 xxxxx 框架生成一个 Button 组件....
    ZAnko
        6
    ZAnko  
       297 天前   ❤️ 1
    点赞,先收藏了,想一起参与[doge]
    kongkongye
        7
    kongkongye  
    OP
       297 天前 via iPhone
    @xkongstore prompt 吗?一方面这是动态的,另一方面这花精力调出来的也不想别人拿去就用,不好意思
    kongkongye
        8
    kongkongye  
    OP
       297 天前 via iPhone
    @EthanLiu1993 在准备部署了
    kongkongye
        9
    kongkongye  
    OP
       297 天前 via iPhone
    @lujiaosama 还没试,目前只调试了一些核心的东西
    kongkongye
        10
    kongkongye  
    OP
       297 天前 via iPhone
    @gaobh figma 就有插件将网页转设计,然后转代码,只是转了后有很多问题,每步都会失真,最终生成的代码勉强能看,但没法用,改来改去还不如直接照着 ui 手撸
    kongkongye
        11
    kongkongye  
    OP
       297 天前 via iPhone
    @luchenwei9266 如果是热门的框架,openai 训练时已经输入进去了,那是有戏,否则 token 不够描绘整个组件定义
    LavaC
        12
    LavaC  
       297 天前
    我们公司现有的组件库基本都是知名 UI 库的二次封装,也就是拼页面从拼 html 到拼 json ,每次写搜索项和表格就很烦,然后试了下用 ai 来处理,先复制原型上对应内容的 html 清洗掉标签,然后在 gpt 那边描述好这些清洗后的内容的对应含义和需要转换的内容,几秒就解决了这种垃圾工作内容。
    kongkongye
        13
    kongkongye  
    OP
       297 天前 via iPhone
    @LavaC 对的,就像 antd 这种强大复杂的,写表格一大片都是字段定义之类的,这种情况下 ui 无所谓了,主要就是内容展示与事件处理
    luchenwei9266
        14
    luchenwei9266  
       297 天前
    @kongkongye #11 不一定,看时间可能没有放进去(或者放进去的是旧版)。而且,外挂知识库的方法,可以让大模型更加有针对性。
    kongkongye
        15
    kongkongye  
    OP
       297 天前 via iPhone
    @luchenwei9266 是这样的,外挂就是 embedding 搜索,就是做着有些费力,技术上是这个思路
    gydi
        16
    gydi  
       297 天前
    我也有做类似的,只不过不是生成组件
    xuyihao
        17
    xuyihao  
       297 天前
    有同样的想法,目前公司正在往这方面去做,可以加个好友聊聊吗
    Guidoo
        18
    Guidoo  
       297 天前
    什么时候上线
    kongkongye
        19
    kongkongye  
    OP
       297 天前 via iPhone
    @xuyihao a29uZ2tvbmd5ZV8wMDI=
    kongkongye
        20
    kongkongye  
    OP
       297 天前 via iPhone
    @Guidoo 计划这周末
    manasheep
        21
    manasheep  
       297 天前
    应该把美工截图丢给它,自动生成代码,hh
    kongkongye
        22
    kongkongye  
    OP
       297 天前 via iPhone
    @manasheep 上面有回,从图片转代码,质量太差很难用
    shui14
        23
    shui14  
       297 天前
    adobe 以前有个 bracket ,挺有设计感的编辑器
    有一个功能,将设计稿生成静态页面,对于展示型的重设计非业务页面,很好用
    这完全可以重启,一个单独的业务,现在的前端完全失去了初心,没有考虑对人感受友好的交互
    shimada666
        24
    shimada666  
       297 天前
    这个看起来挺酷的啊,要是有 demo 了我也想试试
    kongkongye
        25
    kongkongye  
    OP
       297 天前 via iPhone
    @shimada666 👌🏻到时候 @你
    ZAnko
        27
    ZAnko  
       294 天前
    EthanLiu1993
        28
    EthanLiu1993  
       292 天前
    @kongkongye 厉害了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1136 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 22:53 · PVG 06:53 · LAX 15:53 · JFK 18:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.