I am currently writing code projects in Vue 3 + TypeScript. Let’s talk about some of my feelings: JavaScript itself is a weak language type, in simple and easy to use at the same time, but also brought the problem of type confusion. TypeScript emerges as a superset of JavaScript that enforces language-type “JavaScript.” When writing TypeScript code, you define types; Use written types to define variables for strongly typed purposes.

A primer on TypeScript: juejin.cn/post/690313… Introduction to Vue 3: juejin.cn/post/690818…

Ref Reactive Incoming type

interface LeaveInfoForm {
  userId: number | undefined.startDate: string,
  endDate: string,
  attendanceEventTypeCode: string | undefined,    
}

interface DatePartEnum{
  code: string
  name: string
}

const switchOptions = ref<DatePartEnum[]>([])

const formState = reactive<LeaveInfoForm>({
  userId: undefined.startDate: ' '.endDate: ' '.attendanceEventTypeCode: undefined,})Copy the code

The generic type of Ref Reactive is passed in to enhance VS Code’s prompt and takes advantage of typescript type checking to avoid type errors.

Application of enumeration types

In a project, when you encounter the above TAB switch, you can use enumerated types to make your code more readable

enum EventType{
    StatutoryAnnualLeave = 11,
    WelfareLeave = 12,
    FullPaySickLeave = 13,
    TransferVacation = 14,}switch (holidaysRecordParams.typeCode) {
    case EventType.StatutoryAnnualLeave:
    break.default:
    break
}
Copy the code

Write a declaration document for the project

The main purpose of writing your own project declaration file is to expose some global types, facilitate unified management, and reduce the writing of duplicate code.

  1. Declare the location of the file: It can be anywhere in the project, and this location has a configuration compilation path in the tsconfig.json include or files

  1. Declare declared types and variables are global and need to be added to.eslintrc.js

DefineAsyncComponent imports dynamic components and cache components in keep-alive

const Home = defineAsyncComponent(() = > import('.. /Home/Home.vue'))
Copy the code

The name of the Home component is no longer homeNoKeep as defined in the Home component. AsyncComponentWrapper () {exclude/include from keep-alive is the name of the component. The reason is that the name of the Home component has been changed.

Solution: Manually modify the name property of the Home component:

const Home: any = defineAsyncComponent(() = > import('.. /Home/Home.vue'))
Home.name = 'homeNoKeep'
Copy the code

In this way, the Home component is not cached to meet business requirements

Composition Api

You need to implement a function that slides up to hide a filter and slides down to show a filter in a move item. Pull out the finger up and down events here:

// useMouseMove.ts

import { reactive, onMounted, onBeforeUnmount } from 'vue'

const MIN_DISTANCE = 10
interface Position{
  x: number
  y: number
}
type FnArgus = () = > void
function useMouseMove(onMoveDown: FnArgus = () => {}, onMoveUp: FnArgus = () => {}) {
  const startPoint = reactive<Position>({
    x: 0.y: 0,})const touchStart = (evt: TouchEvent) = > {
    startPoint.x = evt.targetTouches[0].pageX
    startPoint.y = evt.targetTouches[0].pageY
  }
  const touchMove = (evt: TouchEvent) = > {
    const dis: number = evt.targetTouches[0].pageY - startPoint.y
    if (dis > 0) {
      if (Math.abs(dis) > MIN_DISTANCE) {
        onMoveDown()
      }
    } else if (Math.abs(dis) > MIN_DISTANCE) {
      onMoveUp()
    }
  }

  onMounted(() = > {
    document.addEventListener('touchstart', touchStart, false)
    document.addEventListener('touchmove', touchMove, false)})// Uninstall event
  onBeforeUnmount(() = > {
    document.removeEventListener('touchstart', touchStart, false)
    document.removeEventListener('touchmove', touchMove, false)})}export default useMouseMove
Copy the code

Usage:

// The finger swipe event
import useMouseMove from '~/hooks/useMouseMove'
setup(){
    const onMouseDown = () = >{}const onMouseUp = () = > {
    }
    useMouseMove(onMouseDown, onMouseUp)
}
Copy the code

Provide and Inject

The use of Provide and Inject is not the same as Vuex state management. Vuex managed data is available in all components of the page, but Provide and Inject are hierarchical concepts. Only the parent component provides data, it can Inject data in the child component. If two components do not have a parent or grandparent relationship, Provide is invalid.

Data management functions similar to Vuex can be achieved by using Provide to register data in the top-level component. Cloud.tencent.com/developer/a… Provide and Inject (TypeScript) version of data management is clearly introduced. Since the data used in the project does not need to be managed at the top level, this approach has been modified a bit. As follows:


// src/context/dates.ts
import { provide, inject, computed, Ref } from '@vue/composition-api';
import { DateItem } from '~/components/Calendar/Calendar.ts'

export type DatesContext = {
  dates: Ref<DateItem[]>
  datesList: Ref<DateItem[]>
  setDates: (value: DateItem[]) = > void
  updateDate: (value: DateItem) = > void
}

export const DateSymbol = 'DATE_SYMBOL'

/ / dojo.provide data
export const useDateListProvide = (dates: Ref<DateItem[]>) = >{
  // dates All dates
  // Only the date of the month is displayed
  const datesList = computed(() = > dates.value.filter(item= > item.type === 'current'))
  const setDates = (value: DateItem[]) = > {
    dates.value = value
  }

  const updateDate = (value: DateItem) = > {
    dates.value.every(item= > {
      if (item.date === value.date) {
        item.id = value.id
        item.tagName = value.tagName
        item.selVisible = value.selVisible
        item.popVisible = value.popVisible
        return false
      }
      return true
    })
  }

  provide<DatesContext>(DateSymbol, {
    dates,
    datesList,
    setDates,
    updateDate,
  })  
}

/ / Inject
export const useDateListInject = () = >{
  const dateContext = inject<DatesContext>(DateSymbol);
  if(! dateContext) {throw new Error(`useDateListInject must be used after useDateListProvide`);
  }
  return dateContext;  
}
Copy the code

Record so much first, welcome to leave a message to add.