为了账号安全,请及时绑定邮箱和手机立即绑定

React应用的视觉编辑神器Onlook

Jude Miracle写✏️

设计与开发之间的差距常常令许多团队感到困扰。设计师使用 Figma 等工具创建美观的设计稿,但开发者发现很难使用传统的集成开发环境将这些设计稿变为可运行的代码。这种脱节现象有时会减缓开发速度,并可能导致误解和昂贵的修复。

Onlook 是一个新工具,能够通过将设计功能直接集成到您的开发环境中来帮助弥合这一差距。使用 Onlook,您可以优化工作流程,加强设计师和开发人员之间的协作,并更快、更准确地交付产品。

在这篇文章里,我们将探讨 Onlook,一个直接将设计功能带入开发环境的工具。我们将对比它与其他现有工具,比如 Figma 和 Webflow,并提供一个实用的设置教程。

Onlook是什么呀?

Onlook 是一个开源的视觉编辑器,专为 React 应用程序打造。它让开发人员可以在使用实时 React 组件时设计和调整用户界面。Onlook 提供了一个类似 Figma 的直接操作界面,提供了拖放编辑、实时预览和无缝代码生成。

使用 Onlook,开发人员可以直观地操作组件,调整样式设置,并实时查看变化,所有这些操作都直接在代码中进行。这种方式简化了设计与开发之间的交接流程,减少了不一致,并优化了整体工作流程。

与传统的设计工具或无代码构建器不同,Onlook 允许开发人员直接将其现有的 React 项目集成,并在保持完整开发控制的同时,享受可视编辑带来的好处。Onlook 相对来说是一个较新的工具,在 GitHub 上获得了超过 4.2k 星 的支持。该项目有超过 40 名贡献者,这意味着团队会定期推出更新和新功能。

丹麦观者功能
  • 在 React 应用中实时编辑组件: Onlook 允许你实时观察到你的更改如何影响应用的实际状态和行为,使用真实数据调整布局,并在进行设计更改时立即测试交互。
  • 实时设计编辑: Onlook 的实时编辑功能不仅限于基本样式调整,还包括组件定位和布局调整的拖放界面,实时预览 CSS 变更并立即得到反馈,交互调整元素大小并实时显示响应式断点,以及组件属性和状态的实时更新。
  • AI 聊天: Onlook 集成了 AI 聊天,以增强其功能。借助 AI,它可以基于当前工作推荐设计、颜色方案、布局和组件选择,并帮助用户快速开发想法。
  • 代码优先的方法: 其代码优先的方法确保你的视觉编辑能转化为干净且易于维护的 React 代码,可以直接编辑现有组件代码,无需生成不必要的包装元素或样式冗余,并在编辑时提供对组件属性、状态和方法的完全访问。
  • 与现有 React 项目兼容: Onlook 可以无缝集成到现有 React 项目中,支持任何 React 项目结构,支持现代 React 功能及流行的样式解决方案,如 Tailwind CSS、CSS 模块、Context 和 Hooks,并保留现有的构建和部署工作流程。
使用 Onlook 的好处有
  • Onlook帮助减少了在设计工具和代码编辑器之间切换的需求,并促进了更高效且集成的开发流程
  • 它允许快速尝试不同的布局、样式和交互
  • Onlook通过提供一种共享的视觉语言来弥合设计师和开发人员之间的差距,这使传达设计想法和确保一致性变得更加容易
  • 将其设计转换成React代码使得对React开发者来说,Onlook更加方便
前提条件

旁观是一款独立的应用程序,但要跟着本教程做:您还需要以下内容:

  • 一个像 VS Code 或 Cursor 这样的代码编辑器
  • 基本会使用终端运行命令
  • 设计基础和 React 有一定了解
项目启动

要开始使用Onlook,请按照如下步骤做:

  • 下载并安装 Onlook 桌面应用程序,选择适合你系统的版本。
  • 启动 Onlook 应用程序。 然后系统将提示你使用 GitHub 或 Google 账户进行注册或登录。
  • 创建一个新的 React 项目:

  • 给项目命名。

  • 选择应用的文件夹。

  • 设置完成后,你将被引导至设计应用的界面。
  • 启动开发服务器: 点击底部工具栏上的播放按钮。
  • 验证 URL: 确保 http://localhost:3000/ 指向正确的位置。如果它在浏览器中打开,也应该在 Onlook 应用程序中自动打开。
  • 检查终端: 你也可以打开终端确认应用是否正在运行。

运行后,你将看到应用的主页。Onlook界面示例图,现在我们的应用已经运行起来了,先熟悉一下Onlook界面,再开始设计我们的第一个应用。

理解Onlook界面是怎么回事

当你第一次启动Onlook时,你会看到一个集成了视觉编辑和代码功能的界面。这个界面有几个主要区域,每个区域在你的开发过程中都扮演着特定的角色。

主工作区主要有三个部分:

  • 组件画布位于中心位置,您可以在其中实时查看组件运行
  • 属性和AI聊天面板位于右侧,显示当前编辑元素的控制选项,包括一个可以和AI聊天的区域
  • 组件树导航器位于左侧,显示应用结构

另外,还有一些重要的内容。

  • 工具栏:位于界面底部的,包括选择元素的按钮、平移视图的按钮、插入对象和文本、启动程序及访问控制台或终端的按钮。

Onlook界面将设计与开发连接起来。你所做的任何设计调整都会立即反映到React代码中。任何代码的修改也会立即体现在设计上。这种双向联动就是Onlook与传统设计工具的主要区别。

从设计到编码

与传统的将设计导出为代码的工作流程不同,Onlook 保持了你的视觉编辑和 React 代码之间的实时同步。这带来了以下好处:

  • 可視化更改可讓您的 React 應用程序中的代碼立即更新
  • 代碼可以通過您喜歡的編輯器(例如 VS Code)訪問
  • 更改既可以通過可視化方式,也可以通過代碼進行,並保持同步

让我们把这分解成各个部分。当你在操作某个部件时,你可以做以下事情:

  • 在 Onlook 的界面上设计它
  • 点击“在 VS Code 中打开”以查看和编辑生成的代码
  • 在任一环境中进行修改
  • 立即在两个地方看到你的修改 Onlook Interface 2
组件的创建及管理

我们来用Onlook做一个待办事项列表的应用,来看看Onlook的视觉编辑器是如何跟React配合工作的。通过利用状态管理、用户交互和组件组合,这个例子能很好地展示Onlook的主要功能,做一个真正的应用。

当你开始在 Onlook 上进行设计时,你有两个选择:你可以直接使用可视化编辑器,或者你可以使用 Onlook 的 AI 助手。初学者或寻求指导的人可能会觉得 AI 助手很有帮助。你可以描述你想要的设计,AI 会帮助你创建一个基本的布局,你可以在此基础上进行改进:在 Onlook 中创建和管理组件 可视化编辑器让你可以拖放元素,调整样式,并立即看到效果。当你进行修改时,Onlook 会自动为你生成 React 代码。起始时,所有代码都会写入 page.tsx 文件,这只是一个初始点,但不适合用于实际生产环境。

应用程序结构 尽管 Onlook 的自动代码生成虽然很有用,但实际的应用程序需要更清晰的架构。为了解决此问题,我们可以采用这种方法来使用基于组件的架构。这将分离关注的方面,并使代码更易于维护。以下是我们如何组织项目的计划:

    app/
    ├── 页面.tsx
    └── 组件/
        ├── TodoContainer.tsx (这是一个包含待办事项的容器组件)
        ├── TodoForm.tsx (这是一个用于添加或编辑待办事项的表单组件)
        ├── TodoList.tsx (这是一个展示所有待办事项的列表组件)
        ├── TodoItem.tsx (这是一个展示单个待办事项的组件)
        └── types.ts (这是一个定义组件类型等类型的文件)

切换到全屏模式 退出全屏

此结构遵循 React 最佳实践,将用户界面拆分成清晰且可重用的组件。每个组件都有特定功能,使代码更有序和易懂。Onlook 中的 Types 组件

省略号

    // types.ts
    // 定义Todo接口
    export interface Todo {
        id: number;        // 任务的唯一标识
        text: string;      // 任务的描述文本
        completed: boolean; // 任务是否完成
    }

全屏 退出全屏

Onlook的页面组件

以下
(xià yǐ)

    // page.tsx
    import TodoContainer from './components/TodoContainer';

    export default function Page() {
        return (
            <div className="w-full min-h-screen bg-gradient-to-br from-purple-50 to-white dark:from-gray-900 dark:to-gray-800 p-4">
                <div className="max-w-2xl mx-auto">
                    <div className="text-center mb-8">
                        <h1 className="text-4xl font-bold text-purple-600 dark:text-purple-400 mb-2">
                            待办事项
                        </h1>
                        <p className="text-gray-600 dark:text-gray-300">
                            保持有条理和高效
                        </p>
                    </div>
                    <TodoContainer />
                </div>
            </div>
        );
    }

进入全屏,退出全屏

在Onlook中 待办事项容器 组件:

    // components/TodoContainer.tsx
    'use client';

    import { useState } from 'react';
    import TodoForm from './TodoForm';
    import TodoList from './TodoList';
    import { Todo } from './types';

    export default function TodoContainer() {
        const [todos, setTodos] = useState<Todo[]>([]);
        const [newTodo, setNewTodo] = useState('');

        const addTodo = (e: React.FormEvent) => {
            e.preventDefault();
            if (newTodo.trim()) {
                setTodos([
                    ...todos,
                    {
                        id: Date.now(),
                        text: newTodo.trim(),
                        completed: false,
                    },
                ]);
                setNewTodo('');
            }
        };

        const toggleTodo = (id: number) => {
            setTodos(
                todos.map((todo) => (todo.id === id ? { ...todo, completed: !todo.completed } : todo)),
            );
        };

        const deleteTodo = (id: number) => {
            setTodos(todos.filter((todo) => todo.id !== id));
        };

        return (
            <>
                <TodoForm
                    newTodo={newTodo}
                    setNewTodo={setNewTodo}
                    addTodo={addTodo}
                />
                <TodoList
                    todos={todos}
                    toggleTodo={toggleTodo}
                    deleteTodo={deleteTodo}
                />
            </>
        );
    }

点击进入全屏模式 点击退出全屏模式

在Onlook的 TodoForm 组件:

等等

    // components/TodoForm.tsx
    'use client';

    interface TodoFormProps {
        newTodo: string;
        setNewTodo: (value: string) => void;
        addTodo: (e: React.FormEvent) => void;
    }

    export default function TodoForm({ newTodo, setNewTodo, addTodo }: TodoFormProps) {
        return (
            <form onSubmit={addTodo} className="mb-8">
                <div className="flex gap-2">
                    <input
                        type="text"
                        value={newTodo}
                        onChange={(e) => setNewTodo(e.target.value)}
                        placeholder="请输入待办事项"
                        className="flex-1 p-3 rounded-lg border border-gray-300 dark:border-gray-600 
                                 bg-white dark:bg-gray-700 text-gray-900 dark:text-white
                                 focus:ring-2 focus:ring-purple-500 focus:border-transparent"
                    />
                    <button
                        type="submit"
                        className="px-6 py-3 bg-purple-600 text-white rounded-lg
                                 hover:bg-purple-700 focus:outline-none focus:ring-2
                                 focus:ring-purple-500 focus:ring-offset-2
                                 transition-colors duration-200"
                    >
                        添加任务
                    </button>
                </div>
            </form>
        );
    }

切换到全屏 退出全屏

在Onlook中 TodoList 组件如下


// components/TodoList.tsx
'use client';

import { Todo } from './types';
import TodoItem from './TodoItem';

interface TodoListProps {
    todos: Todo[];
    toggleTodo: (id: number) => void;
    deleteTodo: (id: number) => void;
}

export default function TodoList({ todos, toggleTodo, deleteTodo }: TodoListProps) {
    return (
        <div className="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6">
            {todos.length === 0 ? (
                <p className="text-center text-gray-500 dark:text-gray-400 py-8">
                    暂时还没有待办事项。试试在上面添加一个吧!
                </p>
            ) : (
                <ul className="space-y-3">
                    {todos.map((todo) => (
                        <TodoItem
                            key={todo.id}
                            todo={todo}
                            toggleTodo={toggleTodo}
                            deleteTodo={deleteTodo}
                        />
                    ))}
                </ul>
            )}

            {todos.length > 0 && (
                <div className="mt-6 pt-6 border-t border-gray-200 dark:border-gray-700">
                    <div className="flex justify-between text-sm text-gray-600 dark:text-gray-400">
                        <span>{todos.filter((t) => !t.completed).length} 剩余的事项</span>
                        <span>{todos.filter((t) => t.completed).length} 已完成的事项</span>
                    </div>
                </div>
            )}
        </div>
    );
}

全屏 退出全屏

Onlook的 TodoItem组件


    // components/TodoItem.tsx
    'use client';

    import { Todo } from './types';

    interface TodoItemProps {
        todo: Todo;
        toggleTodo: (id: number) => void;
        deleteTodo: (id: number) => void;
    }

    export default function TodoItem({ todo, toggleTodo, deleteTodo }: TodoItemProps) {
        return (
            <li className="flex items-center gap-3 bg-gray-50 dark:bg-gray-700/50 
                          p-4 rounded-lg group">
                <input
                    type="checkbox"
                    checked={todo.completed}
                    onChange={() => toggleTodo(todo.id)}
                    className="w-5 h-5 rounded border-gray-300 
                             text-purple-600 focus:ring-purple-500"
                />
                <span
                    className={`flex-1 ${
                        todo.completed
                            ? 'line-through text-gray-400 dark:text-gray-500'
                            : 'text-gray-700 dark:text-gray-200'
                    }`}
                >
                    {todo.text}
                </span>
                <button
                    onClick={() => deleteTodo(todo.id)}
                    className="opacity-0 group-hover:opacity-100 transition-opacity
                             text-red-500 hover:text-red-600 p-1"
                >
                    <svg
                        xmlns="http://www.w3.org/2000/svg"
                        className="h-5 w-5"
                        viewBox="0 0 20 20"
                        fill="currentColor"
                    >
                        <path
                            fillRule="evenodd"
                            d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
                            clipRule="evenodd"
                        />
                    </svg>
                </button>
            </li>
        );
    }

切换到全屏,退出全屏

Onlook的一个有用的功能是它能够双向连接可视化编辑器和代码。这是通过在开发过程中Onlook为组件添加一个特殊的data-oid属性来实现的:

    <TodoContainer data-oid="zshvwmp"/>

按Enter全屏,按Esc退出Fullscreen mode

此属性帮助Onlook跟踪组件变化,连接视觉元素与代码,实现双向实时更新,并在视觉编辑过程中保持组件功能。

在构建应用的过程中,你可以使用 Onlook 的视觉编辑器来优化设计而不影响代码质量。你可以更改组件布局、调整间距、调整颜色和字体,并测试应用在不同屏幕尺寸上的表现。

Onlook 在设计生态系统中扮演什么角色

网页开发工具满足不同的需求并适应各种工作流程。它们可以为设计和开发提供解决方案。为了了解Onlook的定位,我们将它与其他工具进行对比,突出其优缺点。

Onlook vs. Figma:传统设计工具的比较 传统设计工具在绘图、协同工作、原型制作和设计资源管理方面表现出色。Onlook则通过允许直接操作React组件、实时互动组件的状态和属性、生成可以直接用于生产的代码、无缝集成到开发流程以及在设计过程中积极测试组件的行为提供了一种不同的方式。

Onlook vs. Webflow: 无代码平台对比
无代码平台提供可视化的开发和代码导出功能,擅长快速原型设计、例如视觉CMS集成和内置托管。Onlook则直接集成到现有的React代码库中,保持组件逻辑,更注重开发者的使用体验,同时支持视觉编辑功能。它与开发工具集成,支持带有完整React功能的自定义组件,并生成干净的React代码,保持代码的整洁性。

直接在 React 内进行设计的优势
  • 开发者可以在设计过程中使用真实的数据和状态变化来观察组件的行为,这有助于他们发现交互问题和状态管理问题。
  • 使用React组件,开发者可以快速评估设计选择对性能的影响。
  • 设计师和开发者可以在不同的状态下智能地决定组件的外观,确保在设计过程中考虑所有可能的状态。
  • 在React中工作可以让设计师快速访问应用程序的属性系统和上下文,因此他们可以与真实的数据流进行交互。
  • 开发者可以在保持对组件逻辑和属性完全访问的同时,尝试不同的组件组合和组织方法。
结论部分

Onlook 改进了 React 生态系统中的工作流程。它加强了设计与开发团队之间的协作,并允许用户在不影响代码的情况下视觉编辑 React 组件。通过实时同步视觉更改和代码,Onlook 解决了各种常见工作流程中的问题。此外,其 AI 功能和无缝集成到现有 React 项目中的能力使其成为现代开发流程的有力工具。

尽管 Onlook 仍在不断改进,但它已经展现出了巨大的潜力。随着它不断添加新功能,它能够彻底改变 React 应用程序的构建方式。随着它不断添加新功能,它可能成为希望优化工作流程并更轻松地创建高质量用户体验的 React 开发者的重要工具。了解 Onlook 并在您的项目中尝试其 功能,亲身体验其带来的高效和便捷。


快速设置 LogRocket 的现代 React 错误跟踪,只需几分钟
  1. 访问 https://logrocket.com/signup/ 获取应用ID。
  2. 使用 NPM 或 script 标签安装 LogRocket。LogRocket.init() 必须在客户端调用,不要在服务器端调用。

NPM:Node.js 包管理器


$ npm i --save logrocket 

// 代码示例:

import LogRocket from 'logrocket'; // 导入 LogRocket 模块
LogRocket.init('app/id'); // 初始化 LogRocket 并传入应用ID

全屏进入 退出全屏

脚本标签,也就是我们常说的编写代码时使用的标签。

在你的HTML里加一下这个代码:

<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script> <!-- 初始化LogRocket(将'app/id'替换为实际应用ID) -->

点击进入全屏 按钮 点击退出全屏 按钮

3.(可选) 安装插件以更深入地集成到您的栈中

  • Redux 中间件插件
  • ngrx 中间件 (一种Angular的状态管理工具)
  • Vuex 插件

现在就开始吧

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消