本周主要完成三个任务
企业项目技术栈:
一、需求:修改患者基础信息(后端未开始,等待联调):
实现了一个弹窗组件,具有“查看权限”的用户可以点击患者姓名,查看完整的患者基础信息(完整姓名、性别、生日);具有“编辑权限”的用户可以点击编辑按钮,对患者的“姓名、性别、生日”进行编辑修改。 如图所示:
二、学习TypeScript。
1.为什么有TypeScript?
JS的四种漏洞/困扰(TS解决以下问题):
(1)不清不楚的数据类型
(2)有漏洞的逻辑
(3)访问不存在的属性
(4)低级的拼写错误
2.变量声明方式
(1)基础声明
let name: string = "Alice"; // 显式类型
const age = 30; // 类型推断(inferred as number)
(2)联合类型
let id: string | number; // 多类型支持
id = "ABC123";
id = 123;
(3)解构声明
const { username }: { username: string } = getUser(); // 对象解构+类型
3.数据类型
(1)7种JS的数据类型
// 原始类型
let str: string;
let num: number;
let bool: boolean;
let nul: null;
let undef: undefined;
let sym: symbol;
let big: bigint;
// 引用类型
let obj: object;
let arr: number[]; // 数组特化
(2)六个新类型
| 类型 | 用途 | 示例 |
|---|---|---|
| any | 动态类型(慎用) | let data: any = fetch() |
| unknown | 类型安全的any | 需类型断言后使用 |
| void | 无返回值函数 | function log(): void |
| never | 永不返回的函数 | function error(): never |
| enum | 枚举 | enum Color { Red, Blue } |
| tuple | 固定长度数组 | let point: [number, number] |
(3)两个用于自定义类型方式
interface - 扩展性优先
interface User {
id: number;
name: string;
// 可选属性
email?: string;
// 方法
greet(): string;
}
// 接口继承
interface Admin extends User {
role: string;
}
接口作用: 定义类结构、定义对象结构、定义函数结构、接口之间的继承、接口自动合并(可重复定义) 何时使用接口? 定义对象的格式、类的契约、自动合并
type - 灵活性优先
type Status = 'active' | 'inactive'; // 联合类型
// 交叉类型
type AdminUser = User & { permissions: string[] };
// 工具类型
type PartialUser = Partial<User>;
**interface与type的区别: **
同:interface和type都可用于定义对象结构,两者在许多场景中可以互换
异:
(1)interface:更专注于定义对象和类的结构,支持继承、合并
(2)type:可定义类型别名、联合类型、交叉类型,但不支持继承和自动合并
**interface与抽象类的区别: **
同: 都用于定义一个类的格式(应该遵循契约)
异:
(1)接口:只能描述结构,不能有任何实现的代码,一个类可实现多个接口
(2)抽象类:既可以包含抽象方法,也可以包含具体方法,一个类只能继承一个抽象类
4.属性修饰符
public:公开的(可被类内部、子类、类外部访问)
protect:受保护的(可被类内部、子类访问)
private:私有的(可被类内部访问)
readonly:只读属性(属性无法修改)
三、学习ant-design这一UI组件的使用。
安装
npm install ant-design-vue --save
导入组件
组件库一般都提供有两种导入方式:全局导入和局部导入。
- 全局导入
import Vue from 'vue';
// ...
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
Vue.use(Antd);
// ...
-
全局导入会把所有组件都进行注册,这样会导致一些冷门的、项目中完全用不上的组件被打包到线上,所以一般不推荐使用
-
局部导入、按需加载
我们需要通过vue-cli的
babel-plugin-import插件,帮助我们自动导入组件及其样式
npm install babel-plugin-import --save-dev
修改 babel.config.js
// ...
plugins: [
[
'import',
{
libraryName: 'ant-design-vue',
libraryDirectory: 'es',
style: true
}
]
]
//...
最后导入组件
import Vue from 'vue';
// ...
import { Button, message } from 'ant-design-vue';
Vue.use(Button); Vue.prototype.$message = message;
umijs/babel-plugin-import - Babel 中文文档
1.弹窗组件(a-model):
<a-button @click="showModal">打开弹窗</a-button>
<a-modal
v-model:visible="visible"
title="患者信息"
@ok="handleOk"
:confirm-loading="confirmLoading"
>
<p>{{ modalContent }}</p>
</a-modal>
2.输入框 (a-input)
基础输入
<a-input
v-model:value="inputValue"
placeholder="请输入患者姓名"
:max-length="20"
allow-clear
/>
复合型输入框
<a-input-group compact>
<a-select v-model:value="prefix" style="width: 20%">
<a-select-option value="86">+86</a-select-option>
<a-select-option value="1">+1</a-select-option>
</a-select>
<a-input style="width: 80%" v-model:value="phone" />
</a-input-group>
表单验证(配合 Form)
<a-form-item
label="用户名"
name="username"
:rules="[{ required: true, message: '必填项' }]"
>
<a-input v-model:value="formState.username" />
</a-form-item>
3.下拉框 (a-select)
单选模式
<a-select
v-model:value="selectedPatient"
placeholder="请选择患者"
:options="patientOptions"
:field-names="{ label: 'name', value: 'id' }"
show-search
option-filter-prop="label"
/>
多选模式
<a-select
mode="multiple"
v-model:value="selectedTags"
:options="tagOptions"
:max-tag-count="2"
/>
动态加载选项
<a-select
:loading="loading"
@focus="fetchOptions"
:options="dynamicOptions"
/>
4. 日期选择框 (a-date-picker)
基础日期选择
<a-date-picker
v-model:value="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
四、总结
上周刚来公司,是第一次实习,在公司里面学习了很多技术知识,都是在学校不可能接触到的,收获很大。
公司业务方向:
医疗器械行业,负责企业级中后台管理系统B端页面的实现
项目认知:
1. 首次接触大型项目,文件模块化组织
2. 目录结构规划范例:
/src/components/EncryptData/index.tsx
/src/hooks/usePatientInfo.ts
亮点-技术实践:
- 封装加密组件(JSX实现):
① 接收props基础信息
② 权限控制:
hasPermission('patient:decrypt') 显示眼睛图标
③ 加密流程:
用户点击 → 传参给后端 → 获取完整数据