前言:为什么程序员的第一个动作总是"建模型"?
想象一下开学第一天,辅导员给每个同学发学生信息卡——要求填写姓名、学号、专业、联系方式。如果没有统一格式,有人写昵称"熬夜冠军",有人把手机号写成QQ号,整个档案室就会乱成一锅粥。
数据模型就是程序的"信息卡模板",它决定了:
- 🔑 数据身份证:每个字段的类型、格式
- 🚧 安全护栏:防止乱填乱写
- 📦 收纳指南:明确数据存放规则
一、创建模型目录(建立档案室)
👉 在项目根目录右键新建model
文件夹,就像在学校行政楼里开辟一个档案室
src/
└── model/
├── user.model.ts # 学生档案
├── post.model.ts # 帖子档案
└── shop.model.ts # 二手交易档案
二、设计用户模型(你的数字学生证)
场景分析:
- 用户微信登录后,我们需要存储基本信息
- 需要展示昵称头像,但又要保护隐私信息
// model/user.model.ts
// 就像学生证的必填项
export interface User {
id: string; // 学号般的存在
nickname: string; // 展示用昵称
avatarUrl: string; // 头像(尺寸限制?后面会讲!)
// 以下信息相当于学生档案的"密封部分"
openid: string; // 微信身份证(严禁展示!)
phone?: string; // 选填手机号(用?表示)
// 时间记录(自动生成)
createTime: string; // 注册时间
}
避坑指南:
openid
是微信用户的唯一标识,相当于身份证号,绝对不能直接显示在页面上avatarUrl
建议存储缩略图地址(比如_thumb
后缀),节省流量createTime
统一用ISO时间格式(如2023-08-20T10:00:00Z
),方便排序
三、帖子模型设计(校园墙的灵魂)
需求分析:
- 支持文字+图片(参考朋友圈)
- 需要展示作者信息
- 区分普通帖子和置顶公告
// model/post.model.ts
export interface Post {
id: string; // 帖子唯一编号
content: string; // 文字内容(建议限制300字)
images?: string[]; // 图片列表(最多9张)
// 关联用户(只展示必要信息)
author: {
id: string;
nickname: string;
avatarUrl: string;
};
// 互动数据
likeCount: number; // 点赞数
commentCount: number; // 评论数
// 时间轴
createTime: string; // 发帖时间
updateTime?: string; // 编辑时间(可选)
// 管理标识
isTop?: boolean; // 是否置顶(公告用)
isHot?: boolean; // 是否热门(自动计算)
}
设计技巧:
images
使用数组存储,方便后续做轮播图- 通过
isTop
和isHot
实现帖子排序逻辑 - 嵌套的
author
对象避免暴露用户敏感信息
四、二手交易模型(跳蚤市场数字化)
业务需求:
- 商品信息发布
- 定位校内交易地点
- 买卖双方匿名对接
// model/shop.model.ts
export interface Shop {
id: string; // 商品编号
productName: string; // 商品标题
price: number; // 价格(单位:元)
imageUrls: string[]; // 商品实拍图
// 位置信息(重要!)
location: [number, number]; // [经度, 纬度]
addressLabel?: string; // 文字地址(如"三食堂门口")
// 买卖双方信息(脱敏处理)
sellerId: string; // 卖家ID
buyerId?: string; // 买家ID(未售出时为空)
// 时间轴
createdAt: string; // 上架时间
soldAt?: string; // 售出时间(可选)
// 状态管理
isSold?: boolean; // 是否已售出
isHidden?: boolean; // 是否被下架
}
避坑指南:
location
使用经纬度元组,比字符串更易计算距离addressLabel
作为辅助描述,提升用户体验- 通过
isSold
和isHidden
实现商品状态管理
五、模型使用技巧(档案室管理手册)
技巧1:类型复用(避免重复填表)
// 提取时间相关字段
interface Timestamp {
createTime: string;
updateTime?: string;
}
// 继承使用
export interface Post extends Timestamp {
//...
}
技巧2:数据转换(适配器模式)
// 处理微信返回的原始数据
export function adaptWechatUser(wechatData: any): User {
return {
id: generateUUID(), // 生成唯一ID
nickname: wechatData.nickName,
avatarUrl: wechatData.avatarUrl,
openid: wechatData.openid,
createTime: new Date().toISOString()
}
}
技巧3:表单校验(前端第一道防线)
// 发布商品校验
export function validateShopForm(form: ShopForm): boolean {
return !!form.productName &&
form.price > 0 &&
form.imageUrls.length >= 1
}
六、新手常见问题(学长踩过的坑)
❌ 错误1:滥用any类型
// 坏味道代码
let user: any = { /*...*/ }
// 正确姿势
let user: User = { /*...*/ }
❌ 错误2:直接暴露敏感字段
// 危险操作!
<template>
<div>{{ user.openid }}</div>
</template>
// 正确做法:使用计算属性过滤
const safeUser = computed(() => ({
nickname: user.nickname,
avatarUrl: user.avatarUrl
}))
下一章预告:《搭建第一个页面——信息流列表》
你将学到:
- 使用NutUI组件快速搭建界面
- 实现下拉刷新/上拉加载
- 处理图片懒加载与预览
校园小知识:为什么计算机专业要学数据库设计?
因为现实世界的"学生信息卡"就是最早的"数据模型",而图书馆管理系统就是古代的"校园墙"呀!