阅读视图

发现新文章,点击刷新页面。

美关税压力难阻增势 南非汽车出口创新高

南非汽车商业委员会17日发布报告显示,尽管美国加征关税对南非汽车业造成影响,但南非汽车出口在2025年仍实现增长,出口量创历史新高。南非汽车商业委员会在其最新季度汽车制造业商业状况回顾报告中说,南非2025年共对全球109个国家和地区出口创纪录的41.43万辆汽车,较2024年增长5.9%。

四川:正月初一全省A级景区迎客超767万人次

2月17日,2026年春节假期第三日(正月初一),四川省文旅市场平稳规范有序运行,在团圆喜庆的氛围中迎来首个出游高峰。截至15时,全省纳入统计的873家A级景区接待游客767.67万人次、门票收入4834.33万元。其中,5A级旅游景区接待游客65.49万人次、实现门票收入1346.14万元。假日前三天累计接待游客1756.96万人次,门票收入11304.84万元。全省图书馆、文化馆、博物馆17日接待群众155.5万人次,第一天至第三天累计接待群众267.38万人次。

Flutter 为什么能运行在 HarmonyOS 上

335328e4fabd7656e8f1e9587269d3a4.jpeg

前言

Flutter 是 Google 推出的跨平台 UI 框架,最初只支持 iOS 和 Android。随着 HarmonyOS 的崛起,Flutter 也能在鸿蒙系统上运行了。这背后到底是怎么实现的呢?本文将从源码层面进行解析。


一、核心原理:Flutter 分层架构

要理解 Flutter 如何在 HarmonyOS 上运行,首先需要了解 Flutter 的架构。Flutter 采用分层设计,从上到下分为三层:

┌─────────────────────────────────┐
│   Framework 层(Dart)           │  ← Flutter 代码
├─────────────────────────────────┤
│   Engine 层(C++)               │  ← 渲染引擎(Impeller)
├─────────────────────────────────┤
│   Embedder 层(平台相关)         │  ← 与操作系统交互(调用 HarmonyOS 原生 API)
└─────────────────────────────────┘

前面两层完全复用现有Dart和C++代码,而 Embedder 层则是为 HarmonyOS 定制的。

关键点:Embedder 层

Embedder 层是 Flutter 能够跨平台运行的关键。它负责:

  • 创建和管理窗口

  • 处理输入事件

  • 调用系统 API

  • 管理渲染 Surface

**不同平台有不同的 Embedder 实现: **

  • Android:platform_view_android.cc

  • iOS:platform_view_ios.mm

  • HarmonyOS:platform_view_ohos.cpp


cc和cpp是标准的C++语言代码后缀

鸿蒙的系统API是C++ 实现的,所以鸿蒙platform_view 使用C++实现进行调用最方便**

二、HarmonyOS Embedder 的核心实现

让我们看看 HarmonyOS Embedder 的核心代码结构:

2.1 平台视图(PlatformViewOHOS)

这是 HarmonyOS Embedder 的核心类,位于: engine/src/flutter/shell/platform/ohos/platform_view_ohos.cpp

class PlatformViewOHOS final : public PlatformView {
 public:
  PlatformViewOHOS(PlatformView::Delegate& delegate,
                   const flutter::TaskRunners& task_runners,
                   const std::shared_ptr<PlatformViewOHOSNapi>& napi_facade,
                   const std::shared_ptr<flutter::OHOSContext>& ohos_context);

  // 通知窗口创建
  void NotifyCreate(fml::RefPtr<OHOSNativeWindow> native_window); 

  // 更新显示尺寸
  void UpdateDisplaySize(int width, int height);

  // 分发平台消息
  void DispatchPlatformMessage(std::string name, void* message, ...);
 private:
  std::shared_ptr<OHOSContext> ohos_context_;  // HarmonyOS 图形上下文
  std::shared_ptr<PlatformViewOHOSNapi> napi_facade_;  // NAPI装饰器(NAPI 是 HarmonyOS 提供的 JavaScript 接口, 用于调用 HarmonyOS 系统 API
  std::unique_ptr<OHOSSurface> ohos_surface_;  // HarmonyOS 渲染 Surface, surface 是渲染的目标画布, 可以是窗口, 也可以是离屏缓冲区
};

**这个类做了什么? **

  1. 继承自 PlatformView(Flutter 的通用平台视图接口)

  2. 持有 HarmonyOS 的图形上下文 OHOSContext

  3. 持有 NAPI装饰器 PlatformViewOHOSNapi(用于调用 HarmonyOS 原生 API)

  4. 管理渲染 Surface OHOSSurface

2.2 Shell 持有者(OHOSShellHolder)

Shell 是 Flutter 引擎的核心,负责管理 Flutter 应用的生命周期、渲染循环、事件处理等, OHOSShellHolder 负责创建和管理 Shell:

class OHOSShellHolder {
 public:
  // 构造函数
  // settings: Flutter 引擎启动参数(如是否启用 Impeller、日志级别等)

  // napi_facade: 与 HarmonyOS 原生层交互的 NAPI 装饰器

  // platform_loop: HarmonyOS 平台线程的 looper,用于投递平台任务
  OHOSShellHolder(const flutter::Settings& settings,
                  std::shared_ptr<PlatformViewOHOSNapi> napi_facade,
                  void* platform_loop);

  // 析构函数:确保 Shell 安全退出并释放所有资源
  ~OHOSShellHolder();
 
  // 启动 Flutter 引擎,加载 Dart 代码并开始渲染
  // hap_asset_provider: HarmonyOS HAP 包资源提供器,用于读取 assets、fonts、kernel_blob 等
  // entrypoint: Dart 入口函数名(默认为 main)

  // libraryUrl: Dart 库 URI(如 package:my_app/main.dart)

  // entrypoint_args: 传给 Dart main 的命令行参数列表

  void Launch(std::unique_ptr<OHOSAssetProvider> hap_asset_provider,
              const std::string& entrypoint,
              const std::string& libraryUrl,
              const std::vector<std::string>& entrypoint_args);
  // 优雅地停止 Flutter Shell,等待所有任务完成后退出
  void Shutdown();
  // 获取 PlatformViewOHOS 的弱引用,用于在平台线程安全地访问平台视图
  fml::WeakPtr<PlatformViewOHOS> GetPlatformView();
  // 设置应用生命周期回调,供 HarmonyOS 通知 Flutter 前后台切换
  void SetLifecycleHandler(std::function<void(AppLifecycleState)> handler);
  // 设置平台消息回调,供 HarmonyOS 主动发消息到 Dart 侧
  void SetPlatformMessageHandler(
      std::function<void(const std::string& channel,
                         const std::vector<uint8_t>& message,
                         std::function<void(std::vector<uint8_t>)> reply)> handler);
  // 向 Dart 侧发送平台消息,支持异步回调
  void SendPlatformMessage(const std::string& channel,
                           const std::vector<uint8_t>& message,
                           std::function<void(std::vector<uint8_t>)> reply = nullptr);
  // 通知 Flutter 引擎窗口尺寸变化,触发重新布局
  void NotifyViewportMetricsChanged(const ViewportMetrics& metrics);
  // 通知 Flutter 引擎内存压力,触发 Dart 侧 GC 或资源释放
  void NotifyLowMemoryWarning();
  // 获取当前 Shell 的运行状态
  enum class ShellState { kNotStarted, kRunning, kShuttingDown, kStopped };
  ShellState GetShellState() const;
  // 返回当前线程安全的 Shell 指针,仅用于调试或测试
  Shell* GetShellUnsafe() const { return shell_.get(); }
 private:
  // 创建并配置 Flutter Shell,内部调用 Shell::Create
  void CreateShell(const flutter::Settings& settings,
                   std::unique_ptr<OHOSAssetProvider> asset_provider);
  // 初始化平台任务执行器,将 HarmonyOS 平台任务映射到 Flutter 的任务队列
  void SetupTaskRunners(void* platform_loop);
  // 注册 HarmonyOS 平台视图到 Shell,完成平台桥接
  void RegisterPlatformView();
  // 加载 Dart AOT 或 Kernel,决定运行模式(Release/Profile 使用 AOT,Debug 使用 Kernel)
  void LoadDartCode(const std::string& entrypoint,
                    const std::string& libraryUrl,
                    const std::vector<std::string>& entrypoint_args);
  // 释放所有资源,顺序:PlatformView → Shell → TaskRunners
  void Teardown();
 private:
  std::unique_ptr<Shell> shell_;                         // Flutter 引擎核心
  std::shared_ptr<PlatformViewOHOSNapi> napi_facade_;  // NAPI 装饰器
  fml::WeakPtrFactory<OHOSShellHolder> weak_factory_;    // 弱引用工厂,防止悬空指针
  ShellState state_ = ShellState::kNotStarted;           // 当前 Shell 状态
  flutter::TaskRunners task_runners_;                    // 跨平台任务队列(UI/GPU/IO/Platform)
  std::mutex state_mutex_;                               // 保护 state_ 的线程安全
};

三、图形渲染适配

Flutter 在 HarmonyOS 上支持三种渲染方式:

3.1 鸿蒙三种渲染方式

enum class OHOSRenderingAPI {
  kSoftware,          // 软件渲染, 基于 CPU 进行渲染, 性能较低, 不依赖于 GPU,适用于简单场景。
  kOpenGLES,          // OpenGL ES 渲染(Skia), 基于 OpenGL ES 进行渲染, 性能较高, 依赖于 GPU, 适用于复杂场景。
  kImpellerVulkan,    // Vulkan 渲染(Impeller), 基于 Vulkan 进行渲染, 性能最高, 依赖于 GPU, 适用于需要高性能渲染的场景。
};

platform_view_ohos.cpp 中,根据渲染方式创建不同的Surface

std::unique_ptr<OHOSSurface> OhosSurfaceFactoryImpl::CreateSurface() {
  switch (ohos_context_->RenderingApi()) {
    case OHOSRenderingAPI::kSoftware:
      return std::make_unique<OHOSSurfaceSoftware>(ohos_context_); // 软件渲染, 基于 CPU 进行渲染, 性能较低, 不依赖于 GPU,适用于简单场景。
    case OHOSRenderingAPI::kOpenGLES:
      return std::make_unique<OhosSurfaceGLSkia>(ohos_context_); // OpenGL ES 渲染(Skia), 基于 OpenGL ES 进行渲染, 性能较高, 依赖于 GPU, 适用于复杂场景。
    case flutter::OHOSRenderingAPI::kImpellerVulkan:
      return std::make_unique<OHOSSurfaceVulkanImpeller>(ohos_context_); // Vulkan 渲染(Impeller), 基于 Vulkan 进行渲染, 性能最高, 依赖于 GPU, 适用于需要高性能渲染的场景。
    default:
      return nullptr;
  }
}

3.2 原生窗口(OHOSNativeWindow)

HarmonyOS 的窗口系统通过 OHNativeWindow 暴露给 Flutter:

class OHOSNativeWindow : public fml::RefCountedThreadSafe<OHOSNativeWindow> {
 public:
  Handle Gethandle() const// 获取 HarmonyOS 原生窗口句柄
  bool IsValid() const;      // 检查窗口是否有效
  SkISize GetSize() const;   // 获取窗口尺寸
 private:
  Handle window_;  // OHNativeWindow*
};

**渲染流程: **

Flutter Engine
    ↓
PlatformViewOHOS
    ↓
OHOSSurface(根据渲染方式创建不同的Surface)
    ↓
OHOSNativeWindow(HarmonyOS 原生窗口)
    ↓
HarmonyOS 图形系统

025444

四、输入事件处理

因为事件处理需要在渲染完成后(VSync同步流程)才能触发, 否则会导致事件处理与渲染不一致的问题。

4.1 VSync 同步

VSync(垂直同步)信号是渲染的关键,它是每次屏幕刷新周期开始时发送的信号,用于同步渲染和显示。

Flutter 需要等待系统的 VSync 信号,才能触发下一帧渲染。

class VsyncWaiterOHOS final : public VsyncWaiter {
 public:
  explicit VsyncWaiterOHOS(const flutter::TaskRunners& task_runners,
                           std::shared_ptr<bool>& enable_frame_cache);

 private:
  OH_NativeVSync* vsync_handle_;  // HarmonyOS VSync 句柄
  void AwaitVSync() override// 等待 VSync 信号
  static void OnVsyncFromOHOS(long long timestamp, void* data); // 接收 HarmonyOS VSync 信号, 通知 Flutter Engine 触发下一帧渲染
};

**工作流程: **

HarmonyOS VSync 信号
    ↓
VsyncWaiterOHOS::OnVsyncFromOHOS
    ↓
通知 Flutter Engine
    ↓
触发下一帧渲染
    ↓
渲染完成
    ↓
触发事件处理

4.2 触摸事件处理

HarmonyOS 的输入事件需要转换为 Flutter 的事件格式:

触摸事件通过 OhosTouchProcessor 处理:

class OhosTouchProcessor {
 public:
  // 处理 HarmonyOS 触摸事件
  void ProcessTouchEvent(const OH_NativeXComponent_TouchEvent* event);
 private:
  // 转换为 Flutter 触摸事件格式
  std::vector<PointerData> ConvertToFlutterTouchEvents(
      const OH_NativeXComponent_TouchEvent* event);
};

五、平台消息通信

Flutter 与 HarmonyOS 的通信通过 Platform Channel 实现:

5.1 NAPI 装饰器(PlatformViewOHOSNapi)

NAPI(Native API)是 HarmonyOS 提供的原生 API 接口:

class PlatformViewOHOSNapi {
 public:
  // 发送平台消息到 HarmonyOS
  void SendPlatformMessage(const std::string& channel,
                           const std::vector<uint8_t>& message);
  // 接收来自 HarmonyOS 的平台消息
  void SetPlatformMessageHandler(
      std::function<void(const std::string&, const std::vector<uint8_t>&)> handler);
 private:
  napi_env env_;  // NAPI 环境
};

5.2 消息处理流程

Flutter 代码(Dart)
    ↓
MethodChannel.invokeMethod
    ↓
PlatformViewOHOS::DispatchPlatformMessage
    ↓
PlatformViewOHOSNapi::SendPlatformMessage
    ↓
HarmonyOS 原生代码(ArkTS/C++)
    ↓
返回结果
    ↓
Flutter 接收响应

六、完整的工作流程

让我们把所有部分串联起来,看看 Flutter 应用在 HarmonyOS 上是如何运行的:

6.1 初始化流程

1. HarmonyOS 应用启动
    ↓
2. 调用 OhosMain::NativeInit(NAPI 入口)
    ↓
3. 创建 OHOSShellHolder
    ↓
4. 创建 PlatformViewOHOS
    ↓
5. 创建 OHOSContext(图形上下文)
    ↓
6. 创建 OHOSSurface(渲染表面)
    ↓
7. 创建 Flutter Shell(引擎)
    ↓
8. 加载 Dart 代码
    ↓
9. 开始渲染

6.2 渲染流程

1. Dart 代码构建 Widget 树
    ↓
2. Framework 层生成 Layer 树
    ↓
3. Engine 层生成 Scene
    ↓
4. Impeller 渲染引擎绘制
    ↓
5. 通过 OHOSSurface 提交绘制指令
    ↓
6. OHOSNativeWindow 接收绘制结果
    ↓
7. HarmonyOS 图形系统显示到屏幕

6.3 事件处理流程

1. 用户触摸屏幕
    ↓
2. HarmonyOS 接收触摸事件
    ↓
3. OhosTouchProcessor 处理
    ↓
4. 转换为 Flutter 触摸事件格式
    ↓
5. PlatformViewOHOS 分发事件
    ↓
6. Framework 层处理事件
    ↓
7. Widget 响应用户操作

七、关键代码示例

7.1 创建 HarmonyOS Embedder

// 创建图形上下文
std::unique_ptr<OHOSContext> CreateOHOSContext(
    const flutter::TaskRunners& task_runners,
    OHOSRenderingAPI rendering_api,
    bool enable_vulkan_validation,
    bool enable_opengl_gpu_tracing,
    bool enable_vulkan_gpu_tracing) {
  switch (rendering_api) {
    case OHOSRenderingAPI::kSoftware:
      return std::make_unique<OHOSContext>(OHOSRenderingAPI::kSoftware);
    case OHOSRenderingAPI::kOpenGLES:
      return std::make_unique<OhosContextGLSkia>(OHOSRenderingAPI::kOpenGLES,
                                                 task_runners);
    case OHOSRenderingAPI::kImpellerVulkan:
      return std::make_unique<OHOSContextVulkanImpeller>(
          enable_vulkan_validation, enable_vulkan_gpu_tracing);
    default:
      return nullptr;
  }
}
// 创建平台视图
PlatformViewOHOS::PlatformViewOHOS(
    PlatformView::Delegate& delegate,
    const flutter::TaskRunners& task_runners,
    const std::shared_ptr<PlatformViewOHOSNapi>& napi_facade,
    const std::shared_ptr<flutter::OHOSContext>& ohos_context)
    : PlatformView(delegate, task_runners),
      napi_facade_(napi_facade),
      ohos_context_(ohos_context) {
  // 创建 Surface 工厂
  surface_factory_ = std::make_shared<OhosSurfaceFactoryImpl>(ohos_context_);
  // 创建渲染 Surface
  ohos_surface_ = surface_factory_->CreateSurface();
  // 预加载 GPU Surface(加速首帧渲染)
  task_runners_.GetRasterTaskRunner()->PostDelayedTask(
      [surface = ohos_surface_]() { surface->PrepareGpuSurface(); },
      fml::TimeDelta::FromMicroseconds(1000));
}

7.2 通知窗口创建

void PlatformViewOHOS::NotifyCreate(
    fml::RefPtr<OHOSNativeWindow> native_window) {
  FML_LOG(INFO) << "NotifyCreate start";
  // 缓存原生窗口
  native_window_ = native_window;
  // 通知 Surface 窗口已创建
  ohos_surface_->SetNativeWindow(native_window);
  // 获取窗口尺寸
  SkISize size = native_window->GetSize();
  // 更新视口尺寸
  UpdateDisplaySize(size.width(), size.height());

  // 通知 Flutter 引擎窗口已创建
  NotifyCreated();
}

7.3 处理平台消息

void PlatformViewOHOS::DispatchPlatformMessage(
    std::string name,
    void* message,
    int messageLength,
    int responseId) {
  // 创建平台消息
  fml::MallocMapping buffer = fml::MallocMapping(
      static_cast<const uint8_t*>(message), messageLength);
  auto platform_message = std::make_unique<PlatformMessage>(
      name,
      std::move(buffer),
      responseId,
      fml::TimePoint::Now());
  // 分发到 Flutter 引擎
  DispatchPlatformMessage(std::move(platform_message));
}

八、为什么 Flutter 能在 HarmonyOS 上运行?

通过上面的代码分析,我们可以总结出以下几个关键原因:

8.1 架构设计优势

Flutter 的分层架构设计使得 Embedder 层可以独立适配不同平台:

  • Framework 层Engine 层是平台无关的

  • 只有 Embedder 层需要针对不同平台实现

8.2 HarmonyOS 提供的开放接口

HarmonyOS 提供了丰富的原生 API,使得 Flutter 可以:

  • 通过 OHNativeWindow 获取窗口句柄

  • 通过 OH_NativeVSync 获取 VSync 信号

  • 通过 NAPI 调用系统能力

  • 通过 XComponent 组件集成 Flutter 视图

8.3 图形接口兼容

HarmonyOS 支持标准的图形接口:

  • OpenGL ES:Skia 渲染引擎可以直接使用

  • Vulkan:Impeller 渲染引擎可以直接使用

  • NativeWindow:提供了跨平台的窗口抽象

8.4 社区共同努力

  • 华为官方和 Flutter 社区共同维护 flutter_flutter 项目

  • 基于 Flutter Engine 源码进行适配

  • 提供完整的开发工具链


从代码层面看,核心就是实现了 PlatformViewOHOSOHOSShellHolderOHOSContext 等类,将 Flutter Engine 与 HarmonyOS 系统连接起来。

**一句话总结:Flutter 通过实现 HarmonyOS 专属的 Embedder 层,将 Flutter Engine 与 HarmonyOS 的窗口系统、图形系统、输入系统对接,从而实现了跨平台运行。 **


九、参考资料

高通将向印度人工智能战略基金投资至多1.5亿美元

根据一份声明,高通公司计划投资高达 1.5 亿美元,以支持印度不断扩大的科技和人工智能初创企业生态系统。资金将通过高通创投(Qualcomm Ventures)投向处于各个发展阶段的初创企业,重点在于汽车、物联网、机器人技术和移动领域的 AI 应用。

Vue3组件开发中如何兼顾复用性、可维护性与性能优化?

一、组件开发的基本原则

1.1 单一职责原则

每个组件应专注于完成一个核心功能,避免将过多无关逻辑塞进同一个组件。例如,一个用户信息组件只负责展示用户头像、名称和基本资料,而不处理表单提交或数据请求逻辑。这种设计让组件更易于理解、测试和维护。

1.2 可复用性原则

通过Props、插槽和组合式API提高组件的复用性。例如,一个按钮组件可以通过Props定义不同的尺寸、颜色和状态,通过插槽支持自定义内容,从而在多个页面中重复使用。

1.3 可维护性原则

  • 命名规范:使用有意义的组件名称(如UserAvatar而非Avatar1),Props和事件名称采用kebab-case(如max-count而非maxCount)。
  • 模块化结构:将组件按功能划分到不同目录(如components/UI存放通用UI组件,components/Features存放业务功能组件)。
  • 注释文档:为组件和关键逻辑添加注释,说明组件用途、Props含义和事件触发时机。

二、组件设计的最佳实践

2.1 Props设计规范

使用TypeScript定义Props类型,设置默认值和校验规则,避免传递无效数据导致组件异常。

<template>
  <div class="counter">
    <button @click="decrement">-</button>
    <span>{{ count }}</span>
    <button @click="increment">+</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 定义Props类型和默认值
interface Props {
  count?: number;
  step?: number;
  min?: number;
  max?: number;
}

const props = withDefaults(defineProps<Props>(), {
  count: 0,
  step: 1,
  min: 0,
  max: 100
});

const emit = defineEmits<{
  'update:count': [value: number]
}>();

const increment = () => {
  const newValue = props.count + props.step;
  if (newValue <= props.max) {
    emit('update:count', newValue);
  }
};

const decrement = () => {
  const newValue = props.count - props.step;
  if (newValue >= props.min) {
    emit('update:count', newValue);
  }
};
</script>

2.2 自定义事件处理

通过defineEmits定义组件触发的事件,避免直接修改父组件状态,保持数据流的单向性。

<!-- 父组件 -->
<template>
  <Counter :count="count" @update:count="count = $event" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import Counter from './Counter.vue';

const count = ref(0);
</script>

2.3 灵活使用插槽

通过插槽让组件支持自定义内容,提高组件的灵活性和复用性。

<!-- Card.vue -->
<template>
  <div class="card">
    <div class="card-header">
      <slot name="header">默认标题</slot>
    </div>
    <div class="card-body">
      <slot>默认内容</slot>
    </div>
    <div class="card-footer">
      <slot name="footer" :current-time="currentTime">
        默认页脚 - {{ currentTime }}
      </slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const currentTime = ref(new Date().toLocaleTimeString());
</script>
<!-- 使用Card组件 -->
<template>
  <Card>
    <template #header>
      <h2>用户详情</h2>
    </template>
    <p>这是用户的详细信息...</p>
    <template #footer="{ currentTime }">
      更新时间:{{ currentTime }}
    </template>
  </Card>
</template>

2.4 组合式API的逻辑复用

往期文章归档
免费好用的热门在线工具

将组件逻辑抽离成可复用的Composables,提高代码的可维护性和复用性。

// composables/useCounter.ts
import { ref, computed } from 'vue';

export function useCounter(initialCount = 0, step = 1) {
  const count = ref(initialCount);
  
  const increment = () => count.value += step;
  const decrement = () => count.value -= step;
  const doubleCount = computed(() => count.value * 2);
  
  return { count, increment, decrement, doubleCount };
}
<!-- 在组件中使用 -->
<template>
  <div class="counter">
    <button @click="decrement">-</button>
    <span>{{ count }}</span>
    <span>双倍值:{{ doubleCount }}</span>
    <button @click="increment">+</button>
  </div>
</template>

<script setup lang="ts">
import { useCounter } from '@/composables/useCounter';

const { count, increment, decrement, doubleCount } = useCounter(0, 2);
</script>

三、组件通信的多种实现方式

graph TD
    A[父组件] -->|Props| B[子组件]
    B -->|Events| A
    A -->|Provide| C[深层子组件]
    C -->|Inject| A
    D[Pinia Store] -->|读取/修改| A
    D -->|读取/修改| B
    D -->|读取/修改| C

3.1 父子组件通信:Props与Events

这是最基础的通信方式,父组件通过Props传递数据给子组件,子组件通过Events通知父组件更新状态。

3.2 跨层级通信:Provide与Inject

适用于深层嵌套组件之间的通信,父组件通过provide提供数据,子组件通过inject获取数据。

<!-- 父组件 -->
<script setup lang="ts">
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';

provide('theme', 'dark');
</script>
<!-- 深层子组件 -->
<script setup lang="ts">
import { inject } from 'vue';

const theme = inject('theme', 'light'); // 默认值为light
</script>

3.3 全局状态管理:Pinia

对于需要在多个组件之间共享的状态(如用户登录状态、购物车数据),推荐使用Pinia进行全局状态管理。

// stores/counter.ts
import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() { this.count++; },
    decrement() { this.count--; }
  },
  getters: {
    doubleCount: (state) => state.count * 2
  }
});
<!-- 在组件中使用 -->
<template>
  <div>
    <span>{{ store.count }}</span>
    <button @click="store.increment">+</button>
  </div>
</template>

<script setup lang="ts">
import { useCounterStore } from '@/stores/counter';

const store = useCounterStore();
</script>

四、组件性能优化策略

4.1 异步组件与懒加载

使用defineAsyncComponent实现组件懒加载,减少初始包体积,提高页面加载速度。

<template>
  <Suspense>
    <AsyncChart />
    <template #fallback>
      <div>图表加载中...</div>
    </template>
  </Suspense>
</template>

<script setup lang="ts">
import { defineAsyncComponent } from 'vue';

const AsyncChart = defineAsyncComponent(() => import('./Chart.vue'));
</script>

4.2 使用Memoization减少重渲染

使用memo包裹组件,只有当Props发生变化时才重新渲染组件。

<script setup lang="ts">
import { memo } from 'vue';
import ExpensiveComponent from './ExpensiveComponent.vue';

const MemoizedComponent = memo(ExpensiveComponent);
</script>

4.3 虚拟列表处理大量数据

对于包含大量数据的列表,使用虚拟列表技术只渲染可见区域的元素,提高页面性能。推荐使用vue-virtual-scroller库:

npm install vue-virtual-scroller
<template>
  <RecycleScroller
    class="scroller"
    :items="largeList"
    :item-size="50"
  >
    <template v-slot="{ item }">
      <div class="list-item">{{ item }}</div>
    </template>
  </RecycleScroller>
</template>

<script setup lang="ts">
import { RecycleScroller } from 'vue-virtual-scroller';
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';

const largeList = Array.from({ length: 10000 }, (_, i) => `Item ${i}`);
</script>

五、常见问题排查与调试技巧

5.1 Props类型不匹配问题

问题:父组件传递的Props类型与子组件定义的类型不匹配(如传递字符串"5"而非数字5)。 解决:在父组件中转换数据类型,或在子组件中使用类型转换:

// 子组件中处理
const safeCount = Number(props.count);

5.2 事件绑定错误

问题:父组件监听的事件名称与子组件emit的事件名称不一致(如子组件emit('updateCount'),父组件监听update:count)。 解决:统一事件名称,使用kebab-case规范:

// 子组件
emit('update:count', newValue);

// 父组件
<Counter @update:count="handleUpdate" />

5.3 响应式数据更新不及时

问题:直接修改数组索引或对象属性,Vue无法检测到变化:

// 错误写法
const list = ref([1,2,3]);
list.value[0] = 4; // Vue无法检测到

// 正确写法
list.value.splice(0, 1, 4);

六、课后Quiz

问题1:如何在Vue3中实现跨层级组件通信?请至少列举两种方式并说明适用场景。

答案解析:

  1. Provide/Inject:适用于深层嵌套组件之间的通信(如主题设置、全局配置)。父组件通过provide提供数据,子组件通过inject获取数据。优点是无需逐层传递Props,缺点是可能导致组件耦合度升高。
  2. Pinia状态管理:适用于全局状态共享(如用户登录状态、购物车数据)。通过Pinia Store统一管理状态,任何组件都可以读取和修改Store中的数据。优点是状态管理集中化,缺点是需要额外引入Pinia库。
  3. Event Bus:使用mitt库创建事件总线,组件之间通过发布/订阅事件通信。但Vue3官方不推荐使用,建议优先使用Pinia。

七、常见报错解决方案

7.1 Props类型不匹配警告

错误信息[Vue warn]: Invalid prop: type check failed for prop "count". Expected Number, got String. 原因:父组件传递的Props类型与子组件定义的类型不匹配。 解决:在父组件中传递正确类型的数据,或在子组件中转换类型:

// 父组件
<Counter :count="5" /> <!-- 使用v-bind传递数字 -->

// 子组件
const safeCount = Number(props.count);

7.2 未定义的属性或方法错误

错误信息[Vue warn]: Property "increment" was accessed during render but is not defined on instance. 原因:在<script setup>中未正确导出变量或方法,或在选项式API中未在methods中定义方法。 解决:在<script setup>中确保变量和方法是顶级声明(自动导出),或在选项式API中添加到methods对象中。

7.3 生命周期钩子调用错误

错误信息[Vue warn]: Invalid hook call. Hooks can only be called inside the body of a setup() function. 原因:在setup函数外部调用了组合式API钩子(如onMounted)。 解决:确保所有钩子函数在setup函数内部调用:

<script setup lang="ts">
import { onMounted } from 'vue';

onMounted(() => {
  console.log('组件挂载完成');
});
</script>

八、参考链接

面试官 : “ 请问你实际开发中用过 函数柯理化 吗? 能讲一下吗 ?”

一、先搞懂:柯里化到底是什么?

核心定义:柯里化是把接收多个参数的函数,转换成一系列只接收单个参数的函数,并持续返回新函数,直到所有参数都被传入后,才执行最终逻辑并返回结果。

用 “人话” 说:原本要一次性传完所有参数的函数,现在可以 “分批传”,传一个参数就返回一个新函数等着接下一个,直到传完为止。

对比:普通函数 vs 柯里化函数

// 普通函数:一次性传所有参数
function add(a, b, c) {
  return a + b + c;
}
add(1, 2, 3); // 6

// 柯里化函数:分批次传参数
function curriedAdd(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    };
  };
}
curriedAdd(1)(2)(3); // 6(传一个参数,返回新函数,直到传完3个)

二、手动实现一个通用柯里化函数

你不用为每个函数单独写柯里化逻辑,这里写一个通用的 curry 工具函数,能把任意多参数函数转换成柯里化函数:

// 通用柯里化函数
function curry(fn) {
  // 保存原函数的参数个数
  const argsLength = fn.length;
  
  // 递归接收参数
  function curried(...args) {
    // 1. 如果已传参数 >= 原函数需要的参数,执行原函数
    if (args.length >= argsLength) {
      return fn.apply(this, args);
    }
    // 2. 否则,返回新函数,继续接收参数
    return function(...newArgs) {
      return curried.apply(this, [...args, ...newArgs]);
    };
  }
  
  return curried;
}

// 测试:给加法函数做柯里化
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);

// 支持多种传参方式(核心优势)
console.log(curriedAdd(1)(2)(3)); // 6(逐个传)
console.log(curriedAdd(1, 2)(3)); // 6(分批传)
console.log(curriedAdd(1)(2, 3)); // 6(混合传)
console.log(curriedAdd(1, 2, 3)); // 6(一次性传)

三、柯里化的核心价值(为什么要用?)

  1. 参数复用:提前固定部分参数,生成新函数,避免重复传参。示例:固定 “税率” 参数,复用计算逻辑

    // 原函数:计算税后价格(价格 + 税率)
    const calculateTax = (taxRate, price) => price * (1 + taxRate);
    // 柯里化后,固定税率为10%
    const calculateTax10 = curry(calculateTax)(0.1);
    // 后续只用传价格,不用重复传税率
    calculateTax10(100); // 110
    calculateTax10(200); // 220
    
  2. 延迟执行:先收集参数,不立即执行,等参数凑齐后再执行。示例:表单提交前收集多个字段,凑齐后再验证提交

    const submitForm = (name, phone, address) => {
      console.log(`提交:${name} ${phone} ${address}`);
    };
    const curriedSubmit = curry(submitForm);
    
    // 分步收集参数(比如用户分步填写表单)
    const step1 = curriedSubmit("张三"); // 收集姓名,未执行
    const step2 = step1("13800138000"); // 收集手机号,未执行
    step2("北京市"); // 收集地址,参数凑齐,执行 → 输出:提交:张三 13800138000 北京市
    
  3. 适配函数参数:把多参数函数转换成单参数函数,适配只接收单参数的场景(比如 React 的高阶组件、数组的 map/filter 等)。示例:适配数组 map 的单参数回调

    // 原函数:乘以指定倍数
    const multiply = (multiplier, num) => num * multiplier;
    const curriedMultiply = curry(multiply);
    
    // 固定倍数为2,生成单参数函数
    const double = curriedMultiply(2);
    // 适配 map 的单参数回调
    [1,2,3].map(double); // [2,4,6]
    

四、常见误区

❌ 误区:“柯里化就是把函数拆成只传一个参数的函数,必须链式调用 (a)(b)(c)”

✅ 纠正:柯里化的核心是 “参数分批传递 + 延迟执行”,支持任意分批方式(比如 (a,b)(c)、(a)(b,c)),不一定非要逐个传。

❌ 误区:“柯里化能提升性能”

✅ 纠正:柯里化本质是多了层函数嵌套,性能略有损耗,它的价值是提升代码复用性和可读性,而非性能。

总结

  1. 柯里化核心:把多参数函数转成 “单参数函数链”,支持参数分批传递,凑齐后执行;
  2. 实现关键:通过闭包保存已传参数,递归判断参数是否凑齐,凑齐则执行原函数;
  3. 核心用途:参数复用、延迟执行、适配单参数场景。

基于高德地图JS的旅游足迹,可嵌入个人博客中

一、足迹地图效果

制作最基础的旅行足迹地图,显示效果见下图,可以查看下面的 Demo 演示,显示标记地点的名称和经纬度,并在地图上用红点显示

足迹footprint - AomanHao的博客空间

以前的足迹地图因为地图不合规,显示效果也不太好,如下图

二、足迹地图制作

教大家如何将制作好的足迹地图嵌入到我们自己的博客中,基于 高德地图 (AMap) 来实现这个功能,因为它对中国地图的支持非常完善,且接入简单。整个页面会包含:

  1. 中国地图的基础展示
  2. 已去过地点的标记(带经纬度显示)

2.1 高德地图 Key 获取

前往 高德开放平台 注册账号,创建应用即可获取(免费)。

1)注册高德开放平台,注册个人认证开发者

2)创建新应用,选择web应用,选择web端JS相关

3)把生成的key复制,替换到代码中高德地图key

2.2 高德地图 Key 应用

把生成的key复制,找到到代码中高德地图key的地方,替换上

html文件在本地浏览器可以直接预览

2.3 线上部署

将该文件放到博客的静态资源目录(如 static/pages/footprint_lite.html)。

在博客导航栏添加链接指向该页面即可。

三、后记

1、因为是静态网页展示,足迹地点需要手动离线更新,然后把新文件覆盖到博客部署文件地址上。

2、考虑足迹更新频次很低,静态更新地址完全是OK的


四、代码链接

足迹代码链接:FootPrint/基于高德地图JS at main · AomanHao/FootPrint · GitHub

推荐用lite版本


我的个人博客主页,欢迎访问

我的CSDN主页,欢迎访问

我的GitHub主页,欢迎访问

我的知乎主页,欢迎访问

春运火车票已累计发售2.74亿张

据新华社,从中国国家铁路集团有限公司获悉,2月18日,全国铁路预计发送旅客1080万人次,计划加开旅客列车476列。截至2月18日8时,铁路12306累计发售春运期间车票2.74亿张。

YouTube在短暂的流媒体中断后恢复服务

YouTube周二表示,它已经解决了一个短暂影响视频共享平台访问的问题,此前停电跟踪网站Downdetector报告了全球大范围的中断。 YouTube表示,由于其推荐系统出现问题,导致视频无法在YouTube表面出现。 YouTube在更新中说:我们的推荐系统问题已经解决,我们所有的平台(YouTube.com、YouTube应用程序、YouTube音乐、儿童和电视)都已恢复正常。 根据Downdetector的数据,在高峰期,美国有超过32万用户报告了YouTube的问题。 Downdetector的数据基于用户提交的报告。实际受影响的用户数量可能有所不同。 根据DownDetector的数据,包括印度、英国、澳大利亚和墨西哥在内的个国家的YouTube也面临中断问题。

2026春节档新片总票房破16亿

据猫眼专业版数据,2026年春节档新片总票房破16亿,《飞驰人生3》《惊蛰无声》《熊出没·年年有熊》暂列春节档新片票房榜前三位​​。

大年初一广东省4A级及以上景区迎客近400万人次

春节假期第三天(2月17日),文旅市场持续火热。广东省4A级及以上景区接待游客399万人次,同比增长11.2%(按可比口径,下同);纳入监测的14段古驿道沿线重点区域接待游客68.5万人次,同比增长4.6%;纳入监测的13家红色旅游经典景区接待游客25.7万人次,同比增长7.2%;纳入监测的100个乡村旅游点和历史古村落接待游客33万人次,同比增长8.8%;纳入监测的80个重点公共文化机构接待市民游客22.1万人次,同比增长5.6%。

特斯拉避免了加州30天销售禁令 其自动驾驶功能营销实现合规

加利福尼亚州机动车管理局表示,特斯拉公司已就其车辆自动驾驶功能的营销行为采取了合规措施,因此不会在该州面临30天的销售禁令。该机构周二在一份声明中称,特斯拉已采取“纠正措施”以避免被暂停销售。去年12月,在一名行政法官就州监管机构指控特斯拉在营销中夸大其Autopilot和Full Self-Driving的功能能力作出裁决后,该公司被给予90天时间以实现合规。

O(1) 做法原理讲解(Python/Java/C++/C/Go/JS/Rust)

为了做到 $\mathcal{O}(1)$ 时间,我们需要快速判断所有相邻比特位是否都不同

如何判断不同?用哪个位运算最合适?

异或运算最合适。对于单个比特的异或,如果两个数不同,那么结果是 $1$;如果两个数相同,那么结果是 $0$。

如何对所有相邻比特位做异或运算?

例如 $n = 10101$,可以把 $n$ 右移一位,得到 $01010$,再与 $10101$ 做异或运算,计算的就是相邻比特位的异或值了。

如果异或结果全为 $1$,就说明所有相邻比特位都不同。

如何判断一个二进制数全为 $1$?

这相当于判断二进制数加一后,是否为 231. 2 的幂

设 $x$ 为 (n >> 1) ^ n,如果 (x + 1) & x 等于 $0$,那么说明 $x$ 全为 $1$。

class Solution:
    def hasAlternatingBits(self, n: int) -> bool:
        x = (n >> 1) ^ n
        return (x + 1) & x == 0
class Solution {
    public boolean hasAlternatingBits(int n) {
        int x = (n >> 1) ^ n;
        return ((x + 1) & x) == 0;
    }
}
class Solution {
public:
    bool hasAlternatingBits(int n) {
        uint32_t x = (n >> 1) ^ n;
        return ((x + 1) & x) == 0;
    }
};
bool hasAlternatingBits(int n) {
    uint32_t x = (n >> 1) ^ n;
    return ((x + 1) & x) == 0;
}
func hasAlternatingBits(n int) bool {
x := n>>1 ^ n
return (x+1)&x == 0
}
var hasAlternatingBits = function(n) {
    const x = (n >> 1) ^ n;
    return ((x + 1) & x) === 0;
};
impl Solution {
    pub fn has_alternating_bits(n: i32) -> bool {
        let x = (n >> 1) ^ n;
        (x + 1) & x == 0
    }
}

复杂度分析

  • 时间复杂度:$\mathcal{O}(1)$。
  • 空间复杂度:$\mathcal{O}(1)$。

专题训练

见下面位运算题单的「一、基础题」。

分类题单

如何科学刷题?

  1. 滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
  2. 二分算法(二分答案/最小化最大值/最大化最小值/第K小)
  3. 单调栈(基础/矩形面积/贡献法/最小字典序)
  4. 网格图(DFS/BFS/综合应用)
  5. 位运算(基础/性质/拆位/试填/恒等式/思维)
  6. 图论算法(DFS/BFS/拓扑排序/基环树/最短路/最小生成树/网络流)
  7. 动态规划(入门/背包/划分/状态机/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
  8. 常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
  9. 数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
  10. 贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
  11. 链表、树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA)
  12. 字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)

我的题解精选(已分类)

欢迎关注 B站@灵茶山艾府

美国加州成立人工智能监督部门 推进xAI调查

美国加利福尼亚州总检察长罗布-邦塔周二在接受媒体采访时说,他的办公室正在建立一项人工智能问责计划,同时也在调查埃隆-马斯克的xAI在未经同意的情况下生成色情露骨图像的问题。邦塔说,加利福尼亚州总检察长办公室上个月迅速采取行动,向xAI公司发出了一封禁止令,因为全球监管机构正在调查该公司的人工智能聊天机器人Grok制作的成人和可能未成年人的性化内容。邦塔说,他的办公室正在寻求确认该行为已经停止,并仍在与该公司进行讨论。他说,xAI 公司推卸责任,仍然允许为付费用户生成一些性化内容。邦塔补充说:"你停止前进并不意味着你的所作所为就可以免责。”最近被马斯克的 SpaceX 收购的 xAI 没有回应置评请求。

苹果 AI 硬件三件套曝光,iPhone 将迎来史诗级加强

昨天苹果官宣了春季发布会,我们大概会看到 iPhone 17e 和 A18 处理器无印 MacBook等一大波新品。但苹果接下来两年最值得期待的新品,可能远不止手机电脑和平板。

据彭博社记者 Mark Gurman 爆料,苹果正在加速推进三款全新的 AI 可穿戴设备。这三款产品都将围绕 Siri 数字助手构建,通过摄像头获取视觉上下文来执行各种操作。

APPSO 先给大家快速总结三款新苹果 AI 硬件特点:

  • 智能眼镜 N50:代号 N50,定位「进阶版 AI 硬件」,对标 Meta Ray-Ban 但要更高端。无显示屏,靠扬声器、麦克风和双摄像头实现功能——一颗拍照录像,一颗专门用于计算机视觉。计划 2027 年发售。
  • 可穿戴吊坠:AirTag 大小,可夹衣服或挂项链上。配备低分辨率摄像头和麦克风,被内部员工称为 iPhone 的「眼睛和耳朵」。不是独立设备,而是 iPhone 配件,依赖手机进行大部分处理。
  •  摄像头 AirPods:在现有 AirPods 基础上加入摄像头,主要为 AI 提供视觉信息,而非拍摄照片视频。进展最快,最早可能今年亮相。

▲APPSO 假想图.

苹果的 AI 硬件路线,不再「重磅」

苹果的上一款重磅新品 Vision Pro,虽然在技术工程和供应链上做到了极致,但高达 3499 美元的定价和笨重的头戴设计,让它始终未能真正走进大众市场。

Introducing Apple Vision Pro: Apple's first spatial computer - Apple

这一次,苹果显然改变了策略。

据知情人士透露,苹果正在研发的三款 AI 设备都走的是「轻量化」路线:它们不会取代 iPhone,更多作为 iPhone 的延伸,通过摄像头和麦克风为 AI 助手提供「眼睛和耳朵」。

也就是说,苹果终于不打算再造一个「新 iPhone」了,要造一堆让 iPhone 更好用的配件

在本月初的全员大会上,CEO 蒂姆·库克罕见地放话:「我们正在投资新技术,世界变化很快。」他透露苹果正在开发由 AI 驱动的「全新产品类别」,并直言「我们对此非常兴奋」。

兴奋不兴奋的不知道,但焦虑肯定多少是有的。

智能眼镜 N50:对标 Meta Ray-Ban,但要更高端

在三款产品中,智能眼镜显然是苹果的旗舰产品。这款代号 N50 的设备被定位为「进阶版 AI 硬件」,目标直指 Meta 的 Ray-Ban 智能眼镜。

与 Meta 当前的产品类似,N50 也不会配备显示屏,而是依靠扬声器、麦克风和摄像头来实现功能。用户可以接打电话、唤醒 Siri、根据周围环境执行操作、播放音乐、拍摄照片和视频。

 

不过 Meta 眼镜市场反馈相当不错。苹果现在入场,拿什么打?苹果希望在两个关键领域实现差异化:做工质感和摄像技术

据悉,苹果最初曾考虑像 Meta 那样与眼镜品牌合作,甚至用现成镜架嵌入电子元件做原型测试。但最近苹果决定自主设计镜框,推出多种尺寸和颜色。目前的原型机已经实现了组件内置化,不再需要外接电池包。苹果还在讨论未来推出更多款式,走时尚单品路线。

▲APPSO 假想图.

N50 将搭载双摄像头系统:一颗用于高分辨率拍照录像,另一颗专门用于计算机视觉——类似 Vision Pro 的技术,帮助设备更精准地理解周围环境、测量物体距离。

苹果希望这款眼镜能成为「全天候 AI 伴侣」,实时理解用户在看什么、在做什么。你可以看着一样东西问「这是什么」,看到海报上的活动信息直接添加到日历,在超市看着某件商品时收到提醒「该买这个了」。导航时,Siri 不再只说「左转」,而是「走过那栋红色建筑再转弯」。

苹果计划最早今年 12 月启动生产,2027 年正式发售。

吊坠和 AI AirPods:不想戴眼镜?还有别的选择

当然,不是所有人都愿意在脸上戴东西。苹果为这部分用户准备了另外两款产品:吊坠和带摄像头的 AirPods。

▲APPSO 假想图.

吊坠的设计理念很有意思。它由苹果的工业设计团队在研发眼镜的过程中提出,外观类似失败的 Humane AI Pin,但定位完全不同——它不是独立设备,而是 iPhone 的配件。

这款 AirTag 大小的设备可以夹在衣服上或挂在项链上,配备低分辨率摄像头和麦克风。目前团队还在争论是否要加入扬声器——如果加入,用户就可以不戴 AirPods、不把 iPhone 掏出口袋,直接与设备对话。

▲APPSO 假想图.

带摄像头的 AirPods 则进展更快,最早可能今年亮相。

彭博社早在 2024 年初就爆料过这个项目,苹果也一直在为 AirPods 添加 AI 功能,比如去年推出的实时翻译模式。这两款产品的摄像头分辨率都不高,主要目的是为 AI 提供视觉信息。

Siri 升级一波三折,苹果先用 AI 硬件跟上

虽然 iPhone 销量依然强劲,但苹果在 AI 领域确实落后了。Siri 的升级已经成了一个「跳票专业户」。

  • 2024 年 6 月 WWDC 大会上官宣 AI Siri,承诺 2025 年初上线;
  • 2025 年推迟到 2026 年 3 月;
  • 2016 年又要推迟到 iOS 26.5,全部功能甚至要拖到 9 月的 iOS 27。

据内部测试反馈,问题还不少:理解不准确,用户语速快一点就会被打断;处理速度太慢,复杂查询需要更长推理时间;偶尔还会「退回」到现有的 ChatGPT 集成,明明应该用苹果自家的能力完成请求;App Intents 系统(用语音控制应用内操作)早期版本根本不可靠。

苹果软件工程主管 Craig Federighi 在员工会议上反复强调:个性化的 AI 绝对不能泄露用户数据。苹果要打破行业惯例——不在服务器上保存用户数据用于训练,而是让数据只存在于本地或隐私保护的服务器上。这个坚持很苹果,但也让开发难度成倍增加。

雪上加霜的是,苹果 AI 团队去年经历了严重的人才流失:基础模型团队负责人、Siri 智能搜索项目负责人投奔 Meta,多位关键研究员出走 OpenAI、xAI、Cohere。

而竞争对手们已经跑在前面。Meta 的 Ray-Ban 智能眼镜已经成为爆款,OpenAI 则在 Jony Ive 等前苹果高管的帮助下开发一系列 AI 设备,就连 Google 都在与 Warby Parker 合作推智能眼镜。

长期来看,苹果的目标依然是推出带增强现实显示屏的智能眼镜,为用户提供更丰富的数据和视觉体验。但这还需要很多年。

据悉苹果去年已经停止了低价版 Vision Pro(代号 N100)的开发。这款产品原本被定位为通往 AR 设备的桥梁,但最终苹果选择专注做眼镜,而非更笨重的头戴设备。

除了可穿戴设备,苹果还在开发一系列 AI 家居产品:基于新版 Siri 的智能显示屏、带机械臂的大屏版本、升级版 HomePod,以及用于家庭安防和自动化的紧凑型室内传感器。问题是,这些智能家居新品全部因为 AI Siri 的推迟而「按兵不动」。

写在最后

从 Vision Pro 的「技术炫技」到 N50 眼镜的「实用主义」,苹果的产品思路正在发生微妙转变。

Meta 已经证明,不带屏幕、主打 AI 助手的智能眼镜是有市场的。而 OpenAI 即将推出的 AI 硬件,则代表了另一种可能性:完全跳出手机的逻辑,重新定义人机交互

苹果选择了一条中间路线:不做手机的替代品,去做手机的延伸。眼镜、吊坠、AI 耳机——这些设备都依赖 iPhone,都在强化苹果的生态系统

这很苹果,也是最务实稳当的路线。

但还有一个巨大的不确定因素,2026 开年 AI 的进展已经让人快跟不上了,当 AI 真正变得无处不在,用户还需要被「锁定」在某个生态系统里吗?

OpenAI CEO Sam Altman 曾在纽约的一场午餐会上直言:「大家别盯着 Google 了,OpenAI 真正的宿敌,是苹果。」

Altman 的逻辑是:未来 AI 的主战场不在云端,而在终端。现在的智能手机根本承载不了真正的 AI 伴侣体验——屏幕太小、交互方式太局限、隐私保护机制太僵化。谁能率先打造出「AI 原生设备」,谁就能在下一个十年占据制高点。

而在这个战场上,苹果的优势几乎是碾压性的。它手握全球数亿 iPhone 用户,拥有全球最成熟的硬件供应链,更重要的是,它有能力将 AI 能力深度整合进操作系统和芯片层面。

所以苹果这次押注的三款 AI 设备,与其说是追赶竞争对手,不如说是在捍卫自己的护城河,让 iPhone 变得更不可或缺。

接下来真正的较量,或许不在于谁能造出最酷的硬件,而是谁能用 AI 体验成为新的入口

#欢迎关注爱范儿官方微信公众号:爱范儿(微信号:ifanr),更多精彩内容第一时间为您奉上。

爱范儿 | 原文链接 · 查看评论 · 新浪微博


豆包千问疯狂撒钱,月之暗面疯狂搞钱 | 智能涌现独家

文|周鑫雨

编辑|苏建勋

春节,热钱涌动在中国大模型赛道上。

一端,是狂撒几十亿元发红包、请奶茶,替当家AI应用拉流量的大厂们;另一端,则是股价飞涨、融资迅猛的大模型六小虎们。

在搞钱的战场上,开年最大的一笔融资,来自月之暗面。

此前彭博社等媒体报道称,近期月之暗面即将完成的超7亿美元融资,由阿里、腾讯、五源资本、九安医疗等老股东领投,并且已经超募。与此同时,月之暗面已经以100亿-120亿美金的估值,无缝开启了新一轮融资。

《智能涌现》独家获悉,月之暗面的超7亿美元融资中,股东阵容除了联合领投的老股东们,还包括老股东高榕创投,以及新增的凯辉基金——这也是凯辉,首次朝大模型公司开枪

据我们了解,以超100亿美金估值开启的新一轮融资,已经收到了多家机构的意向,包括欧洲背景的海外基金。

有关上述信息,截至发稿前,月之暗面暂无回应。

用“”形容月之暗面这轮融资的局面,一点也不过分。

一名知情人士告诉我们,从2025年下半年,月之暗面开启融资之初,不少机构的LP,就“催着投资”。

这几轮融资,还吸引到了不少首次对大模型出手的基金。

比如,我们得知,在月之暗面上一轮超7亿美金的融资中,凯辉基金成为了新增股东——直到2025年5月,凯辉基金管理合伙人段兰春,还在36氪的访谈中提到,凯辉暂时没有参与通用大模型或底层Infra的投资,原因是凯辉的投资策略是“重落地、重生态”。

这或许是除了2023年初,行业对大模型最大的一次FOMO(错失恐慌症)。

溯其缘由,是自港股IPO以来,智谱和MiniMax这两家大模型初创公司飞速上涨的市值,再次给予一级市场投资大模型的热情。

自2026年初相继IPO后,智谱和MiniMax的股价就水涨船高。尤其2月12日,两家公司上架新一代模型后,市值又达到了新的峰值——

截至2月17日,智谱的盘中最高市值已经超过2200亿港元,MiniMax则超过2600亿港元,两者相较上市初期,均翻了四五倍。

二级市场可观的回报,也让一级市场的捕手们,将目光投向尚未上市的月之暗面,试图囤积居奇。

港股IPO,也将中国大模型的影响力扩大至海外。可见的是,此前鲜少接触中国企业的欧洲资本,也在新一轮融资中,罕见地向月之暗面伸出了橄榄枝。

一名知情人告诉《智能涌现》,月之暗面上一轮7亿美金的融资,新投资者“速度快才能抢到份额”。以超100亿美金估值开启的新一轮融资,某种意义上也是没抢到上一轮份额的机构,“推着开启的”。

与此同时,“智谱和MiniMax的市值,给了大模型公司在二级市场的一个估值锚点。”另有知情人士表示。

之前,月之暗面和阶跃星辰的估值都相对偏低。即便如今估值已超过100亿美金,但相较智谱(估值约280亿美金)和MiniMax(估值约330亿美金),两家未上市的模型初创公司,还有数倍的差距。

二级市场逐渐验证了模型公司的价值,这一现象也改变了月之暗面和阶跃星辰的融资策略:自2025年下半年以来,开启滚动融资,迅速抬高估值

就月之暗面而言,2025年12月底,公司宣布完成5亿美金的融资后,就开启了价值7亿美金的新一轮;之后无缝开启的,则是如今以超100亿美金估值快速推进的融资——短短两个月,月之暗面估值翻了超过2.2倍。

如今,大模型六小虎,纷纷在一二级市场,加快了筹措资金的步伐。他们最强劲的对手——大厂战队的字节、阿里、腾讯,已经先他们一步,迈入了撒钱换用户的阶段。

春节期间,赞助上春晚,豪掷几十亿元发红包、请奶茶,显然,大厂们已经更早抢滩“AI国民应用”。

对于留在场上的4家大模型创业公司而言,稳住模型技术第一梯队的位置,是当下最重要的命题。

阶跃星辰董事长印奇在最近的访谈中提到,基模研发,一年需要30亿-50亿元的资金投入,才能留在牌桌上

高涨的估值,仍愿意买单的一二级市场,对创业公司而言,是个乐观的信号。

欢迎交流!

今天全国铁路预计发送旅客1080万人次

今天,全国铁路预计发送旅客1080万人次,计划加开旅客列车476列。按照火车票提前15天售票的规定,今天全国铁路开始发售3月4日,也就是正月十六的火车票。

新西兰央行维持利率不变 暗示今年晚些时候或加息应对通胀风险

新西兰央行决定维持利率在三年半以来的最低水平,并暗示鉴于通胀压力不断增加,下一步可能会上调利率。新西兰央行周三决定维持官方现金利率在2.25%不变,符合接受彭博调查的22位经济学家的预测。该央行的最新预测显示不排除今年晚些时候加息25个基点。新西兰央行在声明中表示:“如果经济按预期发展,货币政策可能会在一段时间内保持宽松。委员会将继续密切评估数据。随着经济复苏势头增强,通胀率持续迈向目标区间中点水平,货币政策将逐步正常化。”货币政策声明发布后,新西兰元兑美元下跌0.45%,报0.6022美元。 09:18:57
❌