作者: gzzhiyi

  • 〔City Corners〕佛山・高明

    高明,它藏着老巷的烟火、山水的灵秀。这是我对高明一步一脚印的记录,领略这座城每一个角落。

    荷城

    高明汽车客运站是我暂时去过最大的公交站场,对于公交迷的我是一个胜地。

    高明有轨电车,算是遗址吧~反映了一个城市变迁的缩影。

    西江

    骑共享电驴游西江是一种享受。

    苏村

    这个坐落西江,以锦鲤为主题的村落,绝对是来高明必去的打卡地。

  • BYD K9FE・284路公交・1:76模型

    模型资料

    比亚迪 K9FE 巴士模型
    厂商
    比亚迪
    型号
    K9FE
    城市
    广州
    线路
    284
    运营区间
    广园新村 ⇄ 员村
    比例
    1 / 76
    材质
    树脂胶

    比亚迪 K9FE 是比亚迪 K9 系列的经典改进型纯电动城市客车,型号常对应 BYD6121LGEV3/4,2017 年后推出,核心定位为高效、安全、适配城市通勤的纯电公交主力。

    车身展示

    细节展示

    线路历史

    广州公交284路初期走向为“广园新村—东山”,途经大东门、北京路、纪念堂,由广州市电车公司营运。

    1993年,广州公交284路走向由“广园新村—东山”调整为“广园新村—员村生活区”。

    约2000年,广州公交284路走向由“广园新村—员村生活区”调整为“广园新村—员村(绢麻厂)”。

  • 关于音符一拍的时值计算

    音符一拍的时值计算是音乐理论中的基础概念,涉及音符的时值和拍号。

    1. 音符时值

    音符时值表示音符的持续时间,常见音符及其时值如下:

    • 全音符:4拍
    • 二分音符:2拍
    • 四分音符:1拍
    • 八分音符:0.5拍
    • 十六分音符:0.25拍

    2. 拍号

    拍号决定每小节的拍数和每拍的时值,通常表示为分数,如4/4、3/4等。

    • 分子:每小节的拍数
    • 分母:每拍的音符类型(4代表四分音符,8代表八分音符)

    3. 计算一拍的时值

    以4/4拍为例:

    • 拍号:4/4
    • 每拍时值:四分音符(分母为4)
    • 每拍时长:1拍

    4. 不同拍号的时值计算

    • 3/4拍:每拍为四分音符,每小节3拍。
    • 6/8拍:每拍为八分音符,每小节6拍。

    5. 示例

    • 4/4拍:四分音符=1拍,二分音符=2拍,全音符=4拍。
    • 6/8拍:八分音符=1拍,四分音符=2拍,附点四分音符=3拍。

    6. 实际应用

    • 4/4拍:四分音符=1拍,八分音符=0.5拍。
    • 3/4拍:四分音符=1拍,二分音符=2拍。

    总结

    音符一拍的时值由拍号决定,分母指定每拍的音符类型,分子决定每小节的拍数。

  • 【CSS】动画性能优化

    60fps 与设备刷新率

    目前大多数设备的屏幕刷新率为60fps(Frame per Second),即每秒60帧。因此,如果在页面中有一个动画或渐变效果,或者用户正在滚动页面,那么浏览器渲染动画或页面的每一帧的速率也需要跟设备屏幕的刷新率保持一致,即每一帧要在16毫秒(1S/60 = 16.66ms)之内完成。如果无法完成,由于帧率的下降会导致内容在屏幕上抖动。此现象通常称为卡顿,会对用户体验产生负面影响。

    浏览器渲染

    在讲性能之前,我们需要先对浏览器渲染页面有一个基础的理解。

    css 图层

    浏览器在渲染一个页面时,会将页面分为很多个图层,图层有大有小,每个图层上有一个或多个节点。需要注意的是,如果图层中某个元素需要重绘,那么整个图层都需要重绘(关于重绘下面会讲到)。

    渲染过程

    简单来说,浏览器的渲染过程其实就是将页面转换成像素显示到屏幕上,大致有如下几个步骤:

    渲染过程流程图
    • JavaScript操作: 一般来说,我们会使用 JavaScript 来实现一些交互操作。比如用往页面里添加一些元素,切换显示隐藏等。
    • style 样式计算: 该过程根据 css 选择器,获取每个元素匹配的 css 样式并计算其最终应用样式。
    • Layout 布局:该过程计算元素要占据的空间大小及其在屏幕的位置。网页的布局模式意味着一个元素可能影响其他元素,例如 <body> 元素的宽度一般会影响其子元素的宽度以及树中各处的节点,因此对于浏览器来说,布局是经常发生的。
    • Paint 绘制:本质上就是填充像素的过程。包括绘制文字、颜色、图像、边框和阴影等。也就是绘制元素所有的可视效果。
    • Composite 渲染层合并:在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上如果我们需要提高动画的性能,需要做的就是减少浏览器在动画运行时所需要做的工作。当 css 在进行动画时,其不同属性值引起的改变,重新渲染可能会有三种执行路径:
      1. layout -> paint -> composite
      2. paint -> composite
      3. composite 很明显,最短路径的 C 动画性能是最高的,所以我们在使用动画的时候就得考虑使用什么属性,以尽量减少执行路径。

    动画属性

    css 的属性大致分为三类:布局类(layout),绘制类(paint),合成类(composite)。

    重排(reflow)

    由元素的布局类属性改变所触发的行为过程,我们称为 reflow,也叫做 relayout(重新布局)。当某个节点 reflow 时会重新计算节点的尺寸和位置,还可能会引起其它节点的 reflow。

    该系列属性的改变,会执行路径 A 进行重新渲染,所以性能是最差的。(这充分说明,重排会引起重绘)

    触发重排的属性

    • 盒子模型相关属性会触发重布局:

      • width
      • height
      • padding
      • margin
      • display
      • border-width
      • border
      • min-height
    • 定位属性及浮动也会触发重布局:

      • top
      • bottom
      • left
      • right
      • position
      • float
      • clear
    • 改变节点内部文字结构也会触发重布局:

      • text-align
      • overflow-y
      • font-weight
      • overflow
      • font-family
      • line-height
      • vertival-align
      • white-space
      • font-size

    重绘(repaint)

    由绘制类属性改变触发节点重新绘制其可视效果的过程,我们称为 repaint。

    该系列属性的改变,会执行路径 B,所以性能一般。

    修改时只触发重绘的属性有:

    • color
    • border-style
    • border-radius
    • visibility
    • text-decoration
    • background
    • background-image
    • background-position
    • background-repeat
    • background-size
    • outline-color
    • outline
    • outline-style
    • outline-width
    • box-shadow

    上面的属性由于不会修改节点的大小和位置,因此不会触发重排,其只是改变了节点内部的渲染效果,所以只会进行重绘以下的步骤。

    composite

    目前只有两个属性属于 composite 类:

    • transform
    • opactiy

    优化技巧

    减少动画元素

    减少动画元素是动画性能优化中首先需要完成的。通过审查页面动画 DOM 元素结构,去除不必要的动画元素,减少元素的数量,相应地会减少布页面局和绘制的时间。

    尽量使用 fixed、absolute 定位

    对于动画元素,尽量使用用 fixed、absolute 定位方式,避免影响到其他节点重排。

    尽量只改变 transform 和 opacity

    能用 transform、opacity 优先使用,其属性的改变不会发生重排和重绘。如位移操作的,可以使用translate 来实现,渐隐渐现效果可以使用 opacity 属性来实现。

    恰当开启硬件加速效果

    对动画元素应用

    transform: translate3d(0, 0, 0);
    /* transform: translateZ(0); */
    will-change: transform;

    等来开启硬件加速。通常开启硬件加速可以让动画变得更加流畅。但这里需注意,在不需要的时候需去掉避免过多的内存消耗。

  • Laravel 学习笔记

    一、前期准备:项目初始化与基础配置

    1.1 项目创建与依赖安装

    Laravel 内置API开发支持,无需额外引入前端脚手架,推荐使用纯净API项目初始化方式:

    # 创建Laravel项目
    composer create-project laravel/laravel laravel-api
    
    # 进入项目目录
    cd laravel-api
    
    # 禁用前端相关依赖(可选,纯API无需前端)
    rm -rf resources/js resources/css package.json vite.config.js

    1.2 环境配置与数据库连接

    修改根目录 .env 文件,配置核心环境变量,确保数据库、时区、接口响应格式适配后端API:

    # 应用基础配置
    APP_NAME=LaravelAPI
    APP_ENV=local
    APP_KEY=生成的密钥
    APP_DEBUG=true
    APP_URL=http://localhost:8000
    APP_TIMEZONE=Asia/Shanghai
    APP_LOCALE=zh-CN
    
    # 数据库配置(MySQL为例)
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel_api
    DB_USERNAME=root
    DB_PASSWORD=
    
    # 接口跨域配置(后续详解)
    ALLOWED_ORIGINS=*

    生成应用密钥(必填,保障加密安全):

    php artisan key:generate

    二、路由:API路由定义与规范

    2.1 API专属路由文件

    Laravel 提供 routes/api.php 路由文件,专门用于定义后端接口,默认前缀 /api,无需手动添加,且不包含Session中间件,适配无状态API。

    2.2 基础路由定义

    use Illuminate\Support\Facades\Route;
    use App\Http\Controllers\Api\UserController;
    use App\Http\Controllers\Api\PostController;
    
    // 单接口路由
    Route::get('/test', function () {
        return response()->json([
            'code' => 200,
            'msg' => 'API接口正常',
            'data' => []
        ]);
    });
    
    // 控制器路由(推荐)
    Route::get('/users', [UserController::class, 'index']); // 用户列表
    Route::get('/users/{id}', [UserController::class, 'show']); // 单个用户
    Route::post('/users', [UserController::class, 'store']); // 创建用户
    Route::put('/users/{id}', [UserController::class, 'update']); // 更新用户
    Route::delete('/users/{id}', [UserController::class, 'destroy']); // 删除用户
    

    2.3 资源路由(RESTful规范)

    针对标准CRUD接口,使用资源路由简化定义,自动映射RESTful风格接口:

    // 完整资源路由
    Route::apiResource('posts', PostController::class);
    
    // 仅指定部分接口
    Route::apiResource('posts', PostController::class)->only(['index', 'show']);
    
    // 排除部分接口
    Route::apiResource('posts', PostController::class)->except(['destroy']);

    2.4 路由分组与中间件

    对接口进行分组管理,统一添加前缀、中间件(如鉴权、跨域):

    Route::prefix('v1')->group(function () {
        // 公开接口
        Route::post('/login', [AuthController::class, 'login']);
        Route::post('/register', [AuthController::class, 'register']);
    
        // 需鉴权接口
        Route::middleware('auth:sanctum')->group(function () {
            Route::get('/user/info', [AuthController::class, 'userInfo']);
            Route::apiResource('posts', PostController::class);
        });
    });

    三、控制器:API业务逻辑处理

    3.1 创建API专用控制器

    推荐在 app/Http/Controllers/Api 目录下创建控制器,区分前后端,命令行创建:

    # 创建基础控制器
    php artisan make:controller Api/UserController
    
    # 创建资源控制器(自带CRUD方法)
    php artisan make:controller Api/PostController --api

    3.2 控制器标准写法(API响应规范)

    后端API统一返回JSON格式数据,遵循 code+msg+data 响应规范,避免直接返回原生数据:

    <?php
    
    namespace App\Http\Controllers\Api;
    
    use App\Http\Controllers\Controller;
    use App\Models\User;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Hash;
    
    class UserController extends Controller
    {
        /**
         * 用户列表
         */
        public function index(Request $request)
        {
            // 分页查询
            $users = User::query()->paginate(10);
            return $this->success('用户列表获取成功', $users);
        }
    
        /**
         * 单个用户详情
         */
        public function show($id)
        {
            $user = User::find($id);
            if (!$user) {
                return $this->fail('用户不存在', 404);
            }
            return $this->success('用户详情获取成功', $user);
        }
    
        /**
         * 统一成功响应
         */
        protected function success($msg = '操作成功', $data = [], $code = 200)
        {
            return response()->json([
                'code' => $code,
                'msg' => $msg,
                'data' => $data
            ]);
        }
    
        /**
         * 统一失败响应
         */
        protected function fail($msg = '操作失败', $code = 400)
        {
            return response()->json([
                'code' => $code,
                'msg' => $msg,
                'data' => []
            ]);
        }
    }
    

    四、请求验证:参数校验与异常处理

    4.1 表单请求验证(推荐)

    创建独立验证类,分离校验逻辑与业务逻辑,命令行创建:

    php artisan make:request Api/UserStoreRequest

    编写验证规则(app/Http/Requests/Api/UserStoreRequest.php):

    <?php
    
    namespace App\Http\Requests\Api;
    
    use Illuminate\Foundation\Http\FormRequest;
    
    class UserStoreRequest extends FormRequest
    {
        /**
         * 权限判断
         */
        public function authorize()
        {
            return true; // 开放接口直接返回true
        }
    
        /**
         * 验证规则
         */
        public function rules()
        {
            return [
                'username' => 'required|string|unique:users|max:20',
                'email' => 'required|email|unique:users',
                'password' => 'required|string|min:6|confirmed',
            ];
        }
    
        /**
         * 自定义错误提示
         */
        public function messages()
        {
            return [
                'username.required' => '用户名不能为空',
                'email.unique' => '邮箱已被注册',
                'password.confirmed' => '两次密码不一致',
            ];
        }
    }
    

    4.2 控制器调用验证

    public function store(UserStoreRequest $request)
    {
        // 验证通过后获取安全参数
        $data = $request->validated();
        $data['password'] = Hash::make($data['password']);
        $user = User::create($data);
        return $this->success('用户创建成功', $user);
    }

    4.3 全局异常处理(API适配)

    修改 app/Exceptions/Handler.php,将异常转为JSON响应,避免页面报错:

    use Illuminate\Validation\ValidationException;
    
    public function register()
    {
        $this->renderable(function (ValidationException $e, $request) {
            if ($request->is('api/*')) {
                return response()->json([
                    'code' => 422,
                    'msg' => '参数校验失败',
                    'data' => $e->errors()
                ], 422);
            }
        });
    }

    五、数据库:迁移、模型与数据操作

    5.1 数据迁移(表结构管理)

    通过迁移文件管理数据库表,无需手动建表:

    # 创建迁移文件
    php artisan make:migration create_posts_table
    
    # 执行迁移(建表)
    php artisan migrate
    
    # 回滚迁移
    php artisan migrate:rollback

    迁移文件示例(创建文章表):

    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->integer('user_id');
            $table->timestamps();
        });
    }

    5.2 模型定义与关联

    # 创建模型
    php artisan make:model Post

    模型配置(app/Models/Post.php):

    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
        use HasFactory;
    
        // 允许批量赋值字段
        protected $fillable = ['title', 'content', 'user_id'];
    
        /**
         * 关联用户(一对多)
         */
        public function user()
        {
            return $this->belongsTo(User::class);
        }
    }

    5.3 API常用数据操作

    • 分页查询Post::paginate(10),自动返回分页元数据

    • 条件筛选Post::where('user_id', $userId)->get()

    • 关联查询Post::with('user')->paginate(10)(预加载避免N+1问题)

    • 新增数据Post::create($validatedData)

    • 更新数据Post::findOrFail($id)->update($validatedData)

    • 删除数据Post::findOrFail($id)->delete()

    六、接口鉴权:Sanctum无状态认证

    6.1 Sanctum安装与配置

    Laravel官方推荐的轻量级API鉴权方案,无状态、适配纯后端接口:

    # 安装Sanctum
    composer require laravel/sanctum
    
    # 发布配置文件
    php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
    
    # 执行迁移(生成令牌表)
    php artisan migrate

    app/Models/User.php 引入令牌 trait:

    use Laravel\Sanctum\HasApiTokens;
    
    class User extends Authenticatable
    {
        use HasApiTokens, HasFactory, Notifiable;
    }

    6.2 登录签发令牌

    public function login(Request $request)
    {
        $credentials = $request->validate([
            'email' => 'required|email',
            'password' => 'required|string',
        ]);
    
        if (!Auth::attempt($credentials)) {
            return $this->fail('账号或密码错误', 401);
        }
    
        $user = Auth::user();
        // 签发令牌
        $token = $user->createToken('api_token')->plainTextToken;
    
        return $this->success('登录成功', [
            'token' => $token,
            'user' => $user
        ]);
    }

    6.3 鉴权中间件使用

    在路由中添加 auth:sanctum 中间件,保护接口:

    Route::middleware('auth:sanctum')->group(function () {
        Route::get('/user/profile', [AuthController::class, 'profile']);
        Route::apiResource('posts', PostController::class);
    });

    前端请求时,在请求头携带令牌:Authorization: Bearer 令牌值

    6.4 退出登录(销毁令牌)

    public function logout(Request $request)
    {
        $request->user()->currentAccessToken()->delete();
        return $this->success('退出登录成功');
    }

    七、跨域处理:API接口跨域解决方案

    纯后端API需解决跨域问题,Laravel 自带跨域中间件,修改配置文件 config/cors.php

    return [
        'paths' => ['api/*'],
        'allowed_methods' => ['*'],
        'allowed_origins' => ['*'], // 生产环境替换为具体域名
        'allowed_origins_patterns' => [],
        'allowed_headers' => ['*'],
        'exposed_headers' => [],
        'max_age' => 0,
        'supports_credentials' => false,
    ];

    修改后重启服务,跨域中间件自动生效。

    八、API优化与进阶技巧

    8.1 资源响应(格式化输出)

    使用API资源类统一数据返回格式,避免字段冗余:

    # 创建资源类
    php artisan make:resource PostResource

    资源类编写(app/Http/Resources/PostResource.php):

    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'content' => $this->content,
            'author' => $this->user->username ?? '',
            'create_time' => $this->created_at->toDateTimeString(),
        ];
    }

    控制器调用:return $this->success('获取成功', PostResource::collection($posts));

    8.2 接口限流(防恶意请求)

    使用Laravel内置限流中间件,限制接口请求频率:

    // 限制1分钟内最多60次请求
    Route::middleware('throttle:60,1')->group(function () {
        Route::post('/login', [AuthController::class, 'login']);
    });

    8.3 软删除与数据恢复

    迁移文件添加软删除字段,模型引入软删除trait,避免物理删除数据:

    // 迁移文件
    $table->softDeletes();
    
    // 模型
    use Illuminate\Database\Eloquent\SoftDeletes;
    class Post extends Model
    {
        use SoftDeletes;
    }

    九、接口调试与启动

    • 启动服务php artisan serve,默认地址 http://127.0.0.1:8000
    • 路由查看php artisan route:list,查看所有API路由详情
    • 调试工具:使用Postman、ApiFox等接口工具调试,无需前端页面
    • 日志查看:日志文件位于 storage/logs/laravel.log,排查后端异常
  • 宇通 ZK5120A1 | 107路公交 | 1:160模型

    模型资料

    宇通无轨电车 ZK6120EGQAA
    厂商
    宇通客车
    型号
    ZK5120A1
    城市
    广州
    线路
    107
    运营区间
    东山 ⇄ 中山八路
    比例
    1 / 160
    材质
    树脂胶

    2010年,广州电车公司联合宇通客车,推出首款 “典雅之星 3” 电车,车型编号 ZK6120EGQAA。凭借极具辨识度的前脸造型与锐利大灯,这款车一经亮相便备受关注,更被巴士爱好者亲切称作 “电鲨”。广州先后引进五代电鲨车型,而图中这三台便是广州最后一代电鲨,型号为 ZK5120A1。相较上一代,该车改用非全封闭车窗设计,成为一代经典的换代标志。

    模型展示

  • 【React】学习笔记-基础篇

    虚拟 DOM 的原理是什么?为什么比直接操作 DOM 高效?

    • 虚拟 DOM 是一个轻量的 JS 对象,用来描述真实 DOM 的层次和属性。
    • 通过 Diff 算法最小化 DOM 操作,减少重绘和回流。

    JSX 是什么?和普通 JavaScript 的区别?

    • JSX 是语法糖,最终会被 Babel 编译为 React.createElement() 调用。

    数据流

    • 单向数据流,自上而下传递。
    • 父组件通过 props 把数据传递给子组件;
    • 子组件可以通过回调函数通知父组件。

    Props

    • PropTypes 定义类型
    • defaultProps 定义默认值
    • this.props.children 表示组件的所有子节点
    • 不要把 props 复制到 state 中,要尽可能把 props 当作数据源(避免反模式)

    高阶组件(HOC)

    • 用于复用组件逻辑。本质上是一个函数,通过接收一个组件并返回一个新组件

    PureComponent 和 React.memo

    • PureComponent 会对 props 和 state 进行浅比较
    • memo 只对 props 进行浅比较

    `

    ` 和 “ (空标签)的区别 – 只有 ` ` 可以带 key 属性,这在列表渲染时非常重要 #### 类组件和函数组件的区别? – 语法与结构 “`js class MyComponent extends React.Component { render() { return
    Hello, {this.props.name}
    ; } } function MyComponent(props) { return
    Hello, {props.name}
    ; } “` – 状态管理 – 类组件通过 `this.state` 定义状态,`this.setState()` 更新状态 – 函数组件使用 Hooks 的 `useState` 管理状态 – 生命周期与副作用 – 类组件通过生命周期处理副作用 – 函数组件通过 `useEffect` 替代生命周期 – `this` 的绑定问题 – 类组件通过手动绑定事件函数的 `this` “`js class Button extends React.Component { handleClick() { console.log(this); } // this 可能为 undefined render() { return ; } } “` – 函数组件没有 this,直接访问 props 和状态 “`js function Button() { const handleClick = () => console.log(“No this!”); return ; } “` – 性能优化 – 类组件使用 `shouldComponentUpdate` 或 `PureComponent` 避免不必要的渲染 – 函数组件使用 `React.memo` 进行浅比较 ### 【状态管理】 #### React 中的状态提升(Lifting State Up)是什么? – 把状态提升到父组件进行管理,子组件通过 props 读取数据。 #### Context API 的作用?如何避免不必要的渲染? – Context(上下文) 是 React 提供的跨层级组件数据传递方案,用于解决多层组件嵌套时(逐层传递 props)的问题。 – 核心作用 – 跨组件共享数据(如主题、用户信息、全局配置等) – 避免中间组件透传 props(减少冗余代码) #### MobX / Redux – 全局状态管理,把状态抽离到组件之外。 **Redux** * 工作流程: 1. 定义 Store:集中管理全局状态(createStore)。 2. 派发 Action:组件通过 dispatch(action) 发出状态修改请求(action 是一个描述“发生了什么”的普通对象)。 3. 执行 Reducer:根据 action.type,纯函数 reducer 计算新状态(不可变更新)。 4. 更新视图:Store 通知订阅者(如 React 组件),触发重新渲染。 * 核心概念: – 单向数据流:View → Action → Reducer → Store → View – 三大原则:单一数据源、状态只读、纯函数修改。 * 总结: – 组件 dispatch → Reducer 处理 → Store 更新 → 视图同步 **MobX** * 工作流程: 1. 定义 Observable State:用 @observable 或 makeObservable 标记可变状态。 2. 修改 State:在 @action 函数中更新状态(直接赋值/修改对象属性)。 3. 自动追踪依赖:组件用 observer 包裹,自动订阅其依赖的状态。 4. 触发更新:状态变化时,依赖它的组件自动重渲染。 * 核心概念: – 响应式编程:像 Excel 公式一样自动更新(无需手动 dispatch/reducer)。 – 直接修改状态(但通过 action 规范变更)。 * 总结: – 响应式状态,自动追踪依赖,修改即更新 ### 【性能优化】 #### React 的渲染机制是怎样的?如何避免不必要的渲染? – 使用 React.memo、useMemo、useCallback、避免内联对象/函数。 #### React 的 key 属性有什么作用? – 帮助 React 识别元素变化,优化列表渲染。 #### 实现代码分割(Code Splitting) – 动态 import() 语法 – 动态 import() 是 ES2020 引入的语法,返回一个 Promise: “`js // 普通模块中使用 import(“./math”).then(math => { console.log(math.add(16, 26)); }); // React 组件中使用 import(“./OtherComponent”).then(OtherComponent => { // 使用加载的组件 }); “` – React.lazy + Suspense – React.lazy 和 Suspense 来实现组件的懒加载: “`js import React, { Suspense } from ‘react’; const OtherComponent = React.lazy(() => import(‘./OtherComponent’)); function MyComponent() { return (
    Loading…
    }> ); } “`
  • 〔City Corners〕佛山・南海

    南海,这里有壮阔的西樵山,有高楼林立的千灯湖CBD…….我将努力探寻南海每一个角落的独特魅力。

    佛山涌

    西樵山

  • BYD K9・岩手县交通・1:150模型

    模型资料

    岩手县交通 比亚迪 K9
    厂商
    比亚迪
    型号
    K9
    城市
    日本・岩手县
    线路
    永旺购物中心南线
    运营区间
    盛岡站 ⇄ 永旺购物中心南
    比例
    1 / 150
    材质
    塑料

    2019年1月29日,岩手県交通株式会社宣布将在2月1日上午10:00举行比亚迪K9纯电动巴士的发车仪式,这是该地区首台纯电动巴士。将投放于全长3.2公里的永旺购物中心南线,从盛岡站东口至永旺购物中心南每天运营9个来回。新车长12米,宽2.5米,高3.4米,可载客56人,几乎与现有的大型燃油客车相同;续航里程达250km,单次充电需5小时,夜间可前往矢巾町的充电站进行充电。

    车身展示

  • 13 路线停运纪念

    无意间在 B 站刷到,广州 13 路公交即将停运。作为一名公交迷,心里瞬间涌上许多感慨。这条线路从我孩童时代就陪伴左右,藏着太多散碎的童年记忆。

    我印象里,它是广州第一条无人售票线路。小时候坐 13 路,紧紧攥着几毛钱硬币,小心翼翼投进投币箱,听见 “咔嚓” 一声清脆落币,只觉得无比新奇。那时的 13 路,还是经典的广州造 GZK6100,后置引擎、蓝白涂装,在满大街还是通道车的年代,显得格外 “高大上”。

    得知它即将停运的消息,下班后我特意和太太来到文德路,再完整坐一遍 13 路的全程。从文德路总站出发,驶过海珠桥,途经工业大道、江南大道…… 每一个站名、每一段路,都熟悉得刻在心里。

    熟悉的街景缓缓掠过耳边,是亲切的粤语报站;身旁是匆匆归家的上班族、带着孩子的家长,还有不少和我一样专程来告别的公交迷。大家举着手机、相机,安静地记录着这条线路最后的时光,没有太多言语,却都藏着同一份不舍。

    特此纪念一趟车,一座城,一段回不去的时光。