基于SqlSugar的开发框架循序渐进介绍(11)– 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

随着Vue3和TypeScript的大浪潮不断袭来,越来越多的Vue项目采用了TypeScript的语法来编写代码,而Vue3的JS中的Setup语法糖也越来越广泛的使用,给我们这些以前用弱类型的JS语法编写Vue代码的人不少冲击,不过随着大量的学习和代码编写,经历过一段难熬的时间后,逐步适应了这种和之前差别不小的写法和冲击。本篇随笔介绍总结了Vue3中一些常见的基于TypeScript的Setup语法与组合式 API的处理代码案例。

TypeScript(简称ts)是微软推出的静态类型的语言,相比于js,TypeScript拥有强类型、编译器严谨的语法检查、更加严苛的语法,TypeScript 是 JS类型的超集,并支持了泛型、类型、命名空间、枚举等特性,弥补了 JS 在大型应用开发中的不足。TypeScript 是 JavaScript 的强类型版本,最终在浏览器中运行的仍然是 JavaScript,所以 TypeScript 并不依赖于浏览器的支持,也并不会带来兼容性问题。

基于TypeScript的Setup语法糖写法越来越多,熟练使用的话,需要一个学习过程,另外ElementPlus控件也有了一些不同的变化,而且它的官方案例代码基本上采用了Setup语法糖的写法来提供例子代码。

<script setup lang="ts">  是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。script-setup 弱化了vue模板式编程体验,也使得代码更简洁。

1、定义组件或者页面名称

由于组合式API的特殊性,组件里面的各项内容可以分开进行定义,同时借助一些辅助函数进行处理。如这里定义组件或者页面名称,通过使用defineOptions进行声明。

<script setup lang="ts"> import { reactive,  ref,  onMounted,  watch,  computed } from "vue";  defineOptions({ name: "MyDictdata" }); //定义组件或页面名称

如果是组件,通过这样定义后,我们在页面引入它的时候,就可以import这个名称就可以了,如下代码所示。

// 自定义字典控件 import MyDictdata from "./src/my-dictdata.vue";

这样我们在页面中就可以和其他HTML标签一样使用这个组件了。

<my-dictdata v-model="editForm.nationality" type-name="民族" />

2、data属性定义

不管是Vue 页面还是组件,我们都需要设置一些属性信息,并提供一些初始化值,以前这些在选项式代码中的时候,是在data块中定义的,采用了<script setup lang="ts">语法后,任何在里面定义的信息,在当前页面或者组件的模板里面都是公开,可以访问的。

我们可以使用ref或者 reactive 来定义不同类型的,ref针对的是简单类型,reactive 针对的是对象类型,它们底层的实现是一样的,ref的参数增加了一个value的属性。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
let expandMore = ref(false); //是否展开更多条件 let list = ref([]); // 页面列表数据 let listSelection = ref([]); // 选中记录 let loading = ref(true); // 加载状态 let sorting = ref(""); // 排序条件  // 分页条件 let pageInfo = reactive({   pageIndex: 1,   pageSize: 20,   totalCount: 0 });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

这些信息可以在HTML页面中直接引用使用即可。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<!--分页部分 --> <div class="block" style="height: 70px"> <el-pagination background :current-page="pageInfo.pageIndex" :page-size="pageInfo.pageSize"   :total="pageInfo.totalCount" :page-sizes="[10, 20, 30, 40]" layout="total, sizes, prev, pager, next,jumper"   @size-change="sizeChange" @current-change="currentChange" /> </div>
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

不过记得,如果是在JS里面引用对象,那么记得加上.value的属性,才能设置或者访问它。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

3、表单或者组件的ref引用

有时候,需要通过在页面的ref=“form” 来引用一些表单或者组件的名称,那么就需要初始化相关的类型的,如下代码所示。

const searchRef = ref<FormInstance>(); //表单引用

而这个需要引入对应的类型的。

import { FormInstance, FormRules } from "element-plus";

这样我们在HTML模板中就可以使用它的名称了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

而对于自定义组件的话,如果需要严谨类型的处理,一般也需要约束对应的类型,我们如果需要反射某个特定组件的类型,那么也可以使用InstanceType的关键字来处理,如下代码所示。

<script lang="ts" setup> import { ref } from 'vue' import { ElTree } from 'element-plus'  const treeRef = ref<InstanceType<typeof ElTree>>()

这样在调用相关接口方法的时候,就有Typescript的只能提示,代码更加健壮了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

通过InstanceType这样方式获得的ref引用,会显示组件很多公开的属性和接口方法,如下图所示。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

 

我们也可以单独定义一个类型,用来约束自定义组件的方法或者属性,如下我们定义一个视图类型组件,只有一个show方法。

我们在<script setup lang="ts">的顶部export一个接口定义,然后再在下面使用 defineExpose 暴露组件属性和方法,这样就可以在组件的引用的地方调用这些方法了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts"> //组件的接口类型 export interface ExposeViewType {   show(id?: string | number): Function; }  //显示窗口 const show = (id: string | number) => {   if (!isNullOrUnDef(id)) {     testuser.Get(id).then(data => {       Object.assign(viewForm, data);        isVisible.value = true; //显示对话框     });   } };  //暴露组件属性和方法 defineExpose({   show });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

这样我们在页面中定义这个自定义组件的引用的时候,除了使用InstanceType之外,还可以使用自定义的类型声明了。

    <!--查看详细组件界面-->     <view-data ref="viewRef" />

在<script setup lang="ts">里面定义对应引用的类型。

const viewRef = ref<ExposeViewType | null>(); //查看表单引用

这样我们就可以在代码中查看它的对外公布的方法信息了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

  

4、组件prop属性定义

在我们开发自定义组件的时候,我们往往需要定义很多父传子的属性,也叫作prop属性定义。

prop属性定义,是通过defineProps函数进行处理的,这个defineProps()宏函数支持从它的参数中推导类型,定义的代码如下所示。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts"> const props = defineProps<{     foo: string     bar?: number }>() </script>
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 我们也可以将 prop 的类型移入一个单独的接口中:

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts"> interface Props {   foo: string   bar?: number }  const props = defineProps<Props>() </script>
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

有时候,我们还需要给指定的prop属性给定默认值,那么也可以通过函数withDefaults一起进行处理即可。

如下面是我们指定模块定义的prop接口信息和defineProps的处理代码。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts"> import {  reactive,  ref,  onMounted,  watch,  computed} from   vue";  //定义组件名称 defineOptions({ name: "MyDictdata" });  //声明Props的接口类型 interface Props {   placeholder?: string; // 空白提示   typeName?: string; // 字典类型方式,从后端字典接口获取数据   options?: Array<TreeNodeItem>; // 固定列表方式,直接绑定,项目包括id,label属性   modelvalue?: string | number; // 接受外部v-model传入的值   clearable?: boolean; // 是否可以清空   disabled?: boolean; // 是否禁用   multiple?: boolean; // 是否多选 }  //使用默认值定义Props const props = withDefaults(defineProps<Props>(), {   placeholder: "请选择",   typeName: "",   options: () => {     return [];   },   clearable: true,   disabled: false,   multiple: false,    modelValue: "" //对应自定义控件的v-model的值 });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

这样我们在使用的时候,就可以传入给组件对应的prop名称了。

  <el-form-item label="民族" prop="nationality">     <my-dictdata v-model="editForm.nationality" type-name="民族" />   </el-form-item>

 

5、Emits事件声明

在组件里面,我们抛出事件,通过在Emits中进行声明,再行使用。

声明事件在setup语法里面也是和其他宏函数一样,如下代码所示。

  // 声明事件   const emit = defineEmits(['updateName'])

如果为了更强的指定事件的参数和返回值等信息,我们也可以通过定义接口然后在声明Emits的方式,如下代码所示。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
//声明控件事件 interface Emits {   (e: "update:modelValue", value: string): void;   (e: "change", value: string): void; } //定义控件事件 const emit = defineEmits<Emits>();
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

或者直接整合一起声明。

// 基于类型的声明 const emit = defineEmits<{   (e: 'change', id: number): void   (e: 'update', value: string): void }>()

然后在组件的函数中触发事件,通知父页面即可。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
function change(data) {   const obj = dictItems.value.find(item => {     return item.id + "" === data;   });   emit("change", obj); }
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

这样我们在页面使用组件的时候,HTML模板中使用的组件代码里面,可以获得获得对应的事件处理。

  <el-form-item label="状态" prop="state">     <my-dictdata v-model="searchForm.state" :options="Status" @change="change" />   </el-form-item>

 

6、Computed计算函数的使用

「computed」 是Vue中提供的一个计算属性。它被混入到Vue实例中,所有的getter和setter的this上下文自动的绑定为Vue实例。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts">   import { computed, ref } from 'vue'    const count = ref(1)    // 通过computed获得doubleCount   const doubleCount = computed(() => {     return count.value * 2   })   // 获取   console.log(doubleCount.value) </script>
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

7、Watch函数的使用

有时候,子组件需要监控自身某个值的变化,然后进行相关的处理,那么对值进行监控就需要用到了watch函数。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
// 监听外部对props属性变更,如通过ResetFields()方法重置值的时候 watch(   () => props.modelValue,   newValue => {     console.log(newValue);     emit("update:modelValue", newValue + "");   } );  watch(   () => props.options,   newValue => {     newValue.forEach(item => {       dictItems.value.push(item);     });   } );
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

8、onMounted函数的使用

我们一般在 onMounted 的逻辑里面准备好组件或者页面显示的内容,这里面在页面组件准备妥当后进行更新显示。

//页面初始化加载 onMounted(() => {   getlist(); });

或者组件里面

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
//挂载的时候初始化数据 onMounted(async () => {   var typeName = props.typeName;   var options = props.options;   if (typeName && typeName !== "") {     // 使用字典类型,从服务器请求数据     await dictdata.GetTreeItemByDictType(typeName).then(list => {       if (list) {         list.forEach(item => {           dictItems.value.push({ id: item.id, label: item.label });         });       }     });   } else if (options && options.length > 0) {     // 使用固定字典列表     options.map(item => {       dictItems.value.push({ id: item.id, label: item.label });     });   }    // 设置默认值   keyword.value = props.modelValue; });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

9、自定义组件的ModelValue

一般组件在绑定值的时候,一般使用v-Model的属性来设置它的值。

  <el-form-item label="姓名" prop="name">     <el-input v-model="editForm.name" />   </el-form-item>

或者日期组件

  <el-form-item label="出生日期" prop="birthDate">     <el-date-picker v-model="editForm.birthDate" align="right" type="date" placeholder="选择日期"       format="YYYY-MM-DD" />   </el-form-item>

因此我们自定义开发的组件,也应该采用这样约定的属性。这里面的v-Model对应的prop属性就是modelValue的,因此我们需要定义这个属性,并处理Emits事件就可以了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
//声明Props的接口类型 interface Props {   modelvalue?: string | number; // 接受外部v-model传入的值 } //使用默认值定义Props const props = withDefaults(defineProps<Props>(), {   modelValue: "" //对应自定义控件的v-model的值 });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

然后声明组件的事件,在组件内部合适的地方触发即可。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
//声明组件事件 interface Emits {   (e: "update:modelValue", value: string): void;   (e: "change", value: string): void; } //定义组件事件 const emit = defineEmits<Emits>();
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

并在Watch监控它的变化,触发组件的自定义事件

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
watch(   () => props.modelValue,   newValue => {     console.log(newValue);     emit("update:modelValue", newValue + "");   } );
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

10、自定义引入Vue的API和组件

上面所有的setup语法糖代码里面,我们在开始的时候,往往都需要引入ref,reactive等API,如下代码所示。

<script setup lang="ts"> import { reactive,  ref,  onMounted,  watch,  computed } from "vue";

那么每次引入局的麻烦的话,可以通过使用https://github.com/antfu/unplugin-auto-import 这个插件来实现自动引入这些配置信息,这样每次就可以省却一些定义代码了。

这样在使用ref,reactive的时候,不用引入就直接使用,如下代码所示。

const count = ref(0) const doubled = computed(() => count.value * 2)

安装组件,直接通过下面npm 或者pnmp进行安装即可。

npm i -D unplugin-auto-import

它提供了Vite、WebPack等编译器的集成,可以参考官网进行修改。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

如Vite的配置处理如下所示。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
// vite.config.ts import AutoImport from 'unplugin-auto-import/vite'  export default defineConfig({   plugins: [     AutoImport({ /* options */ }),   ], })
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

然后对Typescript和ESLint进行修改配置一下就可以一劳永逸了(具体参考官网的说明),希望下个版本的vue能自动不用引入这些API就好了。

以上就是我们在<script setup lang="ts">语法中经常涉及到的一些常用的知识和代码案例了。

 

系列文章:

基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用

基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理

基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发

基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理 

基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转

基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口 

基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传

 《基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录

基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制

基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理

基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用

基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用

 《基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成

基于SqlSugar的开发框架循序渐进介绍(16)-- 工作流模块的功能介绍

基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理

 《基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结 专注于代码生成工具、.Net/.NetCore 框架架构及软件开发,以及各种Vue.js的前端技术应用。著有Winform开发框架/混合式开发框架、微信开发框架、Bootstrap开发框架、ABP开发框架、SqlSugar开发框架等框架产品。 

随着Vue3和TypeScript的大浪潮不断袭来,越来越多的Vue项目采用了TypeScript的语法来编写代码,而Vue3的JS中的Setup语法糖也越来越广泛的使用,给我们这些以前用弱类型的JS语法编写Vue代码的人不少冲击,不过随着大量的学习和代码编写,经历过一段难熬的时间后,逐步适应了这种和之前差别不小的写法和冲击。本篇随笔介绍总结了Vue3中一些常见的基于TypeScript的Setup语法与组合式 API的处理代码案例。

TypeScript(简称ts)是微软推出的静态类型的语言,相比于js,TypeScript拥有强类型、编译器严谨的语法检查、更加严苛的语法,TypeScript 是 JS类型的超集,并支持了泛型、类型、命名空间、枚举等特性,弥补了 JS 在大型应用开发中的不足。TypeScript 是 JavaScript 的强类型版本,最终在浏览器中运行的仍然是 JavaScript,所以 TypeScript 并不依赖于浏览器的支持,也并不会带来兼容性问题。

基于TypeScript的Setup语法糖写法越来越多,熟练使用的话,需要一个学习过程,另外ElementPlus控件也有了一些不同的变化,而且它的官方案例代码基本上采用了Setup语法糖的写法来提供例子代码。

<script setup lang="ts">  是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。script-setup 弱化了vue模板式编程体验,也使得代码更简洁。

1、定义组件或者页面名称

由于组合式API的特殊性,组件里面的各项内容可以分开进行定义,同时借助一些辅助函数进行处理。如这里定义组件或者页面名称,通过使用defineOptions进行声明。

<script setup lang="ts"> import { reactive,  ref,  onMounted,  watch,  computed } from "vue";  defineOptions({ name: "MyDictdata" }); //定义组件或页面名称

如果是组件,通过这样定义后,我们在页面引入它的时候,就可以import这个名称就可以了,如下代码所示。

// 自定义字典控件 import MyDictdata from "./src/my-dictdata.vue";

这样我们在页面中就可以和其他HTML标签一样使用这个组件了。

<my-dictdata v-model="editForm.nationality" type-name="民族" />

2、data属性定义

不管是Vue 页面还是组件,我们都需要设置一些属性信息,并提供一些初始化值,以前这些在选项式代码中的时候,是在data块中定义的,采用了<script setup lang="ts">语法后,任何在里面定义的信息,在当前页面或者组件的模板里面都是公开,可以访问的。

我们可以使用ref或者 reactive 来定义不同类型的,ref针对的是简单类型,reactive 针对的是对象类型,它们底层的实现是一样的,ref的参数增加了一个value的属性。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
let expandMore = ref(false); //是否展开更多条件 let list = ref([]); // 页面列表数据 let listSelection = ref([]); // 选中记录 let loading = ref(true); // 加载状态 let sorting = ref(""); // 排序条件  // 分页条件 let pageInfo = reactive({   pageIndex: 1,   pageSize: 20,   totalCount: 0 });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

这些信息可以在HTML页面中直接引用使用即可。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<!--分页部分 --> <div class="block" style="height: 70px"> <el-pagination background :current-page="pageInfo.pageIndex" :page-size="pageInfo.pageSize"   :total="pageInfo.totalCount" :page-sizes="[10, 20, 30, 40]" layout="total, sizes, prev, pager, next,jumper"   @size-change="sizeChange" @current-change="currentChange" /> </div>
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

不过记得,如果是在JS里面引用对象,那么记得加上.value的属性,才能设置或者访问它。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

3、表单或者组件的ref引用

有时候,需要通过在页面的ref=“form” 来引用一些表单或者组件的名称,那么就需要初始化相关的类型的,如下代码所示。

const searchRef = ref<FormInstance>(); //表单引用

而这个需要引入对应的类型的。

import { FormInstance, FormRules } from "element-plus";

这样我们在HTML模板中就可以使用它的名称了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

而对于自定义组件的话,如果需要严谨类型的处理,一般也需要约束对应的类型,我们如果需要反射某个特定组件的类型,那么也可以使用InstanceType的关键字来处理,如下代码所示。

<script lang="ts" setup> import { ref } from 'vue' import { ElTree } from 'element-plus'  const treeRef = ref<InstanceType<typeof ElTree>>()

这样在调用相关接口方法的时候,就有Typescript的只能提示,代码更加健壮了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

通过InstanceType这样方式获得的ref引用,会显示组件很多公开的属性和接口方法,如下图所示。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

 

我们也可以单独定义一个类型,用来约束自定义组件的方法或者属性,如下我们定义一个视图类型组件,只有一个show方法。

我们在<script setup lang="ts">的顶部export一个接口定义,然后再在下面使用 defineExpose 暴露组件属性和方法,这样就可以在组件的引用的地方调用这些方法了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts"> //组件的接口类型 export interface ExposeViewType {   show(id?: string | number): Function; }  //显示窗口 const show = (id: string | number) => {   if (!isNullOrUnDef(id)) {     testuser.Get(id).then(data => {       Object.assign(viewForm, data);        isVisible.value = true; //显示对话框     });   } };  //暴露组件属性和方法 defineExpose({   show });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

这样我们在页面中定义这个自定义组件的引用的时候,除了使用InstanceType之外,还可以使用自定义的类型声明了。

    <!--查看详细组件界面-->     <view-data ref="viewRef" />

在<script setup lang="ts">里面定义对应引用的类型。

const viewRef = ref<ExposeViewType | null>(); //查看表单引用

这样我们就可以在代码中查看它的对外公布的方法信息了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

  

4、组件prop属性定义

在我们开发自定义组件的时候,我们往往需要定义很多父传子的属性,也叫作prop属性定义。

prop属性定义,是通过defineProps函数进行处理的,这个defineProps()宏函数支持从它的参数中推导类型,定义的代码如下所示。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts"> const props = defineProps<{     foo: string     bar?: number }>() </script>
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 我们也可以将 prop 的类型移入一个单独的接口中:

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts"> interface Props {   foo: string   bar?: number }  const props = defineProps<Props>() </script>
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

有时候,我们还需要给指定的prop属性给定默认值,那么也可以通过函数withDefaults一起进行处理即可。

如下面是我们指定模块定义的prop接口信息和defineProps的处理代码。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts"> import {  reactive,  ref,  onMounted,  watch,  computed} from   vue";  //定义组件名称 defineOptions({ name: "MyDictdata" });  //声明Props的接口类型 interface Props {   placeholder?: string; // 空白提示   typeName?: string; // 字典类型方式,从后端字典接口获取数据   options?: Array<TreeNodeItem>; // 固定列表方式,直接绑定,项目包括id,label属性   modelvalue?: string | number; // 接受外部v-model传入的值   clearable?: boolean; // 是否可以清空   disabled?: boolean; // 是否禁用   multiple?: boolean; // 是否多选 }  //使用默认值定义Props const props = withDefaults(defineProps<Props>(), {   placeholder: "请选择",   typeName: "",   options: () => {     return [];   },   clearable: true,   disabled: false,   multiple: false,    modelValue: "" //对应自定义控件的v-model的值 });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

这样我们在使用的时候,就可以传入给组件对应的prop名称了。

  <el-form-item label="民族" prop="nationality">     <my-dictdata v-model="editForm.nationality" type-name="民族" />   </el-form-item>

 

5、Emits事件声明

在组件里面,我们抛出事件,通过在Emits中进行声明,再行使用。

声明事件在setup语法里面也是和其他宏函数一样,如下代码所示。

  // 声明事件   const emit = defineEmits(['updateName'])

如果为了更强的指定事件的参数和返回值等信息,我们也可以通过定义接口然后在声明Emits的方式,如下代码所示。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
//声明控件事件 interface Emits {   (e: "update:modelValue", value: string): void;   (e: "change", value: string): void; } //定义控件事件 const emit = defineEmits<Emits>();
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

或者直接整合一起声明。

// 基于类型的声明 const emit = defineEmits<{   (e: 'change', id: number): void   (e: 'update', value: string): void }>()

然后在组件的函数中触发事件,通知父页面即可。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
function change(data) {   const obj = dictItems.value.find(item => {     return item.id + "" === data;   });   emit("change", obj); }
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

这样我们在页面使用组件的时候,HTML模板中使用的组件代码里面,可以获得获得对应的事件处理。

  <el-form-item label="状态" prop="state">     <my-dictdata v-model="searchForm.state" :options="Status" @change="change" />   </el-form-item>

 

6、Computed计算函数的使用

「computed」 是Vue中提供的一个计算属性。它被混入到Vue实例中,所有的getter和setter的this上下文自动的绑定为Vue实例。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
<script setup lang="ts">   import { computed, ref } from 'vue'    const count = ref(1)    // 通过computed获得doubleCount   const doubleCount = computed(() => {     return count.value * 2   })   // 获取   console.log(doubleCount.value) </script>
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

7、Watch函数的使用

有时候,子组件需要监控自身某个值的变化,然后进行相关的处理,那么对值进行监控就需要用到了watch函数。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
// 监听外部对props属性变更,如通过ResetFields()方法重置值的时候 watch(   () => props.modelValue,   newValue => {     console.log(newValue);     emit("update:modelValue", newValue + "");   } );  watch(   () => props.options,   newValue => {     newValue.forEach(item => {       dictItems.value.push(item);     });   } );
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

8、onMounted函数的使用

我们一般在 onMounted 的逻辑里面准备好组件或者页面显示的内容,这里面在页面组件准备妥当后进行更新显示。

//页面初始化加载 onMounted(() => {   getlist(); });

或者组件里面

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
//挂载的时候初始化数据 onMounted(async () => {   var typeName = props.typeName;   var options = props.options;   if (typeName && typeName !== "") {     // 使用字典类型,从服务器请求数据     await dictdata.GetTreeItemByDictType(typeName).then(list => {       if (list) {         list.forEach(item => {           dictItems.value.push({ id: item.id, label: item.label });         });       }     });   } else if (options && options.length > 0) {     // 使用固定字典列表     options.map(item => {       dictItems.value.push({ id: item.id, label: item.label });     });   }    // 设置默认值   keyword.value = props.modelValue; });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

9、自定义组件的ModelValue

一般组件在绑定值的时候,一般使用v-Model的属性来设置它的值。

  <el-form-item label="姓名" prop="name">     <el-input v-model="editForm.name" />   </el-form-item>

或者日期组件

  <el-form-item label="出生日期" prop="birthDate">     <el-date-picker v-model="editForm.birthDate" align="right" type="date" placeholder="选择日期"       format="YYYY-MM-DD" />   </el-form-item>

因此我们自定义开发的组件,也应该采用这样约定的属性。这里面的v-Model对应的prop属性就是modelValue的,因此我们需要定义这个属性,并处理Emits事件就可以了。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
//声明Props的接口类型 interface Props {   modelvalue?: string | number; // 接受外部v-model传入的值 } //使用默认值定义Props const props = withDefaults(defineProps<Props>(), {   modelValue: "" //对应自定义控件的v-model的值 });
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

然后声明组件的事件,在组件内部合适的地方触发即可。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
//声明组件事件 interface Emits {   (e: "update:modelValue", value: string): void;   (e: "change", value: string): void; } //定义组件事件 const emit = defineEmits<Emits>();
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

并在Watch监控它的变化,触发组件的自定义事件

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
watch(   () => props.modelValue,   newValue => {     console.log(newValue);     emit("update:modelValue", newValue + "");   } );
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

 

10、自定义引入Vue的API和组件

上面所有的setup语法糖代码里面,我们在开始的时候,往往都需要引入ref,reactive等API,如下代码所示。

<script setup lang="ts"> import { reactive,  ref,  onMounted,  watch,  computed } from "vue";

那么每次引入局的麻烦的话,可以通过使用https://github.com/antfu/unplugin-auto-import 这个插件来实现自动引入这些配置信息,这样每次就可以省却一些定义代码了。

这样在使用ref,reactive的时候,不用引入就直接使用,如下代码所示。

const count = ref(0) const doubled = computed(() => count.value * 2)

安装组件,直接通过下面npm 或者pnmp进行安装即可。

npm i -D unplugin-auto-import

它提供了Vite、WebPack等编译器的集成,可以参考官网进行修改。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

如Vite的配置处理如下所示。

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
// vite.config.ts import AutoImport from 'unplugin-auto-import/vite'  export default defineConfig({   plugins: [     AutoImport({ /* options */ }),   ], })
基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

然后对Typescript和ESLint进行修改配置一下就可以一劳永逸了(具体参考官网的说明),希望下个版本的vue能自动不用引入这些API就好了。

以上就是我们在<script setup lang="ts">语法中经常涉及到的一些常用的知识和代码案例了。

 

系列文章:

基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用

基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理

基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发

基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理 

基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转

基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口 

基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传

 《基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录

基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制

基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理

基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用

基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用

 《基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成

基于SqlSugar的开发框架循序渐进介绍(16)-- 工作流模块的功能介绍

基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理

 《基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面

举报
发表评论

评论已关闭。

相关文章

当前内容话题
  • 0