零基础 Coze + 前端 Vue3 边玩边开发:宠物冰球运动员生成器

引言

现如今 AI 应用开发变得越来越"平民化",即使你不懂任何深度学习,也能通过"玩"一些 AI 开发平台来做出一些有趣又智能的小工具。而这其中不得不提的就是**✨字节跳动推出的一站式AI应用开发平台 Coze 了**。

那为什么要选择 Coze 呢?那是因为其强大的低代码开发能力,即使是小白也可通过可视化界面"搭积木"一样编排工作流------比如上传图片、调用大模型、生成新图像等等,并且全程无需写复杂的后端或算法代码,极大降低了 AI 集成门槛💡。

拥有了工作流后,我们就可以使用优秀的现代前端框架 Vue3 ,通过其简洁的语法、响应式数据和组件化思想,让页面交互开发变得高效又直观。不仅向用户展示我们的开发成果,也要"接住"用户操作,最后再把结果展示出来。

本文就以"宠物变冰球运动员"为例,联合 Coze 的"AI 能力"与 Vue3 的"交互表现力" 来手把手教你如何使用这两项技术,从零搭建一个完整的 AI 应用。

项目简介

本项目是一个基于 Vue3 + Coze AI 工作流 的轻量级 Web 应用,实现用户上传一张宠物照片,选择队服编号、颜色、担任的位置、持杆手以及艺术风格,即可生成该宠物化身"冰球运动员"的图像。

核心功能:

  • 文件上传并预览
  • 用户配置参数(队服、风格等)
  • 调用 Coze 工作流进行 AI 处理
  • 返回生成的图像并展示

📂 项目结构说明

arduino 复制代码
project-root/
├── src/
│   ├── components/
│   └── App.vue          # 主页面组件
├── public/
│   └── index.html
├── vite.config.js
└── package.json

我们只用了一个主文件 App.vue 来完成全部功能,适合快速原型开发。

🤖 Coze 平台开发详解(低代码)

整体流程概述:

  1. 开始节点:接收所有输入数据。
  2. 图像理解节点:分析照片内容,提取宠物图片的关键特征。
  3. 特征提取节点:将特征转化为结构化的描述。
  4. 代码节点:处理用户提供的参数或生成默认值来描述一只宠物作为"冰球运动员"的外观和特性
  5. 图像生成节点:结合用户选择和图片特征来生成需要展现给用户的图片
  6. 结束节点:将生成的新图像展示给用户。

从输入图片开始,经过图像理解、特征提取、代码处理与图像生成,最终输出结果的完整流程


一、开始节点:

功能:流程入口,接收用户的原始输入数据,启动后续流程。

操作演示

输入参数

参数名 类型 是否必填 默认值 描述
picture Image --- ---
style String 写实 生成照片的艺术风格
uniform_number Number 10 运动员的号码
uniform_color String 球衣颜色
position Number --- 整数枚举,0、1、2,分别为守门员、前锋、后卫,默认随机
shooting_hand Number --- 持杆手,整数枚举0、1,分别为左手、右手,默认随机

二、图像理解节点:imgUnderstand

功能:使用AI模型分析图像内容。

操作演示

输入

  • text:这应该是一张宠物图片,请详细描述宠物的外貌特征。
  • url:选择从开始取到的图片

输出:通过"查看示例"可以查看输出效果

  • author:作者信息
  • content:图像描述文本
  • msg:返回消息

三、特征提取节点:

功能:对文本进行语义分析,提取关键词或结构化信息。

操作演示

模型:豆包·1.5 · Pro · 32k(默认即可)

技能:无需配置技能

输入 :连接图像理解节点 会自动配置 imgUnderstandcontent 字段为 input 中的变量值

系统提示词:为对话提供系统级指导,在此之中可以使用{{变量名}}等方式引用变量(此处我们导入文字提示词即可)

复制代码
你是动物学家,负责从动物描述中提取出该动物(主要是外表)里最有独特性的特征,例如特征的肤色、表情、神态、动作等等。

用户提示词 :向模型提供用户指令(此处我们导入输入变量input

css 复制代码
{{input}}

输出output(默认即可)


四、代码节点:

功能:执行自定义代码逻辑,这里我们需要处理用户提供的参数或生成默认值

操作演示

输入 :从开始节点 里面导入shooting_handstyleuniform_numberuniform_colorposition

代码逻辑

ts 复制代码
const random = (start: number, end: number) => {
    // 生成一个 [0, 1) 之间的随机数
    const p = Math.random();
    // 线性插值 + 向下取整
    // start * (1 - p) + end * p 只会让数据居于[start, end)之间
    // 再向下取整使数据只为整数并且小于end
    return Math.floor(start * (1 - p) + end * p);
}

//对用户传入的参数进行标准化处理和默认值填充,以便后续用于图像生成 prompt 的构建
async function main({ params }: Args): Promise<Output> {
    if (params.position == null) params.position = random(0, 3);
    if (params.shooting_hand == null) params.shooting_hand = random(0, 2);

    const style = params.style || '写实';
    const uniform_number:string = (params.uniform_number || 10).toString();
    const uniform_color = params.uniform_color || '红';
    const position = params.position  == 0 ? '守门员': (params.position == 1 ? '前锋': '后卫');
    const shooting_hand = params.shooting_hand == 0 ? '左手': '右手';
    const empty_hand = params.shooting_hand ? '左手': '右手';

    // 构建输出对象
    const ret = {
        style,
        uniform_number,
        uniform_color,
        position,
        shooting_hand,
    };

    return ret;
}

输出


五、图像生成节点:

功能:根据描述生成新图像。

操作演示

模型设置 :选择通用即可,比例按照自身喜好调节

参考图 :添加参考图,模型选择"形象一致",参考图选择开始节点中的 picture,程度调为 0.7

程度:决定了参考图对最终生成图像的影响程度。数值范围通常是从0到1,其中0表示完全不考虑参考图,而1表示尽可能地模仿参考图。

输入

  • description:图片描述,导入imgUnderstand节点中的content
  • 代码节点 里面导入处理后的shooting_handstyleuniform_numberuniform_colorposition
  • details:详细信息,导入特征提取节点 中的output

提示词:生成内容的提示词,分为两类

  • 正向提示词:引导生成内容
bash 复制代码
用动物的形象和特征,将该动物**拟人**为一名宠物儿童冰球员,生成{{style}}风格的冰球球员照片,球员身穿
{{uniform_color}}色队服,佩戴同色的冰球头盔,队服号码为{{uniform_number}}号,球员位置是{{position}},
用{{shooting_hand}}握着球杆,另一只手空着。该照片图像风格为{{style}}。

# 动物形象描述
{{description}}

# 独特外貌特征
{{details}}

# 注意
- 照片中应强化动物独特的外貌特征,以增加辨识度
- 如果球员位置是守门员,画面中应该有冰球球门
  • 反向提示词:排除不良或无关元素

    球员双手各握一根球杆
    球员未佩戴头盔
    球员吃东西
    画面中出现除了冰球之外的其他球类
    地点不在冰球赛场
    球员四足站立

输出

  • data:生成图像的二进制数据或URL
  • msg:状态信息

六、结束节点:

功能:工作流的最终节点,返回工作流运行后的结果信息。

操作演示

输出变量 :连接图像生成节点

  • output:最终结果,变量值为图像生成节点 中的data

回答内容:编辑智能体回复的内容,我们这里不修改直接输出图片(不需要流式输出)

lua 复制代码
{{output}}

流式输出:回复内容中的大语言模型的生成内容将会逐字流式输出;关闭后,回复内容将全部生成后一次性输出


测试:

在连接好工作流后,我们当然需要进行测试,以保证节点中没有发生错误

操作演示

后话:

当然,在你测试无误之后,可以点击右上角的发布来向别人分享你第一次创作的工作流。

发布之后,在你资源库中的工作流中就能找到你所发布的资源了。

💻 前端实现详解(Vue3 + JavaScript)

一、 <template> ------ 视觉层布局

首先我们确定组件的主要功能为---用户可以上传一张图片,并根据不同的参数(如队服编号、颜色等)进行个性化设置。

所以我们的UI布局,包括两块区域:输入区域(用于上传图片和选择参数)和 输出区域(展示生成的结果)。

html 复制代码
<template>
  <div class="container">
    <!-- 输入区域 -->
    <div class="input">
      <div class="file-input">
        <input type="file" ref="uploadImage" accept="image/*" @change="updateImageData" required />
      </div>
      <img :src="imgPreview" alt="" v-if="imgPreview" />
      <!-- 用户选择参数区域 -->
      <div class="settings">
        <div class="selection">
          <label>队服编号:</label>
          <input type="number" v-model="uniform_number" />
        </div>
        <div class="selection">
          <label>队服颜色:</label>
          <select v-model="uniform_color">
            <option value="红">红</option>
            <option value="蓝">蓝</option>
            <option value="绿">绿</option>
            <option value="白">白</option>
            <option value="黑">黑</option>
          </select>
        </div>
      </div>
      <div class="settings">
        <div class="selection">
          <label>位置:</label>
          <select v-model="position">
            <option value="0">守门员</option>
            <option value="1">先锋</option>
            <option value="2">后卫</option>
          </select>
        </div>
      </div>
      <div class="selection">
        <label>持杆:</label>
        <select v-model="shooting_hand">
          <option value="0">左手</option>
          <option value="1">右手</option>
        </select>
      </div>
      <div class="selection">
        <label>风格:</label>
        <select v-model="style">
          <option value="写实">写实</option>
          <option value="乐高">乐高</option>
          <option value="国漫">国漫</option>
          <option value="日漫">日漫</option>
          <option value="油画">油画</option>
          <option value="涂鸦">涂鸦</option>
          <option value="素描">素描</option>
        </select>
      </div>
      <div class="generate">
        <button @click="generate">生成</button>
      </div>
    </div>
    <!-- 输出区域 -->
    <div class="output">
      <div class="generated">
        <img :src="imgUrl" alt="" v-if="imgUrl">
        <div v-if="status">{{ status }}</div>
      </div>
    </div>
  </div>
</template>

1、输入部分(input):

html 复制代码
<input type="file" ref="uploadImage" accept="image/*" @change="updateImageData" required />

这段代码实现了 让用户选择本地文件并且触发预览更新

  • type="file":声明这是一个文件上传控件,点击后会弹出系统文件选择对话框。
  • accept="image/*"限制用户只能选择图片文件,防止无效输入。
  • @change="updateImageData":当用户选中一张图片后,会立即触发 updateImageData 方法(用于将图片文件转换为可以直接预览的 URL)
  • ref="uploadImage":为这个 input 元素注册一个 引用标识 ,方便在 <script setup> 中通过声明一个相同名称的 ref 变量 来直接访问该 DOM 元素。
  • required: 表示该字段是必填项
对比 refv-model:
  • v-model:同步"数据值",并且可以自动更新(关心的是"值"本身
  • ref:获取"DOM元素",而且需要手动更新(需要访问 DOM 的原生能力

⚠️并且在 <input type="file">中 无法使用 v-model

因为浏览器出于安全考虑,不允许 JS 设置 file input 的值,只能读取 。所以必须用 ref 来读取用户选中的文件。

html 复制代码
<img :src="imgPreview" alt="" v-if="imgPreview" />

在用户上传图片后,需要及时给予用户反馈(让用户知道自己行为驱动了页面,而不是毫无作用),所以需要展示预览图,让用户知道上传图片成功了。

  • :src="imgPreview":动态绑定响应式变量 imgPreview,用于自动更新图片。
  • v-if="imgPreview":条件渲染,只有当用户成功上传后才能渲染<img>元素,避免未上传时显示空白占位图。

2、用户选择参数部分(settings):

html 复制代码
  <div class="selection">
    <label>队服颜色:</label>
    <select v-model="uniform_color">
      <option value="红">红</option>
      ...
    </select>
  </div>

响应式的选择器,以便于用户选择参数

  • <label>队服颜色:</label>:提供文字说明,告诉用户这个下拉框的作用
  • <select>:HTML 的下拉选择控件
  • v-model="uniform_color"双向绑定 uniform_color 用于同步用户选择数据
  • <option value="红">红</option>:每个 <option> 代表一个可选项,该选项被选中时,赋给 uniform_color 的实际值就为红

3、输出部分(output):

html 复制代码
<img :src="imgUrl" alt="" v-if="imgUrl">

同上,绑定的响应式变量 imgUrl 用于返还 Coze 工作流生成后的图片

html 复制代码
<div v-if="status">{{ status }}</div>

显示当前操作的状态提示信息,为用户提供及时的反馈

  • v-if="status":只有当 status 有内容时才渲染
  • {{ status }}:将 status 的文本内容插入到页面中

二、<script setup> ------ 业务逻辑核心

基于业务需求,我们的开发流程总体为:定义响应式状态(数据层) --> 实现图片预览(本地交互) --> 实现文件上传到 Coze(前置依赖) --> 调用工作流生成图像(核心业务) --> 环境变量与 API 配置(支撑信息)

html 复制代码
<script setup>
import { ref, onMounted } from 'vue'

// --------------- 定义响应式状态 -------------------
const uniform_number = ref(10);
const uniform_color = ref('红');
const position = ref(0);
const shooting_hand = ref(0);
const style = ref('写实')
// 数据状态
const status = ref('');     // 反馈用户当前操作状态(空 / 上传中 / 生成中 / 错误)
const imgUrl = ref('');     // 用于存储最终生成的图片 URL
const imgPreview = ref(''); // 用于本地预览用户上传的原图

// --------------- 图片预览模块 -------------------
const uploadImage = ref(null);

onMounted(() => {
  console.log(uploadImage.value)
})
const updateImageData = () => {
  const input = uploadImage.value;
  if (!input.files || input.files.length === 0) {
    return;
  }
  const file = input.files[0];
  console.log(file);
  const reader = new FileReader();
  reader.readAsDataURL(file); 
  reader.onload = (e) => { 
    imgPreview.value = e.target.result;
  }
}


// --------------- 大厂常用业务请求 ----------------
const patToken = import.meta.env.VITE_PAT_TOKEN;
const uploadUrl = 'https://api.coze.cn/v1/files/upload';
const uploadFile = async () => {
  const formData = new FormData(); 
  const input = uploadImage.value;
  if (!input.files || input.files.length <= 0) return;
  formData.append('file', input.files[0]);

  const res = await fetch(uploadUrl, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${patToken}`
    },
    body: formData
  })

  const ret = await res.json();
  console.log(ret);

  if( ret.code !== 0) {
    status.value = ret.msg; 
    return
  }
  return ret.data.id;
}

// --------------- 生成图片模块 -------------------
const workflowUrl = 'https://api.coze.cn/v1/workflow/run';
const workflow_id = 'XXXXXXX';

const generate = async () => {
  status.value = "图片上传中..."
  const file_id = await uploadFile();
  if (!file_id) return;
  status.value = "图片上传成功,正在生成...";

// workflow 调用 
  const parameters = {
    picture: JSON.stringify({
      file_id
    }),
    style: style.value,
    uniform_color: uniform_color.value,
    uniform_number: uniform_number.value,
    position: position.value,
    shooting_hand: shooting_hand.value,
  }

  const res = await fetch(workflowUrl, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${patToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workflow_id,
      parameters
    })
  });
  const ret = await res.json();
  if( ret.code !== 0) {
    status.value = ret.msg;
    return;
  }

  const data = JSON.parse(ret.data);
  console.log(data);
  status.value = '';
  imgUrl.value = data.data;
}
</script>

1、定义响应式状态(数据层):

js 复制代码
// 用户选择参数,并且设定初始值
const uniform_number = ref(10);
const uniform_color = ref('红');
const position = ref(0);
const shooting_hand = ref(0);
const style = ref('写实')

// 数据状态
const status = ref(''); // 空 -> 上传中 -> 生成中 -> 生成成功
const imgUrl = ref(''); // 生成图片url

2、图片预览功能(本地交互):

js 复制代码
const uploadImage = ref(null);

onMounted(() => {
  console.log(uploadImage.value)
})
const updateImageData = () => {
  const input = uploadImage.value;
  if (!input.files || input.files.length === 0) {
    return;
  }
  const file = input.files[0];
  // console.log(file);
  const reader = new FileReader();
  reader.readAsDataURL(file); 
  reader.onload = (e) => { 
    imgPreview.value = e.target.result;
  }
}
定义响应式引用
js 复制代码
const uploadImage = ref(null);

标记模板中的 <input type="file">元素,未挂载前为 null,便于访问该DOM元素

生命周期钩子:组件挂载时执行的操作
js 复制代码
// null -> DOM对象 (变化)
onMounted(() => {
  console.log(uploadImage.value)
})

输出 uploadImage.value 到控制台,便于检查此时是否已经正确绑定了 <input> 元素。如果绑定成功,uploadImage.value 就指向上面的 <input> 元素。

更新图片数据方法
js 复制代码
// 用户选择文件后调用
const updateImageData = () => {
  const input = uploadImage.value;
  // console.log(uploadImage.value.files); 
  if (!input.files || input.files.length === 0) {
    return;
  }
  const file = input.files[0];
  // console.log(file);
  const reader = new FileReader();
  reader.readAsDataURL(file); 
  reader.onload = (e) => { 
    imgPreview.value = e.target.result;
  }
}
  • if (!input.files || input.files.length === 0) return;:判断用户上传的文件中是否至少包含一个文件
  • const file = input.files[0];:取出用户上传的第一个文件(因为不知道用户会上传多少文件,但是我们单次只能处理一个)
  • reader.readAsDataURL(file);:用新创建的 FileReader 实例上的 readAsDataURL 方法将文件转换为 Base64 编码的字符串(这种格式可以直接作为图像的URL使用)
  • reader.onload = (e) => { imgPreview.value = e.target.result; }:onload 是一个事件处理器(回调函数),会自动触发 load 事件,这里也就是事件对象 e,而e.target指的是触发该事件的对象(也就是reader),e.target.result就是转换为 Base64 编码的字符串,并且赋值给本地预览的响应式数据 imgPreview,这样页面上就会自动更新

⚠️ 注意:文件读取是异步的 ,不能直接写 let result = reader.readAsDataURL(file),必须用回调或 Promise。


3、文件上传至 Coze 云服务:

js 复制代码
const patToken = import.meta.env.VITE_PAT_TOKEN;
const uploadUrl = 'https://api.coze.cn/v1/files/upload';
// 先上传到coze服务器 
const uploadFile = async () => {
  // 创建一个空表单用于提交数据
  const formData = new FormData(); // FormData专门用于构建form-data格式数据的对象,常用于传输文件
  const input = uploadImage.value;
  if (!input.files || input.files.length <= 0) return;
  formData.append('file', input.files[0]);

  // 向 coze 发送http请求 上传
  const res = await fetch(uploadUrl, {
    method: 'POST', 
    headers: {
      'Authorization': `Bearer ${patToken}`
    },
    body: formData
  })

  // 等待返还内容(异步),并转换为json格式
  const ret = await res.json();
  // console.log(ret);

  // 错误判断
  if( ret.code !== 0) {
    status.value = ret.msg; 
    return;
  }
  return ret.data.id;
}
  • const patToken = import.meta.env.VITE_PAT_TOKEN;:获取认证令牌,在项目根目录中创建.env文件,在其中放置你的私有访问令牌。
  • const uploadUrl = 'https://api.coze.cn/v1/files/upload';:Coze 官方提供的文件上传 API 地址
  • formData.append('file', input.files[0]);:将用户选中的第一个文件附加到表单字段名为 file 的字段上

⚠️ 注意:Coze API 要求字段名必须是 'file',否则会报错

  • const res = await fetch(uploadUrl, {...}):向 Coze 上传文件
响应结构(Coze API 规范):
js 复制代码
  const ret = await res.json();

  // 错误判断
  if( ret.code !== 0) {
    status.value = ret.msg; 
    return;
  }
  return ret.data.id;

Coze 的 API 通常返回如下 JSON 结构:

json 复制代码
{
  "code": 0,
  "msg": "success",
  "data": {
    "id": "file-abc123xyz",   // ← 我们需要的 file_id
    "name": "cat.jpg",
    "size": 123456
  }
}
  • ret.code !== 0:判断是否出错(code === 0 表示成功)。
  • status.value = ret.msg:将错误信息显示给用户。
  • return ret.data.id:成功时返回 file_id(字符串),供后续工作流调用使用。

注: 这个 file_id 是 Coze 系统内部对文件的唯一引用,后续在调用工作流时,只需传递这个 ID,无需再传整个文件。


4、触发 Coze 工作流生成图像(核心业务):

js 复制代码
const workflowUrl = 'https://api.coze.cn/v1/workflow/run';
const workflow_id = 'XXXXXXX';

const generate = async () => {
  status.value = "图片上传中..."
  const file_id = await uploadFile();
  if (!file_id) return;
  status.value = "图片上传成功,正在生成...";

// workflow 调用 
  const parameters = {
    picture: JSON.stringify({
      file_id
    }),
    style: style.value,
    uniform_color: uniform_color.value,
    uniform_number: uniform_number.value,
    position: position.value,
    shooting_hand: shooting_hand.value,
  }

  const res = await fetch(workflowUrl, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${patToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workflow_id,
      parameters
    })
  });
  const ret = await res.json();
  if( ret.code !== 0) {
    status.value = ret.msg;
    return;
  }

  const data = JSON.parse(ret.data);
  console.log(data);
  status.value = '';
  imgUrl.value = data.data;
}
  • const workflowUrl = 'https://api.coze.cn/v1/workflow/run';:Coze 官方提供的 工作流执行 API 地址
  • const workflow_id = 'XXXXXXX';:你在 Coze 控制台创建的工作流的唯一 ID(在 Coze Bot 或 Workflow 编排界面可找到)
  • const file_id = await uploadFile();:取到返回的 file_id

为什么先上传?

Coze 的工作流无法直接处理前端的本地文件或 Base64,必须使用之前通过接口上传后返回的 file_id

解析最终图片 URL
js 复制代码
const data = JSON.parse(ret.data);
console.log(data);
status.value = '';
imgUrl.value = data.data;

❗ 为什么需要两次 JSON.parse

这是 Coze 工作流 API 的特殊设计

  • 第一层 ret.data 是一个 JSON 字符串 (不是对象!)

    js 复制代码
    ret.data === '{"data":"https://cdn.coze.com/generated.jpg"}'
  • 所以必须用 JSON.parse(ret.data) 得到真正的对象:

    js 复制代码
    const data = { data: "https://cdn.coze.com/generated.jpg" };

最终图片 URL 在 data.data 中。

📌 这是因为 Coze 工作流的输出通常被封装为字符串,确保兼容性


三、CSS 样式优化

css 复制代码
    .container {
      display: flex;
      flex-direction: row;
      align-items: start;
      justify-content: start;
      height: 100vh;
      font-size: .85rem;
    }

    .input {
      display: flex;
      flex-direction: column;
      min-width: 330px;
    }

    .output {
      margin-top: 10px;
      min-height: 300px;
      width: 100%;
      text-align: left;
    }

    .generated {
      width: 400px;
      height: 400px;
      border: solid 1px black;
      position: relative;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .output img {
      width: 100%;
    }

效果演示:

📚 学习资源推荐

类别 推荐内容
Vue3 Vue 官方文档
Coze Coze 开发者中心
REST API MDN Fetch API 文档
前端工程化 Vite、Webpack、JavaScript

📝 最后

这个项目不仅是一个简单的"AI图像生成器",更是现代 Web 开发的一个缩影:前端负责交互与体验,AI 提供智能能力,API 连接两者 😊,这也是当下的趋势:无代码/低代码 + 可视化 AI 编排 + 前端集成

AI 原生应用」的崛起

  • 传统 AI 开发:需要算法工程师 + 后端 + 前端,周期长、成本高。

  • 新范式(Coze 代表):

    • 业务人员/前端开发者 通过拖拽工作流,组合大模型、插件、知识库;
    • 前端直接调用工作流 API,像调用普通接口一样获取 AI 结果;
    • 无需维护后端服务,Coze 托管执行环境。

这就是 "AI as a Service"(AI 即服务)

相关推荐
LYFlied2 小时前
WebGPU与浏览器边缘智能:开启去中心化AI新纪元
前端·人工智能·大模型·去中心化·区块链
Setsuna_F_Seiei2 小时前
2025 年度总结:人生重要阶段的一年
前端·程序员·年终总结
model20053 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
后端小肥肠3 小时前
18条作品狂揽390万赞?我用Coze破解了“情绪放大镜”的流量密码
人工智能·aigc·coze
han_3 小时前
从一道前端面试题,谈 JS 对象存储特点和运算符执行顺序
前端·javascript·面试
aPurpleBerry3 小时前
React 01 目录结构、tsx 语法
前端·react.js
jayaccc4 小时前
微前端架构实战全解析
前端·架构
qingyun9894 小时前
Web Components 实战:创建自定义比例条组件
前端
前端小超超4 小时前
ionic + vue3 + capacitor遇到backButton问题
前端·javascript·vue.js
GIS之路4 小时前
GDAL 空间关系解析
前端