Patient H5 Note

website·Indexed 29 days ago

https://zhousg.github.io/patient-h5-note/

Technical documentation and implementation notes for the 优医问诊 (Youyi Consultation) mobile H5 project. It covers the development of medical modules including Rapid Consultation, Medicine Prescription, Consultation Rooms with socket.io, and Order management. The documentation also includes guides on the Vue 3 ecosystem (Composition API, Pinia, Vite), TypeScript core fundamentals, and deployment workflows using GitLab CI, PM2, and Nginx.

Tokens
39.3K
Snippets
198
Records
209
Agent score
74%

What's inside Patient H5 Note

  1. Introduction to Vue 3 Composition API

    Vue 3 provides two ways to organize code logic: the Options API (using data, methods, watch, etc.) and the Composition API. The Composition API organizes logic within the setup function using functions like ref and watch. Its primary advantages are better logic reusability and maintainability.
  2. Understand TypeScript basics and its relationship to JavaScript

    TypeScript (TS) is a statically typed superset of JavaScript (JS). It extends JavaScript by adding optional type annotations, allowing developers to catch type-related errors (like Uncaught TypeError) during the compilation phase rather than at runtime. Because browsers cannot execute TS directly, it must be compiled into JavaScript.
    // JavaScript: No explicit type
    let age = 18;
    
    // TypeScript: Explicitly defined as a number
    let age: number = 18;
  3. Perform type assertions with the as keyword

    Use type assertions when you have more specific knowledge about a value's type than TypeScript can infer. This is common when working with DOM elements where document.getElementById returns a generic HTMLElement. Use the as keyword to cast the variable to a more specific subtype.
    // Cast to a specific HTML element to access specific properties like .href
    const aLink = document.getElementById('link') as HTMLAnchorElement;
    
    // Cast to an image element
    const img = document.getElementById('img') as HTMLImageElement;
  4. Initialize a project with the Vue 3 and Vite technology stack

    The project uses the create-vue scaffolding tool based on Vite. The core technology stack consists of the Vue 3 ecosystem: Vue 3, TypeScript, Vue-Router, and Pinia.
    # Example of initializing a project with create-vue
    pm create vue@latest
  5. Type Template Refs in Vue

    Template refs require an explicit generic type and should be initialized with null. Because the ref is null until the component is mounted (or if removed via v-if), use optional chaining (?.) or type guards when accessing the value.
    <script setup lang="ts">
    import { ref, onMounted } from 'vue'
    
    const el = ref<HTMLInputElement | null>(null)
    
    onMounted(() => {
      el.value?.focus()
    })
    </script>
    
    <template>
      <input ref="el" />
    </template>
  6. Provide types for global Vue components

    To provide type definitions for global components in a Vue project, create a type declaration file that declares the vue module and extends the GlobalComponents interface. The key should be the component name (PascalCase) and the value should be the component type obtained via typeof the component instance.
  7. Handle null or undefined values in TypeScript

    When dealing with values that may be null or undefined (common with Template Refs), use one of the following three patterns: optional chaining, logical checks, or the non-null assertion operator.
    const input = ref<HTMLInputElement | null>(null);
    
    // 1. Optional Chaining (Read-only access)
    console.log(input.value?.value);
    
    // 2. Logical Guard (Safe for read/write)
    if (input.value) {
      input.value.value = '123';
    }
    
    // 3. Non-null Assertion (Use only when certain value exists)
    input.value!.value = '123';
  8. Install and use the TypeScript compiler (tsc)

    The TypeScript compiler (tsc) is used to convert .ts files into .js files. It can be installed globally via npm or yarn. On some macOS systems, sudo may be required for global installation.
    # Installation
    npm i -g typescript
    # OR
    yarn global add typescript
    
    # Verify installation
    tsc -v
    
    # Compile a specific file (e.g., hello.ts -> hello.js)
    tsc hello.ts
    
    # Run the resulting JS file
    node hello.js
  9. Share TypeScript types across files using .d.ts files

    To avoid duplicating type definitions across multiple .ts files, create a .d.ts (declaration) file to define and export shared types. These types can then be imported into any .ts or .vue file using standard import syntax, omitting the .d.ts extension.
    // src/types/data.d.ts
    export type Person = {
      id: number;
      name: string;
      age: number;
    };
    <script lang="ts" setup>
    import { Person } from './types/data'
    const p: Person = {
      id: 100,
      name: 'jack',
      age: 19
    }
    </script>
  10. Adapt Patient Page for patient selection

    The PatientPage is adapted to serve both as a 'Family Archive' and a 'Patient Selection' page based on the isChange=1 query parameter. When in selection mode, the UI displays a specific header and a 'Next' button, and clicking a patient records their ID.
    const route = useRoute()
    const isChange = computed(() => route.query.isChange === '1')
    
    const patientId = ref<string>()
    const selectedPatient = (item: Patient) => {
      if (isChange.value) {
        patientId.value = item.id
      }
    }
    <cp-nav-bar :title="isChange ? '选择患者' : '家庭档案'" />
    
    <div class="patient-change" v-if="isChange">
      <h3>请选择患者信息</h3>
      <p>以便医生给出更准确的治疗,信息仅医生可见</p>
    </div>
    
    <div class="patient-next" v-if="isChange">
      <van-button type="primary" round block>下一步</van-button>
    </div>
  11. Validate and save illness description data

    The 'Next' button is disabled until illnessDesc, illnessTime, and consultFlag are all provided. On submission, the data is validated and saved to the useConsultStore before redirecting the user to the patient selection page.
    const disabled = computed(
      () =>
        !form.value.illnessDesc ||
        form.value.illnessTime === undefined ||
        form.value.consultFlag === undefined
    )
    
    const next = () => {
      if (!form.value.illnessDesc) return showToast('请输入病情描述')
      if (form.value.illnessTime === undefined) return showToast('请选择症状持续时间')
      if (form.value.consultFlag === undefined) return showToast('请选择是否已经就诊')
      
      store.setIllness(form.value)
      router.push('/user/patient?isChange=1')
    }
    
  12. Simplify components with the <script setup> syntax sugar

    The <script setup> syntax sugar removes the need to export a default object, declare a setup function, and manually return variables to the template. All top-level variables, functions, and imports declared inside <script setup> are automatically available to the template.
    <script setup>
      import { ref } from 'vue';
    
      const count = ref(0);
      const increment = () => {
        count.value++;
      };
    </script>
    
    <template>
      <button @click="increment">{{ count }}</button>
    </template>