TS学习(三):与 Vue3 结合使用

简介: TS学习(三):与 Vue3 结合使用

1. TS在工程项目中的模块使用及配置

1.1 声明文件

  1. 什么是声明文件?

    声明文件就是给 js 代码补充类型标注. 这样在 ts 编译环境下就不会提示 js 文件"缺少类型".

    声明变量使用关键字 declare 来表示声明其后面的全局变量的类型, 比如:

    // packages/global.d.ts
    declare var __DEV__: boolean
    declare var __TEST__: boolean
    declare var __BROWSER__: boolean
    declare var __RUNTIME_COMPILE__: boolean
    declare var __COMMIT__: string
    declare var __VERSION__: string

    上面代码表示 __DEV__ 等变量是全局, 并且标注了他们的类型. 这样无论在项目中的哪个 ts 文件中使用 __DEV__, 变量 ts 编译器都会知道他是 boolean 类型.

  2. 声明文件在哪里?

    声明文件的文件名是有规范要求的, 必须以 .d.ts 结尾。声明文件放在项目里的任意路径/文件名都可以被 ts 编译器识别, 但实际开发中发现, 为了规避一些奇怪的问题, 推荐放在根目录下.

  3. 声明文件对纯js项目有什么帮助?

    即便你只写 js 代码, 也可以安装声明文件, 因为如果你用的是 vscode , 那么他会自动分析 js 代码, 如果存在对应的声明文件, vscode 会把声明文件的内容作为代码提示。

1.2. @types和DefinitelyTyped仓库

DefinitelyTyped 是一个高质量的 TypeScript 类型定义的仓库。通过 @types 方式来安装常见的第三方JavaScript库的声明适配模块

1.3. lib.d.ts

当你安装 TypeScript 时,会顺带安装 lib.d.ts 等声明文件。此文件包含了 JavaScript 运行时以及 DOM 中存在各种常见的环境声明。

  • 它自动包含在 TypeScript 项目的编译上下文中;
  • 它能让你快速开始书写经过类型检查的 JavaScript 代码。

你可以通过指定 —noLib 的编译器命令行标志(或者在 tsconfig.json 中指定选项 noLib: true)从上下文中排除此文件。

看如下例子

const foo = 123;
const bar = foo.toString();

这段代码的类型检查正常,因为 lib.d.ts 为所有 JavaScript 对象定义了 toString 方法。

如果你在 noLib 选项下,使用相同的代码,这将会出现类型检查错误:

const foo = 123;
const bar = foo.toString(); // Error: 属性 toString 不存在类型 number 上

1.4. tsconfig.json配置文件

TS 的项目中,TS 最终都会被编译 JS 文件执行,TS 编译器在编译 TS 文件的时候都会先在项目根目录的 tsconfig.json 文件,根据该文件的配置进行编译,默认情况下,如果该文件没有任何配置,TS 编译器会默认编译项目目录下所有的 .ts.tsx.d.ts文件。实际项目中,会根据自己的需求进行自定义的配置,下面就来详细了解下tsconfig.json的文件配置。

文件选项配置

  • files : 表示编译需要编译的单个文件列表
"files": [
  // 指定编译文件是src目录下的a.ts文件
  "scr/a.ts"
]
  • include: 表示编译需要编译的文件或目录
"include": [
  // "scr" // 会编译src目录下的所有文件,包括子目录
  // "scr/*" // 只会编译scr一级目录下的文件
  "scr/*/*" // 只会编译scr二级目录下的文件
]
  • exclude:表示编译器需要排除的文件或文件夹

默认排除node_modules文件夹下文件

"exclude": [
  // 排除src目录下的lib文件夹下的文件不会编译
  "src/lib"
]
  • extends: 引入其他配置文件,继承配置
// 把基础配置抽离成tsconfig.base.json文件,然后引入
"extends": "./tsconfig.base.json"
  • compileOnSave:设置保存文件的时候自动编译

vscode暂不支持该功能,可以使用'Atom'编辑器

"compileOnSave": true

执行 tsc --init 生成的ts.config.js会有六个初始设置

{
  "compilerOptions":{
    "target":"es2016", // 指定编译成的是哪个版本的js
    "module":"commonjs", // 指定要使用的模块化的规范
    "esModuleInterop":true, //  兼容JS模块无default的导入
    "forceConsistentCasingInFileNames":true, // 兼容JS模块无default的导入
    "strict":true, // 所有严格检查的总开关
    "skipLibCheck":true // 跳过所有.d.ts文件的类型检查
  }
}

Vue3中使用TS

在Vue组合式API中它会有默认的自动类型注解,另外我们可以使用泛型进行复杂类型注解。

  1. 自动类型注解
<script setup lang="ts">
import { ref } from "vue";

let count = ref(0);
count.value = "123"; // 不能将类型“string”分配给类型“number”。
</script>
  1. 手动类型注解
<script setup lang="ts">
import { ref } from "vue";

let count = ref<string|number>(0);
count.value = "123"; // √
</script>
  1. 复杂类型注解
<script setup lang="ts">
import { ref } from "vue";

interface List {

}
let count = ref<string|number>(0);
count.value = "123"; // √
</script>

Vue3 + TS 组件通信

  1. 父子通信
// parent.vue
<my-child :count="count"></my-child>

// my-child
// 1. vue自带的定义方式
defineProps({
    count: [Number] 
})

// 2. ts的方式
interface Props({
    count: number
})

defineProps<Props>()
  1. 子父通信
// parent.vue
<my-child @say-hello="sayHello"></my-child>

const sayHello = (message: string) => {
  console.log({ message });
};

// my-child
interface Emits {
  (e: "say-hello", message: string): void;
}
let emit = defineEmits<Emits>();

emit("say-hello", "hello-world");

VueRouter + TS

  1. RouteRecordRaw -> 路由表选项类型
const routes: Array<RouteRecordRaw> = [
  {
    path: "/",
    name: "home",
    component: HomeView,
  }
];
  1. RouteMeta -> 扩展meta的类型
declare module "vue-router" {
  interface RouteMeta {
    // 是可选的
    isAdmin?: boolean;
    // 每个路由都必须声明
    requiresAuth: boolean;
  }
}
  1. RouterOptions -> createRouter的配置类型
  2. RouteLocationNormalized -> 标准化的路由地址
  3. Router -> router的实例类型
  4. 调用路由的方式
import { userRouter, useRoute } from 'vue-router'
const router = useRouter() // 类似 this.$router
const route = useRoute() // 类似 this.$route

Vuex +TS

  1. 导出key
  2. 导出key
  3. 重写useStore
  4. 使用store
// store.ts
import { createStore, Store, useStore as baseUseStore } from "vuex";
import { InjectionKey } from "vue";

export interface State {
  count: number;
}

// step 3 重写useStore
export function useStore() {
  return baseUseStore(key);
}

// step 1 导入key
export const key: InjectionKey<Store<State>> = Symbol();

export default createStore<State>({
  state: {
    count: 1,
  },
  getters: {},
  mutations: {},
  actions: {},
  modules: {},
});
// main.ts
import store, { key } from "./store";

// step 2 导出key
app.use(store,key)
// App.vue
import { useStore } from '@/store'

// step 4 使用store
const store = useStore()
console.log(store.state.count)

Pinia如何使用TS

  1. 首先在main.ts中注册Pina
import { createPina } from 'pinia'
const pinia = createPinia()
createApp(App).use(pinia).mount('#app')
  1. 创建 /stores/counter.ts文件
import { defineStore } from 'pinia'

interface Counter {
    counter: number
}

export const useCounterStore = defineStore('counterStore', {
    state: (): Counter => ({
        counter: 0
    }),
    actions: {
        add(n : number) {
            this,counter += n
        }
    }
})
  1. 在App.vue中使用
import { storeToRefs } from 'pinia
import { useCounterStore } from './stores/counter'

let counterStore = useCounter()
let { counter } = storeToRefs(counterStore)
let handleClick = () => {
    counterStore.add(2)
}
  1. Pinia除了选项式写法外,也支持组合式写法,主要利用的就是Vue组合式API来实现的
import { defineStore } from 'pinia'
impoer { ref } from 'vue'

export const useCounterStore = defineStore('counterStore', () => {
    conter = ref<number>(0)
    return { counter }
})

Element Plus中如何使用TS

  • 如果使用Volar,在ts.config.json中通过comiplerOptions.types指定全局组件类型"types": ["element-plus/global"],会有更好的提示。
相关文章
|
3月前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
180 64
|
3月前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
167 60
|
29天前
|
资源调度 JavaScript 前端开发
创建vue3项目步骤以及安装第三方插件步骤【保姆级教程】
这是一篇关于创建Vue项目的详细指南,涵盖从环境搭建到项目部署的全过程。
146 1
|
2月前
|
JavaScript API 数据处理
vue3使用pinia中的actions,需要调用接口的话
通过上述步骤,您可以在Vue 3中使用Pinia和actions来管理状态并调用API接口。Pinia的简洁设计使得状态管理和异步操作更加直观和易于维护。无论是安装配置、创建Store还是在组件中使用Store,都能轻松实现高效的状态管理和数据处理。
144 3
|
3月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
67 1
vue学习第一章
|
3月前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
64 1
|
3月前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
55 1
vue学习第四章
|
3月前
|
JavaScript 前端开发 API
从Vue 2到Vue 3的演进
从Vue 2到Vue 3的演进
96 17
|
3月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
117 17
|
3月前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
73 8

热门文章

最新文章