likes
comments
collection
share

TS+vue3 如何结合打套组合拳

作者站长头像
站长
· 阅读数 33

准备

  • 在vscode 中使用Vue3 +ts 开发,还需要额外安装一个插件 Typescript Vue Plugin

    TS+vue3 如何结合打套组合拳

1defineProps

  1. defineProps配合vue默认语法进行类型校验(运行时声明)

    // 运行时声明
    defineProps({
      money: {
        type: Number,
        required: true
      },
      car: {
        type: String,
        required: true
      }
    })
    
  2. props可以通过解构来指定默认值 (TS+Vue)

    props 提供默认值的方式,提供了 withDefaults 宏命令。

    <script lang="ts" setup>
    // 使用ts的泛型指令props类型
    const { money } =withDefaults( defineProps<{
      money: number,
      car?: string,  //可选值 ,非必传
      msg?: (string | number | boolean),//支持多种类型校验
    }>(),{
      car: '小黄车'
    })
    </script>
    
  3. 注意 如果提供的默认值需要在模板中渲染,需要额外添加配置

    参考链接:vuejs.org/guide/extra…

    // vite.config.js
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'// https://vitejs.dev/config/
    export default defineConfig({
      plugins: [
        vue({
          reactivityTransform: true //给 defineProps 添加支持默认值配置
        })
      ]
    })
    •
    

2 defineEmits

  1. defineEmits配合运行时声明

    const emit = defineEmits(['change', 'update'])
    
  2. defineEmits配合ts 类型声明,可以实现更细粒度的校验

    const emit = defineEmits<{
      // 参数 : 返回值 
      (e: 'changeMoney', money: number): void
      (e: 'changeCar', car: string): void
    }>()
    ​
    emit("handleSelect",1)
    

3 ref

  1. 通过泛型指定 value的值 类型,如果是简单值 ,该值可以省略

    const money = ref<number>(10)
    const money = ref(10)
    
  2. 如果是复杂类型,推荐指定泛型

    type Todo = {
      id: number
      name: string
      done: boolean
    }
    const list = ref<Todo[]>([])
    ​
    setTimeout(() => {
      list.value = [
        { id: 1, name: '吃饭', done: false },
        { id: 2, name: '睡觉', done: true }
      ]
    })
    

4 reactive

  1. reactive 可以根据赋值的内容隐式推断出类型

    //在ts中reactive定义复杂数据类型可以不指定类型
    <script setup>
      import { reactive } from 'vue'
        const obj = reactive({
            name: 'zs',
            age: 18
        })
    </script>
    

5 computed

  1. 通过泛型可以指定computed计算属性的类型,通常可以省略

    const leftCount = computed<number>(() => {
      return list.value.filter((item) => item.done).length
    })
    console.log(leftCount.value)
    

6 事件处理

给元素绑定事件时,通常需要从事件源参数中得到所需的属性

事件源参数类型设置

  • 在绑定事件时添加一个事件源参数:$event

  • 鼠标移入到$event中,就可以看到事件源参数类型了

    const move = (e: MouseEvent) => {
      mouse.value.x = e.pageX
      mouse.value.y = e.pageY
    }
    ​
    <h1 @mousemove="move($event)">根组件</h1>
    

7 Template Refs

目标:掌握ref操作DOM时如何配合Typescript使用

说明

  • ref 操作 dom 时,也需要给 ref 指定类型

如何查看一个DOM对象的类型:通过控制台进行查看

document.createElement('img').__proto__

7.1 方式一

import {ref,onMounted} from 'vue'const imgRef = ref<HTMLImageElement | null>()
​
onMounted(() => {
  console.log(imgRef.value?.src)
})
  
<template>
 <img ref="myRef" src="1.jpg">   
</template>

7.2 方式二

getCurrentInstance 支持访问内部组件实例。

  • 注意:

    • 不要把它当作在组合式 API中获取 this的替代方案来使用

    • 只能setup生命周期钩子中调用。

      • 如需在 setup生命周期钩子外使用,请先在 setup 中调用 getCurrentInstance() 获取该实例然后再使用。
    • 千万不要在getCurrentInstance() 中获取ctx来使用element等东西,这玩意在生成环境下结构就不一样了,会报undefined。可以使用proxy。(我第一次搞vue3就卡在这里2天)

//请先在 setup 中调用 getCurrentInstance() 获取该实例然后再使用。
import { getCurrentInstance,onMounted } from 'vue'
import type {ComponentInternalInstance} from 'vue'
const MyComponent = {
  setup() {
    const internalInstance = getCurrentInstance() as ComponentInternalInstance
    internalInstance.appContext.config.globalProperties // 访问 globalProperties
     const handleClick = () => {
      getCurrentInstance() // 无效
      useComponentId() // 无效
      internalInstance // 有效
    }
    onMounted(() => {
      getCurrentInstance() // 有效
    })
​
  }
}

8. Ts限制函数参数类型

8.1 普通函数

 <script setup lang="ts">
  	function test(params:(string|boolean)):void {
       console.log(params);
   }
   test('5555')
</script>

8.2 箭头函数(推荐)

<script setup lang="ts">
   const test = (params:(string|boolean))=>{
       console.log(params)
   }
   test('5555')
</script>

9. vue3中全局挂载 echarts

9.1 全局挂载

  import { createApp } from 'vue'
  import App from './App.vue'

  import * as echarts from 'echarts'//引入 版本为@5.3.3
  
  const app = createApp(App)

  app.config.globalProperties.$echarts = echarts // 全局挂载echarts
   
  app.mount('#app')

9.2 使用

import {getCurrentInstance} from 'vue'
import type {ComponentInternalInstance} from 'vue'

const { appContext  } = getCurrentInstance() as ComponentInternalInstance // 获取全局配置项

let { $echarts }  =  appContext.config.globalProperties 

接到新项目,需要用 vue3 让我瞅瞅有什么新特性?