Skip to content

首页列表与云开发环境(四) ​

本页对应 首页列表与云开发环境,共 6 段视频,约 38 分钟。

学习目标 ​

  • 能够使用 defineProps 获取页面地址中的 type 与 level 参数,并在跳转病情描述页时拼接科室 id,构造包含 type、level、deptId 三个查询参数的 URL,点击科室后可在地址栏验证参数正确。
  • 能够将病情描述页的模板与样式接入项目并替换原页面内容,使页面正常渲染在线医生静态区域、文字描述输入框、患病时长选项和是否就诊选项。
  • 能够定义患病时长与是否就诊的选项数组,使用 v-for 渲染列表,通过点击事件传递 value 并与当前选中值比较来动态添加 active 类,实现任一时刻仅一个选项高亮且默认无选中。
  • 能够使用 ref 定义病情描述表单数据,使用 v-model 获取文字描述,通过选项点击回写患病时长和是否就诊值,并在调试器中验证三项数据随用户操作正确更新。
  • 能够登录 uniCloud 控制台创建阿里云免费服务空间,并在 HBuilderX 中通过项目右键创建阿里云云开发环境、关联对应服务空间,确认项目出现云开发环境目录且重启项目后关联生效。

知识点 ​

一、地址参数要一路带完整 ​

为什么需要:用户从“急速问诊 → 三甲医院 → 消化内科”一路选过来,进入病情描述页后,页面必须知道三件事:问诊类型、医院级别、科室。前两个参数地址栏里已有,科室参数没有,所以新页面会不知道用户选的是消化内科。

怎么想:先在病情描述页用 defineProps 接收地址上的 type 和原有医院级别参数;科室 ID 不单独请求,而是在遍历二级科室时从当前项自身取 ID,再拼到 navigator 的跳转地址里。地址参数本质都是字符串,不要因为看到 1、2 就当成数字类型。

怎么做:关键结构如下,参数名以项目实际为准,长参数名建议复制,避免手写错。

js
// 病情描述页接收地址参数
defineProps({
  type: String,
  原参数名: String
})
html
<!-- 二级科室遍历项中拼三个参数 -->
<navigator
  :url="`/description?type=${props.type}&原参数名=${props.原参数名}&id=${item.id}`"
>
  {{ item.name }}
</navigator>

易错点:defineProps 里的名字必须和地址参数名一致;& 不能丢;科室 ID 要从二级科室的遍历项取,不要拿到一级科室;点“消化内科”后要检查地址栏,转写稿中的验证结果是出现 2(急速问诊)、1(三甲)和科室 ID。

二、病情描述页先把页面壳搭出来 ​

为什么需要:选完科室后还差一步:用户要先描述病情,系统再分配医生。这个页面本质上是一个表单页。

怎么想:把 description/index.vue 的布局和 index.scss 样式拿过来,替换原内容;静态的“在线医生”区域不用管,重点保留文本域、患病时长、是否就诊、图片上传区域。

怎么做:先完成布局和样式,再逐步实现表单数据、tab 切换、图片上传。图片上传放到最后,因为会用到 uni-app 云开发。

易错点:不要一开始就混着写上传逻辑;静态区域不要误绑定数据;文本域、tab、上传区要按表单结构组织,后续才好做验证。

三、患病时长 tab:交互用 value,不用索引 ​

为什么需要:既要点谁谁高亮,又要把用户选中的值交给后端。转写稿强调,1、2、3、4 不是随便定的,是后端接口规定的;是否就诊的 0/1 也一样。

怎么想:构造数组后 v-for 遍历,每个元素绑定点击事件,点击时把 item.value 传给函数,再赋值给病情数据中的选中值字段。高亮条件用 item.value === 选中值。

怎么做:

html
<div
  v-for="item in timeList"
  :key="item.value"
  :class="{ active: form.time === item.value }"
  @click="onTimeTagClick(item.value)"
>
  {{ item.text }}
</div>
js
const form = ref({ time: '', desc: '', visited: '' })

function onTimeTagClick(value) {
  form.value.time = value
}

易错点与调试:一开始所有 tab 都高亮,是因为每个元素都无条件加了 active,要改成条件类名;点击报 undefined,是定义数据时忘了 ref,加上后通过 .value 访问;初始值给空字符串,既不会默认选中,也方便后续表单验证。

四、病情文字说明直接用 v-model ​

为什么需要:文字说明是用户主动填写,最容易获取。

怎么想:把 textarea 绑定到病情数据对象的描述字段,不用额外事件。

怎么做:

html
<textarea v-model="form.desc"></textarea>

易错点:绑定层级要落在表单对象内部;字段名建议复制,防止拼错;验证时看初始为空、输入后数据同步变化。

五、图片上传前先创建并关联云空间 ​

为什么需要:图片要上传到服务器。uni-app 可以用云开发,不必先调后端上传接口。

怎么想:先开通 uniCloud 服务空间,选阿里云免费空间;再让项目和云空间关联,否则代码无法使用。

怎么做:登录 uniCloud 控制台,新建服务空间,选阿里云免费版,命名可用 consult-patient;在项目目录右键“创建 uniCloud 云开发环境”,选阿里云;再右键“关联”选择刚建的空间;最后重启项目生效。

易错点:项目与云空间不会自动关联;腾讯云没有同样免费额度;免费空间一个月后可续期;不完成关联,后续上传代码无法写。

一、这一节在整条业务线上的位置 ​

前面我们已经能把用户从「急速问诊 → 三甲医院 → 消化内科」一路选到科室了。但选完科室还没到「问医生」,中间还差一步:让患者先把自己的情况描述清楚,也就是「病情描述」页。这个页面的作用是把病情、患病时长、是否就诊过、病情图片这些信息收集起来,后端再据此分配医生。

所以这一节要干两件事:一是把科室 ID 继续拼到跳转地址里,保证下一页知道「你选的是哪个科室」;二是把病情描述页的结构、数据和 tab 切换交互做出来。图片上传因为要依赖云开发,放到后面单独处理。

二、跳转时把科室 ID 一起带上 ​

为什么需要?现在地址栏里只有两个参数:type(2 表示急速问诊)和医院级别(1 表示三甲)。用户点了「消化内科」跳过去时,新页面根本看不出选的是哪个科室,所以必须再加一个科室 ID。这个 ID 接口里是有的,展开任意一个二级科室的网络请求就能看到 id 字段。

怎么想?先把地址上的两个参数拿到,再在遍历二级科室时把 item.id 拼上去,最终凑成三个参数。

怎么做?在科室页用 defineProps 接收地址参数,名字必须和地址栏里的参数名一致:

js
// 参数名要和地址栏中的一致,类型统一写 String(地址参数本质是字符串)
const props = defineProps({
  type: String,     // 2 = 急速问诊
  level: String     // 1 = 三甲
})

然后在 navigator 上拼地址,注意用反引号,& 不能丢:

html
<navigator
  v-for="item in secondList"
  :key="item.id"
  :url="`/pages/description/index?type=${props.type}&level=${props.level}&id=${item.id}`"
>

易错点:① 用单引号写字符串,${} 就不生效了;② 多个参数之间的 & 漏掉,后面参数全被当成第一个参数的值;③ id 这个名字是接口规定的,不能自己改。

三、病情描述页的结构 ​

把 pages/description/index.vue 的模板和 index.scss 样式贴过来。页面从上到下是:静态的在线医生头像区(纯静态,不用管)、病情文字描述 textarea、患病时长 tab、是否就诊过 tab、图片上传区。

这个页面本质就是一个表单,所以后面要做的功能也就清楚了:取表单数据、tab 切换、图片上传、表单验证。

四、患病时长:用数据驱动 tab ​

为什么需要?四个时长选项如果写四份死标签,高亮判断和取值都要复制四遍。用数组 + v-for 遍历,才能统一处理。

怎么想?这个 tab 和之前做过的 tab 是同一套路,区别只在比较的依据。

怎么做?数组里的 value 不是随便写的 1、2、3、4,而是后端接口规定的值,交互和提交数据共用它:

js
// 不需要 ref:这份数据全程不改,用普通常量还能省一点开销
const timeList = [
  { text: '一周内', value: 1 },
  { text: '一个月内', value: 2 },
  { text: '半年内', value: 3 },
  { text: '半年以上', value: 4 }
]

const formData = ref({
  desc: '',
  time: '',
  isVisit: ''
})

function onTimeTagClick(value) {
  formData.value.time = value
}
html
<view
  v-for="item in timeList"
  :key="item.value"
  :class="{ active: formData.time === item.value }"
  @click="onTimeTagClick(item.value)"
>
  {{ item.text }}
</view>

调试过程里踩过一个坑:点击时报 undefined,原因是 formData 定义时漏了 ref,没有 .value 可访问。补上 ref 之后点击正常,值会从空串变成 1、2、3。

五、为什么这里比较 value 而不是索引 ​

以往的 tab 都是拿索引 index 做比较,这次刻意换成 value,原因是:value 就是最终要提交给后端的数据。用索引只能做交互,还得再想办法把值取出来;用 value 做交互,点一下既完成高亮,又顺手拿到了要提交的值,一举两得。

初始值不要给 1 或 2,给空串。给了 1 就默认选中「一周内」,用户没选也会有值,后面做表单验证反而麻烦。空串不匹配任何一个 value,四个选项就都不高亮。

「是否就诊过」逻辑完全一样:0 表示没就诊过,1 表示就诊过,同样是接口规定的值。

六、文字描述用 v-model ​

textarea 是用户主动输入的,最简单:

html
<textarea v-model="formData.desc" placeholder="请描述您的病情"></textarea>

易错点:v-model 一定要写在 textarea 标签上,别写到外层包裹的 view 上;formData.desc 拼错不会报错,只会静默失效,建议从定义处复制。

七、开通并关联云开发空间 ​

图片上传用 uni-app 的云开发,比调后端上传接口简单。步骤:登录云开发控制台 → 新建服务空间,选阿里云(有 0 元免费空间,一个月到期点续期即可无限用)→ 名字建议 consult-patient → 立即购买(0 元)。然后回到项目,在项目目录右键「创建 uniCloud 云开发环境」,选阿里云;再右键「关联」服务空间,选中刚才建的那个。不关联,后面上传代码根本没法写。关联后需要重启项目才生效。

从科室选择到病情描述:先把参数带全 ​

为什么需要:用户从“急速问诊 → 三甲医院 → 消化内科”一路点进来,到了病情描述页,页面必须知道“问诊类型、医院类型、科室”。否则后续分配医生、提交表单时不知道用户选的是哪条业务线。

怎么想:地址栏里已经能看到两个参数:type 表示问诊类型,另一个参数表示医院类型;但科室信息看不出来,所以跳转到 description 页面时还要再拼一个科室 ID。课堂中明确说:三个参数分别是问诊类型、医院类型、科室 ID,其中科室 ID 来自二级科室数据里的 id 字段。

怎么做:在页面里用 defineProps 接收地址参数,参数名要和地址栏一致,类型按字符串声明。转写稿里的“deefine crop”应纠正为 defineProps,“死追营”应理解为 String。地址参数即使看起来是数字,本质上也是字符串。跳转时用模板字符串拼参数,& 不能丢:

html
<navigator
  :url="`/pages/description/index?type=${props.type}&hospital=${props.hospital}&id=${item.id}`"
>
  跳转
</navigator>

易错点:参数名不要自己随便起;& 漏写会导致后一个参数丢失;科室 ID 要在遍历二级科室时取,不要拿到一级科室;defineProps 里声明的名字要和地址参数对应。

页面结构:把病情描述当成表单 ​

为什么需要:病情描述页不是纯展示页,用户要填写文字、选择患病时长、选择是否就诊过,还要上传图片。它本质上是一个表单。

怎么想:先熟悉结构:顶部“在线医生”区域是纯静态的,可以先折叠不管;下面才是患者信息。文字说明区域是文本域,可以直接用 v-model;患病时长和是否就诊过是两组 tab 切换;图片上传放到最后,用云开发处理。

怎么做:先定义表单数据对象,至少包含三项:病情文字描述、患病时长、是否就诊过。文字说明用 v-model 绑定:

html
<textarea v-model="form.desc"></textarea>

易错点:不要一上来就写上传;先把前三个数据搞定。文字说明虽然简单,但变量名要复制准确,避免手写错。

患病时长为什么用数组渲染 ​

为什么需要:患病时长有“一周内、一个月内、半年内、半年以上”等选项,如果每个 tab 都手写一遍,结构重复、选中态也难维护。

怎么想:把它当成 tab 切换。遍历数组生成每一项,遍历时能拿到 text 和 value。课堂中强调:value 的 1、2、3、4 不是随便定的,而是后端接口规定的;是否就诊过的 0/1 也一样。

怎么做:定义一个不会修改的数组,不必用 ref:

js
const timeList = [
  { text: '一周内', value: 1 },
  { text: '一个月内', value: 2 },
  { text: '半年内', value: 3 },
  { text: '半年以上', value: 4 }
]

模板中遍历:

html
<view
  v-for="item in timeList"
  :key="item.value"
  :class="{ active: form.time === item.value }"
  @click="changeTime(item.value)"
>
  {{ item.text }}
</view>

易错点:v-for 的 :key 用不重复的 value;不要把所有项都加上 active,否则会出现“全都高亮”。

选中态为什么比较 value 而不是 index ​

为什么需要:只做交互时,用索引也能高亮;但提交给后端时需要的是 value,不是第几项。课堂中特意用 value 做交互,就是为了“既完成切换,又拿到用户选中的值”。

怎么想:给表单数据一个初始值,比如空字符串或 0,让默认不选中,后面做校验更方便。点击时把当前项的 value 传给函数,函数再赋给表单数据。

怎么做:

js
const form = reactive({
  desc: '',
  time: '',
  visited: ''
})

function changeTime(value) {
  form.time = value
}

点击“一个月内”时,form.time 变成 2,模板中 form.time === item.value 的项才加 active。

易错点:转写稿调试时出现 undefined,原因是把 ref 丢了,导致不能访问 .value;补回 ref 后才正常。另一个易错点是 class 写成固定值,导致每项都高亮。下面“是否就诊过”用同样思路再做一遍即可。

图片上传与云开发:先完成环境准备 ​

为什么需要:图片要上传到服务器。uni-app 可以使用云开发,不必先调后端上传接口。

怎么想:先申请阿里云免费服务空间,再让项目和云空间关联。课堂中说明:创建云空间不等于项目已关联,必须右键项目创建 uniCloud 云开发环境,再关联服务空间。

怎么做:按课堂步骤选择阿里云免费空间,项目右键创建云开发环境,右键关联服务空间,最后重启项目生效。图片上传代码留到下一节。

易错点:只建空间不关联,后面上传无法进行;关联后要重启项目才生效。

代码示例 ​

代码 1:二级科室列表页(三个参数一起往下传) ​

vue
<!-- pages/department/index.vue -->
<template>
  <view class="dept-list">
    <!-- 二级科室列表:在 v-for 内部才能拿到每个科室自己的 id -->
    <navigator
      v-for="item in subDeptList"
      :key="item.id"
      class="dept-item"
      :url="`/pages/description/index?type=${props.type}&illnessType=${props.illnessType}&deptId=${item.id}`"
    >
      <text>{{ item.name }}</text>
    </navigator>
  </view>
</template>

<script setup>
import { ref } from 'vue'

// 1. 先把地址栏上的两个参数接住
// 参数名必须和上一页链接里写的名字一模一样,怕写错就复制过来
const props = defineProps({
  type: String,        // 问诊类型:急速问诊 / 普通问诊
  illnessType: String  // 第二个参数(名字照抄项目里上一页的写法)
})

// 2. 二级科室列表,数据来自二级科室接口
// 接口返回的每一项里自带 id,遍历时直接就能拿到
const subDeptList = ref([])
</script>

<style scoped>
.dept-item {
  padding: 30rpx;
  border-bottom: 1rpx solid #eee;
}
</style>

要点解释

  • defineProps 就是用来接地址栏参数的,type 这个名字不是随便起的:上一页链接里叫 type,这里就必须叫 type。
  • 地址栏上的参数全都是字符串,所以声明成 String,不要写成 Number。
  • 三个参数之间必须用 & 连接,少一个 & 后面那个参数就丢了;顺序无所谓,但三个都要带上。
  • deptId 这个名字是接口规定的,不能自己改成 id 或 deptid,否则后端接不到。
  • item.id 必须在 v-for 的作用域里取,写到循环外面拿不到;navigator 的 url 前面必须加 : 并用反引号模板字符串才能拼变量。

代码 2:病情描述页(tab 切换 + 表单数据) ​

vue
<!-- pages/description/index.vue -->
<template>
  <view class="description">
    <!-- 在线医生:纯静态结构,不用处理 -->
    <view class="doctor-online">
      <text class="online-text">在线医生</text>
    </view>

    <!-- 患者信息 -->
    <view class="patient-info">
      <!-- 病情文字描述:表单元素直接用 v-model -->
      <textarea
        v-model="info.desc"
        class="desc-input"
        placeholder="请描述您的病情(症状、程度等)"
      />

      <!-- 患病时长:遍历数据做 tab 切换 -->
      <view class="tag-list">
        <view
          v-for="item in timeList"
          :key="item.value"
          class="tag"
          :class="{ active: info.time === item.value }"
          @click="onTimeTagClick(item.value)"
        >
          {{ item.text }}
        </view>
      </view>

      <!-- 是否就诊过:逻辑和上面完全一样 -->
      <view class="tag-list">
        <view
          v-for="item in visitList"
          :key="item.value"
          class="tag"
          :class="{ active: info.visit === item.value }"
          @click="onVisitTagClick(item.value)"
        >
          {{ item.text }}
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref } from 'vue'

// 患病时长:value 是后端接口规定的值,不是随手写的 1、2、3、4
// 不用 ref,因为这组数据从头到尾不会被改,直接当常量用
const timeList = [
  { text: '一周内', value: 1 },
  { text: '一个月内', value: 2 },
  { text: '半年内', value: 3 },
  { text: '半年以上', value: 4 }
]

// 是否就诊过:0 = 没就诊过,1 = 就诊过(同样是后端规定)
const visitList = [
  { text: '没就诊过', value: 0 },
  { text: '就诊过', value: 1 }
]

// 病情数据:初始值给空,保证默认都不高亮,也方便后面做表单校验
const info = ref({
  desc: '',  // 病情文字描述
  time: '',  // 患病时长
  visit: ''  // 是否就诊过
})

// 点击切换患病时长:把传过来的 value 赋给 info.time
const onTimeTagClick = (value) => {
  info.value.time = value   // 注意 .value 不能丢
}

// 点击切换是否就诊过
const onVisitTagClick = (value) => {
  info.value.visit = value
}
</script>

<style scoped>
.description { padding: 20rpx; }
.desc-input {
  width: 100%;
  height: 200rpx;
  padding: 20rpx;
  box-sizing: border-box;
  border: 1rpx solid #eee;
}
.tag-list { display: flex; flex-wrap: wrap; margin-top: 20rpx; }
.tag {
  padding: 10rpx 30rpx;
  margin-right: 20rpx;
  font-size: 28rpx;
  border: 1rpx solid #ddd;
  border-radius: 8rpx;
}
.tag.active {
  color: #fff;
  background-color: #2b7afb;
  border-color: #2b7afb;
}
</style>

要点解释

  • 高亮判断用 info.time === item.value 而不是索引值:value 既是判断条件,又是将来要提交给后端的值,一步到位;用索引值只能做交互,还得再换算一次。
  • value 的 1/2/3/4 和 0/1 是后端接口规定的,不能为了写交互自己随便定。
  • info 用 ref 包了一层,函数里赋值必须写 info.value.time;模板里 Vue 会自动解包,所以模板写 info.time。漏掉 .value 会报 undefined 之类的错误。
  • 初始值给空字符串 '',所以一进页面所有标签都不高亮;如果给 1,那一周内会默认选中。
  • :key 用 item.value 而不是索引,保证不重复;v-model 只能加在 textarea、input 这类表单元素上,不能加在 view 上。
  • class="tag" 和 :class="{ active: ... }" 可以同时写,Vue 会把它们合并,不会互相覆盖。

常见错误 ​

  1. 跳转后新页面取不到 type、illnessType 参数

    • 现象:进入病情描述页时 defineProps 拿到的值是 undefined,或页面提示缺少参数。
    • 原因:在列表页拼接跳转地址时把已有的两个参数丢了,只拼了科室 ID;或者 defineProps 里声明的字段名与地址栏问号后面的 key 拼写不一致。
    • 修法:跳转 URL 固定拼三个参数,用反引号模板串 + & 连接;defineProps 的字段名直接从跳转处复制,避免手写。建议写成 ?type=${type}&illnessType=${illnessType}&departmentId=${item.id} 这类形式,逐项核对。
  2. defineProps 报 “not defined” 或取值时提示找不到属性

    • 现象:控制台出现 defineProps is not defined;或后续写 xxx.value 时报 undefined。
    • 原因:漏写 import { defineProps } from 'vue'(或按项目约定从 vue 导入),或声明了 props 却当成普通变量直接 .value 访问。
    • 修法:补齐导入语句;props 按项目约定访问(模板里直接用名字,脚本里按 props 对象取值),不要把 props 与 ref 混用。
  3. tab 切换时所有项一起高亮

    • 现象:进入页面后“一周内/一个月内/半年内”全部带上了 active 类名。
    • 原因::class 里写了固定类名字符串,没有加判断条件;或判断依据写成了恒真表达式。
    • 修法:改成 :class="{ active: form.illnessTime === item.value }",让类名由数据比较结果决定,而不是无条件添加。
  4. 点击 tab 后高亮不切换,或切换了但提交值为空

    • 现象:点击某一项界面无变化;或界面变了但最终提交的时长字段始终是初始值。
    • 原因:点击事件里修改的是索引而不是被选中的 value;或只改了局部变量没改表单对象字段;或 ref 漏写导致赋值不生效。
    • 修法:点击时把当前项的 value 传给处理函数,函数内把表单对应字段赋值为该 value;确认表单对象是用 ref/reactive 声明的,赋值时带上 .value(ref 场景)。
  5. 给患病时长设了默认选中,用户没操作就提交了

    • 现象:用户未选择时长也能继续,提交数据里带着一个“一周内”。
    • 原因:初始化时把时长字段写成了 1(或某个有效枚举值),导致默认命中某一项。
    • 修法:初始值设为空字符串或 0 这类不属于枚举范围的值,让所有项默认不高亮;后续做非空校验时也更方便。
  6. 把 1/2/3/4、0/1 当成自己随便定的交互值

    • 现象:交互跑通了,但对接接口时数值对不上,后端返回参数错误。
    • 原因:为了写高亮效果随意定义了枚举值,没有对照接口文档。
    • 修法:枚举值以后端接口规定为准(如时长 1=一周内、2=一个月内……,就诊 0=未就诊、1=就诊过);交互直接用这套 value 做比较和提交,不要另造一套索引映射。
  7. 图片上传相关:云空间建了但项目用不了

    • 现象:调用上传时报错,或提示找不到云开发环境。
    • 原因:只在控制台创建了服务空间,没有在项目里创建云开发环境并做关联;或关联后没有重启项目。
    • 修法:项目目录右键创建 uniCloud 云开发环境(选阿里云)→ 右键关联到已建的服务空间 → 重启项目使其生效。注意免费空间有期限,到期需续期。

练习 ​

  1. 参数链路补全:从科室列表页点击某个二级科室,跳转到病情描述页,要求地址栏同时带上问诊类型、医院类型、科室 ID 三个参数,并在病情描述页用 defineProps 接收后打印到控制台验证。故意把其中一个参数名写错,观察报错表现并修正。

  2. tab 组件化:把“患病时长”和“是否就诊过”两组 tab 抽成同一套逻辑(可复制结构,也可抽公共组件),要求:数据由数组遍历渲染;点击时更新表单字段;高亮由“当前字段值 === 项的 value”决定;初始状态全部不高亮。

  3. 枚举值校验:给病情描述页加一段提交前校验——时长未选、是否就诊未选、文字描述为空时分别给出提示并阻止提交。要求校验逻辑基于接口规定的枚举值(时长 1~4、就诊 0/1),而不是基于索引。

  4. 表单数据收集:用 v-model 绑定文字描述,配合两组 tab 的选中值,组装出一个包含 description、illnessTime、isVisited 三个字段的提交对象,点击“下一步”时在控制台打印该对象,确认三项都有值。

  5. 云环境联通验证:完成服务空间创建 → 项目内创建云开发环境 → 关联 → 重启项目,然后写一个最小验证:调用一次上传或读取云能力的接口,确认能正常返回而不是报“环境不存在”。

课堂画面 ​

课堂画面 01

课堂画面 02

课堂画面 03

课堂画面 04

课堂画面 05

课堂画面 06

原视频对照 ​

#视频时长
1优医咨询-地址传递参数06:04
2优医咨询-病情描述模板03:03
3优医咨询-病情描述患病时长处理16:53
4优医咨询-病情描述文字说明05:20
5优医咨询-申请阿里云空间04:14
6优医咨询-创建云开发环境03:18

小结 ​

  1. 页面间传参是链式的:上一页拿到什么就必须原样往下带,新增参数只能追加,不能覆盖。地址栏里出现三个参数,才说明当前上下文(问诊类型 + 医院类型 + 科室)是完整的。
  2. defineProps 的字段名必须与地址栏 key 完全一致,最稳的做法是从跳转处复制过来,不要凭记忆手写。
  3. 列表渲染时数据本身就带 ID,不需要额外请求,遍历时顺手拼进跳转地址即可。
  4. tab 类交互优先用数组遍历 + 条件类名实现,而不是写死几个 div;条件判断用 value 比用索引更划算,因为 value 同时就是要提交的数据。
  5. 交互用的值和提交给后端的值是同一套,枚举以接口文档为准;自己另造索引映射,后面必然要再写一层转换。
  6. 表单类页面的默认值要谨慎:给了有效枚举值就等于替用户做了选择,初始给空值既符合交互预期,也方便做必填校验。
  7. 图片上传走云开发比对接后端接口更省事,但前置条件(建空间、建环境、关联、重启)一个都不能少,否则代码写得再对也传不上去。