当前位置: 首页 > news >正文

【VUE2】第三期——样式冲突、组件通信、异步更新

目录

1 scoped解决样式冲突

2 data写法

3 组件通信

3.1 父子关系

3.1.1 父向子传值 props

3.1.2 子向父传值 $emit

3.2 非父子关系

3.2.1 event bus 事件总线

3.2.2 跨层级共享数据 provide&inject

4 props

4.1 介绍 

4.2 props校验完整写法

5 v-model原理 

5.1 应用:表单类组件封装 

5.1.1 不用v-model的写法 

5.1.2 用v-model的写法

5.1.3 sync 修饰符

6 ref 与 $refs

6.1 获取dom元素

6.2 获取组件

7 Vue异步更新与$nextTick


1 scoped解决样式冲突

问题:

写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。

解决方法:

可以给组件加上scoped 属性,可以让样式只作用于当前组件

如: 

<style scoped></style>

scoped原理:

自动执行: 

  1. 当前组件内标签都被添加data-v-hash值 的属性

  2. css选择器都被添加 [data-v-hash值] 的属性选择器

最终效果:

     必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到


2 data写法

一个组件的 data 选项必须是一个函数

目的是为了:保证每个组件实例,维护独立的一份数据对象

每次创建新的组件实例,都会新执行一次data 函数,得到一个新对象

如:

<script>
export default {data: function () {return {count: 100,}},
}
</script>

3 组件通信

总结:

父子通信:

1.props & $emit 父向子传值,子通知父改值        3.1

        1.1 v-model简写(不可自定义属性值)        5.1.2

        1.2 sync简写(可自定义属性值)                 5.1.3

2.ref & $refs 父主动拿子的方法与属性                  6.2

非父子通信:

1.event bus 事件总线(任意组件)                       3.2.1

2.跨层级通信(同一家族组件)                             3.2.2


3.1 父子关系

父组件通过 props 将数据传递给子组件
子组件利用 $emit 通知父组件修改更新


3.1.1 父向子传值 props

步骤:

  1. 给子组件以添加属性的方式传值
  2. 子组件内部通过props接收
  3. 模板中直接使用 props接收的值

App.vue(父组件):

<template><!-- 主体区域 --><section id="app"><!--第一步:给子组件挂上list属性,并将值赋值给list属性--><TodoMain :list="list" @del="del"></TodoMain></section>
</template><script>
//...data() {return {list: [{id: 1, content: "吃饭"},{id: 2, content: "睡觉"},{id: 3, content: "打豆豆"}],}},}
</script>

TodoMain.vue(子组件):

注意:此处props为简略用法,完整写法见下文4.2 props校验完整写法

<template><!-- 列表区域 --><section class="main"><ul class="todo-list"><!--第三步:直接使用list变量--><li class="todo" v-for="(item, index) in list" :key="item.id"><!--...--></li></ul></section>
</template><script>
export default {//第二步:props接收数据(简略写法)props: ["list"],
}
</script>

3.1.2 子向父传值 $emit

(此处为子通知父,父为被动,下文中的$refs为父主动拿子) 

步骤

  1. $emit触发事件,给父组件发送消息通知

  2. 父组件监听$emit触发的事件

  3. 提供处理函数,在函数的性参中获取传过来的参数

 TodoMain.vue(子组件):

<template><!-- 列表区域 --><section class="main"><button @click="del(item.id)" ></button></section>
</template><script>
export default {
//...methods: {dela(id) {//第一步:触发delb事件this.$emit("delb", id1)}}
}
</script>

App.vue(父组件):

<template><!-- 主体区域 --><section id="app"><!--监听子组件触发的delb事件,监听到后执行delc函数,并将子组件传过来的id1值用id2接收--><TodoMain @delb="delc"></TodoMain></section>
</template><script>
//...
export default {//...methods: {delc(id2) {console.log(id2)},},}
</script>

此为最基本写法,可以进一步化简:使用v-model或sync修饰符,具体见 5 v-model原理 


3.2 非父子关系

3.2.1 event bus 事件总线

(任意两个组件之间的通信) 

 非父子组件之间,进行简易消息传递。(复杂场景→ Vuex)

Event Bus(事件总线)可以有多个发送方与多个接收方

 第一步:创建事件总线实例

首先创建一个新的 Vue 实例作为事件总线,通常命名为 eventBus

这个实例就像一个中央枢纽,负责管理所有的事件

因为 Vue 实例本身具有 $on(监听事件)、$emit(触发事件)和 $off(移除事件监听器)方法,所以可以利用这些方法来实现事件的发布和订阅

// EventBus.js
import Vue from 'vue'const Bus = new Vue()export default Bus

在使用Bus事件总线时,需要先导入Bus这个实例对象

import Bus from '../utils/EventBus'

第二步:订阅事件(监听事件):

在需要接收数据或响应某个事件的组件中,使用 Bus.$on 方法来监听特定的事件

$on 方法接受两个参数:

第一个参数是事件名称(字符串)

第二个参数是当事件触发时要执行的回调函数

// 组件 A 中监听事件
Bus.$on('sendMsg', (msg) => {this.msg = msg
})

第三步:发布事件(触发事件):

在需要发送数据或通知其他组件的组件中,使用 eventBus.$emit 方法来触发特定的事件

$emit 方法的参数:

第一个参数是事件名称(必须与要监听的事件名称一致)

后面参数不限制个数及数据类型,这些参数会传递给监听该事件的回调函数

Bus.$emit('sendMsg', '这是一个消息')

第四步:取消事件监听(移除事件监听器)

(选学)

在组件销毁或不再需要监听事件时,可以使用 Bus.$off 方法来移除事件监听器,防止内存泄漏

Bus.$off([event, callback])

参数说明:

event(可选):要移除的事件名,可以是一个字符串或一个包含多个事件名的数组。如果省略该参数,则会移除所有事件监听器

callback(可选):要移除的特定回调函数。如果省略该参数,则会移除该事件名下的所有回调函数


3.2.2 跨层级共享数据 provide&inject

(父子、爷孙等之间的通信) 

父组件 provide提供数据:

export default {provide () {return {// 普通类型【非响应式】color: this.color, // 复杂类型【响应式】userInfo: this.userInfo, }}
}

子/孙组件 inject获取数据:

export default {inject: ['color','userInfo'],created () {console.log(this.color, this.userInfo)}
}

注意:

provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式(推荐提供复杂类型数据)

子/孙组件通过inject获取的数据,不能在自身组件内修改

inject中的属性值值也可以写成对象形式,可以设置的值:

from 用于指定从祖先组件注入的属性名。如果不使用 from,则默认使用当前定义的属性名作为注入的属性名

default 用于指定注入属性的默认值,当祖先组件没有提供对应的属性时,会使用这个默认值

      inject: {// 使用 from 指定注入属性的来源名称myUserInfo: {from: 'userInfo',// 设置默认值default: {name: '默认姓名',age: 0}},// 没有使用 from,默认使用当前属性名注入someValue: {default: '默认值'}},

4 props

4.1 介绍 

定义:

组件上 注册的一些 自定义属性

作用:

向子组件传递数据

特点:

  1. 可以 传递 任意数量 的prop

  2. 可以 传递 任意类型 的prop


4.2 props校验完整写法

语法:

props: {校验的属性名: {type: 类型,  // Number String Boolean ...required: true, // 是否必填default: 默认值, // 默认值validator (value) {// 自定义校验逻辑return 是否通过校验}}
},

示例:

<script>
export default {// 完整写法(类型、默认值、非空、自定义校验)props: {w: {type: Number,//required: true,default: 0,validator(val) {// console.log(val)if (val >= 100 || val <= 0) {console.error('传入的范围必须是0-100之间')return false} else {return true}},},},
}
</script>

注意:

1.default和required一般不同时写(因为当时必填项时,肯定是有值的)

2.default后面如果是简单类型的值,可以直接写。如果是复杂类型的值,则需要以函数的形式return一个默认


5 v-model原理 

v-model本质上是一个语法糖。例如应用在输入框上,就是value属性 和 input事件 的合写

<template><div id="app" ><input v-model="msg" type="text"><input :value="msg" @input="msg = $event.target.value" type="text"></div>
</template>

注意:

1.$event 用于在模板中,获取事件的形参

2.不同的表单元素, v-model在底层的处理机制是不一样的,比如给checkbox使用v-model

底层处理的是 checked属性和change事件 


5.1 应用:表单类组件封装 

5.1.1 不用v-model的写法 

(此处就是父子组件通讯的方法 3.1) 

App.vue

<template><div class="app"><BaseSelect :selectId="selectId" @changeCity="selectId = $event"></BaseSelect></div>
</template><script>
import BaseSelect from './components/BaseSelect.vue'
export default {data() {return {selectId: '102',}},components: {BaseSelect,},
}
</script><style>
</style>

BaseSelect.vue

<template><div><select :value="selectId" @change="selectCity"><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {props: {selectId: String,},methods: {selectCity(e) {this.$emit('changeCity', e.target.value)},},
}
</script><style>
</style>

5.1.2 用v-model的写法

注意:使用前需要先基于5.1.1的代码稍作修改 

 App.vue

<template><div class="app"><!--1.给子组件挂在的属性名为:value 2.监听input事件--><BaseSelect :value="selectId" @input="selectId = $event"></BaseSelect></div>
</template><script>
import BaseSelect from './components/BaseSelect.vue'
export default {data() {return {selectId: '102',}},components: {BaseSelect,},
}
</script><style>
</style>

BaseSelect.vue

<template><div><!--绑定value值--><select :value="value" @change="selectCity"><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {props: {//接收value值value: String,},methods: {selectCity(e) {//更改所触发的事件为inputthis.$emit('input', e.target.value)},},
}
</script><style>
</style>

完成上述修改后,可以对父组件(App.vue)中的代码进行简化:

原:

<BaseSelect :value="selectId" @input="selectId = $event"></BaseSelect>

改:

<BaseSelect v-model="selectId" ></BaseSelect>

此种方法缺点也显而易见,固定死了属性名必须传value ,

以下方法可以自定义属性名


5.1.3 sync 修饰符

.sync修饰符 就是 :属性名@update:属性名 合写

<!--父组件-->
<!-- .sync写法 -->
<BaseDialog :visible.sync="isShow" />
--------------------------------------
<!-- 完整写法 -->
<BaseDialog :visible="isShow" @update:visible="isShow = $event" />

对比一下上面的v-model

:value=""               变成了        :属性名=""   

@事件类型=""       变成了        @update:属性名=""

因此在组件中可以使用自定义属性名了,

但是在子组件触发的事件变成了  update:属性名

//子组件
props: {visible: Boolean
},this.$emit('update:visible', false)

除此之外其他与上述一样,本质上还是最基本的props、$emit通信


6 ref 与 $refs

利用ref 和 $refs 可以用于 获取 dom 元素 或 组件实例  

查找范围 → 当前组件内(更精确稳定),

而之前用document.querySelect('.box') 获取的是整个页面中的盒子

6.1 获取dom元素

1.给要获取的盒子添加ref属性

<div ref="chartRef">我是渲染图表的容器</div>

2.恰当时机,通过 $refs获取 this.$refs.xxx 获取

console.log(this.$refs.chartRef)

恰当时机:指的是页面渲染完(mouted时期及以后) 


6.2 获取组件

1.给目标组件添加ref属性

<BaseForm ref="baseForm"></BaseForm>

2.恰当时机,通过 this.$refs.xxx 获取目标组件

this.$refs.baseForm.组件方法()this.$refs.baseForm.属性名

7 Vue异步更新与$nextTick

需求:

编辑标题, 编辑框自动聚焦

  1. 点击编辑,显示编辑框

  2. 让编辑框,立刻获取焦点

代码:

<template><div class="app"><div v-if="isShowEdit"><input type="text" v-model="editValue" ref="inp" /><button>确认</button></div><div v-else><span>{{ title }}</span><button @click="editFn">编辑</button></div></div>
</template><script>
export default {data() {return {title: '大标题',isShowEdit: false,editValue: '',}},methods: {editFn() {// 显示输入框this.isShowEdit = true  // 获取焦点this.$refs.inp.focus() }  },
}
</script> 

问题:

"显示之后",立刻获取焦点是不能成功的!

原因:Vue 是异步更新DOM (提升性能)

解决方案:

$nextTick:等 DOM更新后,才会触发执行此方法里的函数体

语法: this.$nextTick(函数体)

this.$nextTick(() => {this.$refs.inp.focus()
})

注意:$nextTick 内的函数体 一定是箭头函数,这样才能让函数内部的this指向Vue实例

相关文章:

【VUE2】第三期——样式冲突、组件通信、异步更新

目录 1 scoped解决样式冲突 2 data写法 3 组件通信 3.1 父子关系 3.1.1 父向子传值 props 3.1.2 子向父传值 $emit 3.2 非父子关系 3.2.1 event bus 事件总线 3.2.2 跨层级共享数据 provide&inject 4 props 4.1 介绍 4.2 props校验完整写法 5 v-model原理 …...

深度学习代码解读——自用

代码来自&#xff1a;GitHub - ChuHan89/WSSS-Tissue 借助了一些人工智能 2_generate_PM.py 功能总结 该代码用于 生成弱监督语义分割&#xff08;WSSS&#xff09;所需的伪掩码&#xff08;Pseudo-Masks&#xff09;&#xff0c;是 Stage2 训练的前置步骤。其核心流程为&a…...

Linux 配置静态 IP

一、简介 在 Linux CentOS 系统中默认动态分配 IP 地址&#xff0c;每次启动虚拟机服务都是不一样的 IP&#xff0c;因此要配置静态 IP 地址避免每次都发生变化&#xff0c;下面将介绍配置静态 IP 的详细步骤。 首先先理解一下动态 IP 和静态 IP 的概念&#xff1a; 动态 IP…...

Oxidized收集H3C交换机网络配置报错,not matching configured prompt (?-mix:^(<CD>)$)

背景&#xff1a;问题如上标题&#xff0c;H3C所有交换机配置的model都是comware 解决方案&#xff1a; 1、找到compare.rb [rootoxidized model]# pwd /usr/local/lib/ruby/gems/3.1.0/gems/oxidized-0.29.1/lib/oxidized/model [rootoxidized model]# ll comware.rb -rw-r--…...

RAG技术深度解析:从基础Agent到复杂推理Deep Search的架构实践

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…...

6.过拟合处理:确保模型泛化能力的实践指南——大模型开发深度学习理论基础

在深度学习开发中&#xff0c;过拟合是一个常见且具有挑战性的问题。当模型在训练集上表现优秀&#xff0c;但在测试集或新数据上性能大幅下降时&#xff0c;就说明模型“记住”了训练数据中的噪声而非学习到泛化规律。本文将从实际开发角度系统讲解如何应对过拟合&#xff0c;…...

【玩转23种Java设计模式】结构型模式篇:组合模式

软件设计模式&#xff08;Design pattern&#xff09;&#xff0c;又称设计模式&#xff0c;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...

专业工具,提供多种磁盘分区方案

随着时间的推移&#xff0c;电脑的磁盘空间往往会越来越紧张&#xff0c;许多人都经历过磁盘空间不足的困扰。虽然通过清理垃圾文件可以获得一定的改善&#xff0c;但随着文件和软件的增多&#xff0c;磁盘空间仍然可能显得捉襟见肘。在这种情况下&#xff0c;将其他磁盘的闲置…...

SELinux 概述

SELinux 概述 概念 SELinux&#xff08;Security-Enhanced Linux&#xff09;是美国国家安全局在 Linux 开源社区的帮助下开发的一个强制访问控制&#xff08;MAC&#xff0c;Mandatory Access Control&#xff09;的安全子系统。它确保服务进程仅能访问它们应有的资源。 例…...

【十三】Golang 通道

&#x1f4a2;欢迎来到张胤尘的开源技术站 &#x1f4a5;开源如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 通道通道声明初始化缓冲机制无缓冲通道代码示例 带…...

DeepSeek专题:DeepSeek-V2核心知识点速览

AIGCmagic社区知识星球是国内首个以AIGC全栈技术与商业变现为主线的学习交流平台&#xff0c;涉及AI绘画、AI视频、大模型、AI多模态、数字人以及全行业AIGC赋能等100应用方向。星球内部包含海量学习资源、专业问答、前沿资讯、内推招聘、AI课程、AIGC模型、AIGC数据集和源码等…...

Oracle19c进入EM Express(Oracle企业管理器)详细步骤

以下是使用Oracle 19c进入Oracle Enterprise Manager Database Express&#xff08;EM Express&#xff09;的详细步骤&#xff1a; ### **步骤 1&#xff1a;确认EM Express配置状态** 1. **登录数据库服务器** 使用Oracle用户或管理员权限账户登录操作系统。 2. **查看EM…...

游戏引擎学习第140天

回顾并为今天的内容做准备 目前代码的进展到了声音混音的部分。昨天我详细解释了声音的处理方式&#xff0c;声音在技术上是一个非常特别的存在&#xff0c;但在游戏中进行声音混音的需求其实相对简单明了&#xff0c;所以今天的任务应该不会太具挑战性。 今天我们会编写一个…...

C++--迭代器(iterator)介绍---主要介绍vector和string中的迭代器

目录 一、迭代器&#xff08;iterator&#xff09;的定义 二、迭代器的类别 三、使用迭代器 3.1 迭代器运算符 3.2 迭代器的简单应用&#xff1a;使用迭代器将string对象的第一个字母改为大写 3.3 将迭代器从一个元素移动到另外一个元素 3.4 迭代器运算 3.5 迭代器的复…...

RuleOS:区块链开发的“新引擎”,点燃Web3创新之火

RuleOS&#xff1a;区块链开发的“新引擎”&#xff0c;点燃Web3创新之火 在区块链技术的浪潮中&#xff0c;RuleOS宛如一台强劲的“新引擎”&#xff0c;为个人和企业开发去中心化应用&#xff08;DApp&#xff09;注入了前所未有的动力。它以独特的设计理念和强大的功能特性&…...

机器学习之强化学习

引言 在人工智能的众多分支中&#xff0c;强化学习&#xff08;Reinforcement Learning, RL&#xff09; 因其独特的学习范式而备受关注。与依赖标注数据的监督学习或探索数据结构的无监督学习不同&#xff0c;强化学习的核心是智能体&#xff08;Agent&#xff09;通过与环境…...

基于 uni-app 和 Vue3 开发的汉字书写练习应用

基于 uni-app 和 Vue3 开发的汉字书写练习应用 前言 本文介绍了如何使用 uni-app Vue3 uview-plus 开发一个汉字书写练习应用。该应用支持笔画演示、书写练习、进度保存等功能&#xff0c;可以帮助用户学习汉字书写。 在线演示 演示地址: http://demo.xiyueta.com/case/w…...

每天五分钟深度学习PyTorch:向更深的卷积神经网络挑战的ResNet

本文重点 ResNet大名鼎鼎,它是由何恺明团队设计的,它获取了2015年ImageNet冠军,它很好的解决了当神经网络层数过多出现的难以训练的问题,它创造性的设计了跳跃连接的方式,使得卷积神经网络的层数出现了大幅度提升,设置可以达到上千层,可以说resnet对于网络模型的设计具…...

electron + vue3 + vite 主进程到渲染进程的单向通信

用示例讲解下主进程到渲染进程的单向通信 初始版本项目结构可参考项目&#xff1a;https://github.com/ylpxzx/electron-forge-project/tree/init_project 主进程到渲染进程&#xff08;单向&#xff09; 以Electron官方文档给出的”主进程主动触发动作&#xff0c;发送内容给渲…...

《白帽子讲 Web 安全》之身份认证

目录 引言 一、概述 二、密码安全性 三、认证方式 &#xff08;一&#xff09;HTTP 认证 &#xff08;二&#xff09;表单登录 &#xff08;三&#xff09;客户端证书 &#xff08;四&#xff09;一次性密码&#xff08;OTP&#xff09; &#xff08;五&#xff09;多因…...

postgrel

首先按照惯例&#xff0c;肯定是需要对PostgreSQL数据库进行一系列信息收集的&#xff0c;常用的命令有以下这些&#xff1a;-- 版本信息select version();show server_version;select pg_read_file(PG_VERSION, 0, 200);-- 数字版本信息包括小版号SHOW server_version_num;SEL…...

Java基础——java8+新特性——方法引用(::)

1. 什么是方法引用&#xff1f; 定义&#xff1a;Java 8 引入的语法糖&#xff0c;用于 简化 Lambda 表达式&#xff0c;直接引用已有的方法。 符号&#xff1a;使用 :: 双冒号操作符。 本质&#xff1a;将方法作为函数式接口的实例传。 2. 方法引用的四种类型 类型 语法 …...

基于SpringBoot的商城管理系统(源码+部署教程)

运行环境 数据库&#xff1a;MySql 编译器&#xff1a;Intellij IDEA 前端运行环境&#xff1a;node.js v12.13.0 JAVA版本&#xff1a;JDK 1.8 主要功能 基于Springboot的商城管理系统包含管理端和用户端两个部分&#xff0c;主要功能有&#xff1a; 管理端 首页商品列…...

uniapp实现的个人中心页面(仿小红书)

采用 uniapp 实现的一款仿小红书个人中心页面模板&#xff0c;支持vue2、vue3, 同时适配H5、小程序等多端多应用。 简约美观大方 可到插件市场下载尝试&#xff1a; https://ext.dcloud.net.cn/plugin?id22516 示例...

K8s面试题总结(十一)

1.如何优化docker镜像的大小&#xff1f; 使用多阶段构建&#xff08;multi-stage build&#xff09;选择更小的基础镜像&#xff08;如alpine&#xff09;减少镜像层数&#xff0c;合并RUN命令 2.请解释Docker中的网络模式&#xff08;如bridge,host,none) Bridge&#xff…...

用CMake编译glfw进行OpenGL配置,在Visual Studio上运行

Visual Studio的下载 Visual Studio 2022 C 编程环境 GLFW库安装 GLFW官网地址 GLFW官网地址&#xff1a;https://www.glfw.org下载相应版本&#xff0c;如下图&#xff1a; CMake软件进行编译安装 下载CMake 下载的如果是源码包&#xff0c;需要下载CMake软件进行编译安装…...

仿12306项目(4)

基本预定车票功能的开发 对于乘客购票来说&#xff0c;需要有每一个车次的余票信息&#xff0c;展示给乘客&#xff0c;供乘客选择&#xff0c;因此首个功能是余票的初始化&#xff0c;之后是余票查询&#xff0c;这两个都是控台端。对于会员端的购票&#xff0c;需要有余票查询…...

【GPT入门】第9课 思维树概念与原理

【GPT入门】第9课 思维树概念与原理 1.思维树概念与原理2. 算24游戏的方法 1.思维树概念与原理 思维树&#xff08;Tree of Thought&#xff0c;ToT &#xff09;是一种大模型推理框架&#xff0c;旨在解决更加复杂的多步骤推理任务&#xff0c;让大模型能够探索多种可能的解决…...

uniapp登录用户名在其他页面都能响应

使用全局变量 1、在APP.vue中定义一个全局变量&#xff0c;然后在需要的地方引用它&#xff1b; <script>export default {onLaunch: function() {console.log(App Launch)this.globalData { userInfo: {} };},onShow: function() {console.log(App Show)},onHide: fu…...

一周热点-OpenAI 推出了 GPT-4.5,这可能是其最后一个非推理模型

在人工智能领域,大型语言模型一直是研究的热点。OpenAI 的 GPT 系列模型在自然语言处理方面取得了显著成就。GPT-4.5 是 OpenAI 在这一领域的又一力作,它在多个方面进行了升级和优化。 1 新模型的出现 GPT-4.5 目前作为研究预览版发布。与 OpenAI 最近的 o1 和 o3 模型不同,…...