• Vue3最佳实践 第七章 TypeScript 中


    Vue组件中TypeScript

      在Vue组件中,我们可以使用TypeScript进行各种类型的设置,包括props、Reactive和ref等。下面,让我们详细地探讨一下这些设置。

    设置描述
    设置props在Vue中,props本身就具有类型设定的功能。但如果你希望使用TypeScript的方式来设定类型,你可以使用PropType函数。在使用PropType时,你可以在defineProps函数中使用PropType的泛型来设定参数的类型。
    Reactive中的设置Reactive是Vue3的新特性,它允许我们创建一个反应性对象。我们可以使用TypeScript来设定Reactive对象的类型。通过设定类型,我们可以确保Reactive对象的属性和值都符合我们的预期。
    ref中的设置ref是Vue的一个重要特性,它使我们能够访问和修改组件中的响应式数据。在TypeScript中,我们可以使用Ref接口来设定ref的类型。这样,无论我们何时访问或修改ref,TypeScript都会确保我们的操作符合设定的类型。
    反应属性与props在Vue中,我们可以使用props和反应属性(如Reactive和ref)来管理组件的状态。使用TypeScript可以帮助我们更好地管理这些状态,因为它提供了强大的类型检查和自动补全功能,使我们能够在编写代码时就发现并修复错误。

    第一章 Vue3项目创建 1 Vue CLI 创建vue项目
    第一章 Vue3项目创建 2 使用 Webpack 5 搭建 vue项目
    第一章 Vue3项目创建 3 Vite 创建 vue项目
    第二章 Vue3 基础语法指令
    第三章 Vue Router路由器的使用
    第四章 VUE常用 UI 库 1 ( element-plus,Ant ,naiveui,ArcoDesign)
    第四章 VUE常用 UI 库 2 ( ailwind 后台框架)
    第五章 Vue 组件应用 1( Props )
    第五章 Vue 组件应用 2 ( Emit )
    第五章 Vue 组件应用 3( Slots )
    第五章 Vue 组件应用 4 ( provide 和 inject )
    第五章 Vue 组件应用 5 (Vue 插件)
    第六章 Pinia,Vuex与axios,VueUse 1(Pinia)
    第六章 Pinia,Vuex与axios,VueUse 2(Vuex)
    第六章 Pinia,Vuex与axios,VueUse 3(VueUse)
    第六章 Pinia,Vuex与axios,VueUse 4(axios)
    第七章 TypeScript 上
    第七章 TypeScript 中
    第七章 TypeScript 下 创建Trello 任务管理器
    第八章 ESLint 与 测试 ( ESLint )
    第八章 ESLint 与 测试 ( Jest )
    第八章 ESLint 与 测试 (TypeScript 中Jest与检测环境集成)

    1props设置

      现在我们已经确定了如何设置数据属性对象,让我们检查如何设置道具的类型。关于props,Vue本身也有设置props类型的功能。首先检查使用Vue的props中的type设置方法的操作。

    <script setup lang="ts">
    import he from './components/HelloWorld.vue';
    script>
    <template>
    <he msg="true"/>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

      HelloWorld.vue文件中defineProps获得父组件中传递属性msg设置,这是里没有使用到TypeScript语法来设置props属性类型。

    <script setup lang="ts">
    var def=defineProps({
      msg:{
          type: String
        }
    });
    script>
    <template>
      <h1>{{ def.msg }}h1>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1 props中属性设置

      如果想使用 TypeScript 设置props的类型而不是 Vue.js 的方式来设置类型,需要使用到PropType 函数,在组件中导入 PropType并且在defineProps函数中使用 PropType 的泛型来设置参数的类型。

    <script setup lang="ts">
    import { ref,PropType } from 'vue'
    var def=defineProps({
      msg:{
          type: String as PropType<string>,
        }
    });
    script>
    <template>
      <h1>{{ def }}h1>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

      让我们来修改一下HelloWorld.vue文件中props的msg属性类型,将msg类型改成number数值类型。这个时候会发现App.vue中的代码内容

    <script setup lang="ts">
    import { ref,PropType } from 'vue'
    var def=defineProps({
      msg:{
          type: Number as PropType<number>,
        }
    });
    script>
    <template>
      <h1>{{ def }}h1>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这个时候会发现App.vue中的代码中msg参数部分在编辑器中有错误提示信息

    <script setup lang="ts">
    import he from './components/HelloWorld.vue';
    script>
    <template>
    <he msg="2234.33"/>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

      提示的内容是你在HelloWorld子组件中meg参数的类型是数字类型,而你现在组件中meg获得的值是字符串类型。

    在这里插入图片描述

    这说明TypeScript 设置props的类型生效了,App.vue代码应用了TypeScript语法规则。我们将msg改成:msg这种直接获得参数方法来获得数字。这样编辑器不在出现错误提示。

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2 props中对象设置
      如果 Props 的参数是 Object 而不是普通的String 或 Number等属性类型 ,需要使用接口来设置对象的类型。在HelloWorld.vue 中创建一个User接口,它有3个属性name,dept,userid,分别为这3个属性设置PropType 类型。在defineProps函数中设置一个对象参数user,它为参数类型是接口User类型。我们在父组件中设置来传入这个User类型的参数对象。

    <script setup lang="ts">
    import { ref,PropType } from 'vue'
    interface User {
      name: string;
      dept: string;
      userid: number;
    }
    var def=defineProps({
        user:{
          type: Object as PropType<User>,
        }
    });
    script>
    <template>
      <h1>{{ user }}h1>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

      在App.vue父组件中,我们定义User接口,接口内容与HelloWorld.vue中的User接口一致。在创建一个User类型的对象user,为对象中属性name,dept,userid赋值。在通过组件中的props 将参数user传递到HelloWorld.vue组件中。

    <script setup lang="ts">
    import he from './components/HelloWorld.vue';
    interface User {
      name: string;
      dept: string;
      userid: number;
    }
    const user:User={name:'zhtbs',dept:'部门一',userid:1};
    script>
    <template>
    <he :user="user"/>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    浏览器中看到HelloWorld.vue接收到App.vue组件中user对象的内容了。
    在这里插入图片描述

      我们在App.vue代码中user对象中新增一个deptid属性和它的值,这个时候会看到编辑器提示错误。

    <script setup lang="ts">
    import he from './components/HelloWorld.vue';
    interface User {
      name: string;
      dept: string;
      userid: number;
    }
    const user:User={name:'zhtbs',dept:'部门一',userid:1,deptid:112};
    script>
    <template>
    <he :user="user"/>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

      这个错误是App.vue组件中的传的参数对象user的值,在HelloWorld.vue的props中没有对应的类型。原因是App.vue组件的user对象中多了一个deptid参数导致的类型不对。

    在这里插入图片描述

      这个错误说明了父组件参数的对象类型与子组件参数类型必须是一致的,TypeScript 在编辑中会验证它们的一致性。

    3 导出接口

      在上边实例中定义的接口类型,分别在子组件和父组件都要定义,接口类型User被创建了两次。为了解决这个样的问题,将接口类型定义在一个公共的TS文件中,需要使用到它的vue文件直接引入这个TS文件中的接口类型。在pojo文件夹下面创建User.ts文件,在文件中写入下面代码描述。

    export interface User {
        name: string;
        dept: string;
        userid: number;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

      在App.vue与HelloWorld.vue文件中直接引入User文件获得接口User类型,这样父子组将之间就可以共享统一接口类型。App.vue中代码更改内容。

    <script setup lang="ts">
    import he from './components/HelloWorld.vue';
    import {User} from './pojo/User'
    const user:User={name:'zhtbs',dept:'部门一',userid:1};
    script>
    <template>
    <he :user="user"/>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    HelloWorld.vue中代码更改内容。

    <script setup lang="ts">
    import { ref,PropType } from 'vue'
    import {User} from '../pojo/User'
    var def=defineProps({
        user:{
          type: Object as PropType<User>,
        }
    });
    script>
    <template>
      <h1>{{ user }}h1>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

      使用指定对象类型的时候,对象初始化中的属性与值必须与接口中的类型一致。但是使用as类型断言设置对象类型时候,对象中的值可以与接口中的值不一致。

    <script setup lang="ts">
    import he from './components/HelloWorld.vue';
    import {User} from './pojo/User'
     //使用as 断言 User接口类型的时候,对象初始中的值可以增加deptid属性
    const user={name:'zhtbs',dept:'部门一',userid:1,deptid:112} as User;
    script>
    <template>
    <he :user="user"/>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

      这是一个使用 Vue 的选项 API 时在 Vue3 环境中设置 TypeScript 的示例,但是您可以检查如何将 TypeScript 与数据、道具、计算、方法一起使用,这些都是构建 Vue 应用程序的基本要素。我做到了。

    2 Reactive 中的设置

      到目前为止,我们已经使用 Options API 来检查如何配置 TypeScript。您可以使用 Vue3 中的 Composition API 编写代码。从这里开始,我将解释如何在使用 Composition API 时设置 TypeScript。我认为有些人对 Composition API 还不熟悉,所以我在各个地方都包含了 Composition API 的解释。

      使用类型推断判断Reactive 中的参数类型,如果没有给reactive函数属性类型,TypeScript代码将通过属性中的初始化的值进行类型推断来确定参数中的值类型。

    <script setup lang="ts">
    import { reactive } from 'vue';
    import {User} from './pojo/User'
    const state = reactive({
          msg: 'Hello TypeScript' as string,
          user:{name:'zhtbs',dept:'部门一',userid:1,deptid:112} as User
    });
    </script>
    <template>
        <h1> {{ state.msg }}</h1>
        <h2> {{ state.user }}</h2>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    使用类型直接定义Reactive 中的参数类型。

    <script setup lang="ts">
    import { reactive } from 'vue';
    import {User} from './pojo/User'
    let u:User={name:'zhtbs',dept:'部门一',userid:1}
    const state = reactive<{ msg: string ,u1:User}>({
          msg: 'Hello TypeScript' as string,
          u1: u
        });
    </script>
    <template>
        <h1> {{ state.msg }}</h1>
        <h2> {{ state.u1 }}</h2>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    使用接口设置直接定义Reactive 中的参数类型。

    <script setup lang="ts">
    import { reactive } from 'vue';
    import {User} from './pojo/User'
    let u:User={name:'zhtbs',dept:'部门一',userid:1}
     //接口类型设置
    interface State {
      msg: string;
      u1:User;
    }
    const state = reactive<State>({
          msg: 'Hello TypeScript' as string,
          u1: u
        });
    </script>
    <template>
        <h1> {{ state.msg }}</h1>
        <h2> {{ state.u1 }}</h2>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3 ref 中的设置

      ref中设置TypeScript属性与前面的Reactive 函数一样,可以使用类型推断的方式进行初始值设置,通过初始值得类型来设置ref参数类型。代码中导入ref 函数,使用ref函数设置msg属性值与user属性对象值,TypeScript的语法将会自动推断出属性值得类型。

    <script setup lang="ts">
    import { ref  } from 'vue';
    const msg = ref('Hello TypeScript');
    const user=ref({name:'zhtbs',dept:'部门一',userid:1});
    </script>
    <template>
        <h1> {{ msg}}</h1>
        <h2> {{ user }}</h2>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    最标准的在ref 函数中设置类型的方是,使用泛型设置类型。泛型设置是在ref函数的后边加上< > 括号,在括号中定义属性的类型。

    <script setup lang="ts">
    import { ref  } from 'vue';
    import {User} from './pojo/User'
    const msg = ref<string>('Hello TypeScript');
    const user=ref<User>({name:'zhtbs',dept:'部门一',userid:1});
    </script>
    <template>
        <h1> {{ msg}}</h1>
        <h2> {{ user }}</h2>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    泛型中的类型数组设置,通过泛型数组设置可以设置参数数组内容。

    <script setup lang="ts">
    import { ref  } from 'vue';
    import {User} from './pojo/User'
    const msg = ref('Hello TypeScript');
    const user=ref<User>({name:'zhtbs',dept:'部门一',userid:1});
    const users=ref<User[]>([
     {name:'zhtbs',dept:'部门一',userid:1},
     {name:'kimy',dept:'部门二',userid:2}
    ]);
    </script>
    <template>
        <h1> {{ msg}}</h1>
        <h2> {{ user }}</h2>
        <h2> {{ users }}</h2>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    浏览器中看到以下内容。

    在这里插入图片描述

    4 反应属性与props

    在TypeScript 语法中,反应属性与props参数传值的联合使用

    <script setup lang="ts">
    import { ref  } from 'vue';
    import {User} from './pojo/User'
    import he from './components/HelloWorld.vue'
    const msg = ref('Hello TypeScript');
    const user=ref<User>({name:'zhtbs',dept:'部门一',userid:1});
    </script>
    <template>
    <he :user="user" />
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    <script setup lang="ts">
    import { ref,PropType } from 'vue'
    import {User} from '../pojo/User'
    var def=defineProps({
        user:{
          type: Object as PropType<User>,
        }
    });
    const u1=def.user as User;
    </script>
    <template>
     <h2>{{user}}</h2>
     <input v-model="u1.name"  />
     <input v-model="u1.dept"  />
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    在这个示例中,我们使用了反应属性ref和props参数来管理组件的状态。具体来说:

    • 在第一个代码块中,我们使用了ref来创建一个反应性对象msg和user,并将user作为props传递给了he组件。
    • 在第二个代码块中,我们使用了defineProps函数来定义了一个props对象def,并指定了user属性的类型为User。
  • 相关阅读:
    Spring中的设计模式
    AI赋能药物研发的偶然与必然
    如何在Spring Boot应用中进行文件预览?
    class.forName() 里面都发生了啥?一文搞懂 Spi 机制
    WPF Binding对象、数据校验、数据转换
    常用函数式接口:Consumer、Predicate、Function的方法说明解练习
    css新特性?
    用Python开发QQ机器人详解
    【Python高级编程】Python中Excel表格处理数据
    数据结构-快速排序“人红是非多”?看我见招拆招
  • 原文地址:https://blog.csdn.net/zhtbs/article/details/133632192