Chuyển đến nội dung chính

Bài 16: Vibe Coding cho Mobile & Cross-Platform

Phát triển ứng dụng mobile bằng Vibe Coding. React Native và Flutter workflows. UI generation, navigation, API integration. Platform-specific code. Testing mobile apps. Deploy lên App Store và Google Play.

💻 Lập trình — Bài 16 Bài 16: Vibe Coding cho Mobile & Cross-Platform

Vibe Coding với GitHub Copilot: Từ Cơ bản đến Nâng cao

Phần 5: Vibe Coding thực chiến — Xây dựng dự án thực tế

xdev.asia

1. Vibe Coding trên Mobile — Khác gì so với Web?

Mobile development có những đặc thù riêng mà Vibe Coding cần thích ứng:

Đặc điểm Web Mobile
Layout CSS Flexbox/Grid Platform-specific layout
Navigation URL-based routing Stack/Tab navigation
Testing Browser → instant feedback Emulator/Device → chậm hơn
Native APIs Hạn chế Camera, GPS, Sensors, Push
Performance DOM rendering Native rendering
Deploy Vercel/Netlify App Store review process

2. React Native với Vibe Coding

2.1. Setup project

// Prompt:
Create a React Native project with Expo for the Task Management app.
Include:
- TypeScript
- React Navigation (stack + bottom tabs)
- React Query for API calls
- AsyncStorage for local state
- Expo secure-store for auth tokens
- NativeWind (TailwindCSS for React Native)

2.2. Shared types với Backend

// Prompt:
I have a backend with these API responses (paste TypeScript types).
Generate React Native API client and hooks that match these types exactly.
Reuse the same Zod schemas from the web frontend.
// src/hooks/useTasks.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '../lib/api';
import type { Task, CreateTaskInput } from '../types';

export function useTasks(projectId: string) {
  return useQuery({
    queryKey: ['tasks', projectId],
    queryFn: () => api.get<Task[]>(`/tasks?projectId=${projectId}`),
  });
}

export function useCreateTask() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: CreateTaskInput) => api.post('/tasks', data),
    onSuccess: (_, variables) => {
      queryClient.invalidateQueries({
        queryKey: ['tasks', variables.projectId],
      });
    },
  });
}

2.3. Mobile-specific UI

// Prompt:
Create a task list screen for React Native with:
- Pull to refresh
- Infinite scroll pagination
- Swipe to complete/delete
- FAB (floating action button) to add tasks
- Priority color indicators
- Use NativeWind for styling
// src/screens/TaskListScreen.tsx
import { FlatList, RefreshControl, View, Text, Pressable } from 'react-native';
import { Swipeable } from 'react-native-gesture-handler';
import { useTasks } from '../hooks/useTasks';

export function TaskListScreen({ route }) {
  const { projectId } = route.params;
  const { data, isLoading, refetch } = useTasks(projectId);

  const priorityColors = {
    LOW: 'bg-green-500',
    MEDIUM: 'bg-yellow-500',
    HIGH: 'bg-orange-500',
    URGENT: 'bg-red-500',
  };

  const renderTask = ({ item: task }) => (
    <Swipeable
      renderRightActions={() => (
        <Pressable className="bg-green-500 justify-center px-6"
          onPress={() => completeTask(task.id)}>
          <Text className="text-white font-bold">Done</Text>
        </Pressable>
      )}>
      <View className="bg-white p-4 border-b border-gray-100 flex-row items-center">
        <View className={`w-3 h-3 rounded-full mr-3 ${priorityColors[task.priority]}`} />
        <View className="flex-1">
          <Text className="font-semibold text-gray-900">{task.title}</Text>
          <Text className="text-gray-500 text-sm">{task.assignee?.name}</Text>
        </View>
      </View>
    </Swipeable>
  );

  return (
    <View className="flex-1 bg-gray-50">
      <FlatList
        data={data}
        renderItem={renderTask}
        refreshControl={
          <RefreshControl refreshing={isLoading} onRefresh={refetch} />
        }
      />
    </View>
  );
}

3. Flutter với Vibe Coding

3.1. Flutter project setup

// Prompt:
Create a Flutter app for Task Management with:
- Clean architecture (presentation, domain, data layers)
- Riverpod for state management
- Go Router for navigation
- Dio for API calls
- Freezed for immutable models
- Material 3 design

3.2. Dart model generation

// Prompt:
Generate Freezed models for these API responses:
- Task (id, title, description, status, priority, dueDate, assignee)
- Project (id, name, description, owner)
- User (id, email, name, avatar)
Include fromJson/toJson serialization.
// lib/models/task.dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'task.freezed.dart';
part 'task.g.dart';

@freezed
class Task with _$Task {
  const factory Task({
    required String id,
    required String title,
    String? description,
    @Default(TaskStatus.todo) TaskStatus status,
    @Default(Priority.medium) Priority priority,
    DateTime? dueDate,
    User? assignee,
  }) = _Task;

  factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
}

enum TaskStatus {
  @JsonValue('TODO') todo,
  @JsonValue('IN_PROGRESS') inProgress,
  @JsonValue('IN_REVIEW') inReview,
  @JsonValue('DONE') done,
}

enum Priority {
  @JsonValue('LOW') low,
  @JsonValue('MEDIUM') medium,
  @JsonValue('HIGH') high,
  @JsonValue('URGENT') urgent,
}

3.3. Flutter UI với Copilot

// Prompt:
Create a Flutter task board widget with:
- Horizontal scrollable columns (Todo, In Progress, Done)
- Draggable task cards between columns
- Material 3 card design
- Pull to refresh
- Hero animation when opening task detail

4. Platform-Specific Code

// Prompt:
Add push notifications to the mobile app:
- Firebase Cloud Messaging setup
- Handle foreground/background/terminated states  
- Deep link to specific task when notification tapped
- Platform-specific code for iOS (APNs) and Android (FCM)

Copilot hiểu platform differences và generate code phù hợp cho từng platform.

5. So sánh: React Native vs Flutter cho Vibe Coding

Tiêu chí React Native Flutter
AI code quality Tốt (nhiều training data) Tốt (growing ecosystem)
Code sharing với web Cao (shared TypeScript) Thấp (Dart riêng)
Copilot suggestions Rất chính xác (JS/TS) Chính xác (Dart)
Component generation Nhanh (JSX familiar) Nhanh (widget tree)
Testing với AI Jest + RTL (quen thuộc) Widget testing (learning curve)
Hot reload Fast Refresh ✅ Hot Reload ✅

Recommendation: Nếu team đã dùng React cho web → React Native. Nếu cần performance cao và custom UI → Flutter.

6. Testing Mobile Apps

// Prompt cho React Native:
Write tests for TaskListScreen:
- Renders task list from API
- Pull to refresh calls refetch
- Swipe right completes task
- Shows loading indicator
- Shows empty state when no tasks
Use @testing-library/react-native
// Prompt cho Flutter:
Write widget tests for TaskBoard:
- Renders columns with correct titles
- Shows tasks in correct columns
- Drag and drop changes task status
- Pull to refresh triggers reload

7. Deploy Mobile Apps

// Prompt:
Create a CI/CD pipeline for the React Native app:
- GitHub Actions workflow
- Build for iOS (using Expo EAS)
- Build for Android (using Expo EAS)
- Auto-submit to TestFlight and Google Play Internal Testing
- Run tests before build

8. Tổng kết

Mobile Task Vibe Coding Effectiveness
UI screens ⭐⭐⭐⭐⭐ Rất hiệu quả
API integration ⭐⭐⭐⭐⭐ Type-safe và nhanh
Navigation ⭐⭐⭐⭐ Tốt với patterns quen
Native APIs ⭐⭐⭐ Cần review platform specifics
Performance tuning ⭐⭐ Cần human expertise
App Store submission ⭐⭐⭐ CI/CD setup tốt, nhưng cần manual review

Phần 6 sẽ tập trung vào chất lượng và chuyên nghiệp — Code quality, security, technical debt, và làm việc trong team với Vibe Coding.