当前位置: 首页 > news >正文

Vue 3 入门——自学习版本

1. Vue 3 入门

  • 1.1 Vue 3 简介与历史
  • 1.2 Vue 3 与 Vue 2 的主要区别
  • 1.3 安装与项目初始化
    • 使用 Vue CLI 创建项目
    • 使用 Vite 创建项目
  • 1.4 Vue 3 的基本概念:响应式、组件、模板
  • 1.5 第一个 Vue 3 项目

2. Vue 3 响应式系统

  • 2.1 什么是响应式
  • 2.2 refreactive 的使用
  • 2.3 计算属性 (computed)
  • 2.4 侦听器 (watch)
  • 2.5 深入理解 Vue 3 的响应式原理

3. Vue 3 组件系统

  • 3.1 什么是组件

  • 3.2 创建和使用组件

  • 3.3 组件间的通信:props、$emit、事件总线

  • 3.4 插槽(slots)

    • 默认插槽与具名插槽
    • 作用域插槽
  • 3.5 动态组件与异步组件

4. Vue 3 的模板语法

  • 4.1 模板的基本语法:插值、指令(v-ifv-forv-bind 等)
  • 4.2 表达式与条件渲染
  • 4.3 列表渲染与事件处理
  • 4.4 v-model 双向绑定的使用

5. Vue 3 生命周期

  • 5.1 Vue 3 生命周期概述
  • 5.2 Composition API 生命周期钩子
    • onMountedonBeforeMount
  • 5.3 Options API 生命周期钩子
    • mountedcreated

6. Vue 3 的 Composition API

  • 6.1 Composition API 简介
  • 6.2 setup 函数
  • 6.3 refreactivecomputed 在 Composition API 中的使用
  • 6.4 watchwatchEffect
  • 6.5 自定义组合函数(composables)

7. Vue 3 路由(Vue Router)

  • 7.1 安装与配置 Vue Router
  • 7.2 路由的基本使用
  • 7.3 动态路由与路由参数
  • 7.4 嵌套路由与命名视图
  • 7.5 路由守卫与导航钩子

8. Vue 3 状态管理(Vuex)

  • 8.1 Vuex 的基本概念
  • 8.2 安装与配置 Vuex
  • 8.3 State、Getters、Mutations、Actions 的使用
  • 8.4 Vuex 模块化
  • 8.5 与组件的结合使用

9. Vue 3 异常处理与调试

  • 9.1 错误捕获与处理
  • 9.2 使用 Vue DevTools 调试
  • 9.3 日志记录与性能分析

10. Vue 3 的其他功能

  • 10.1 过渡与动画
  • 10.2 Vue 3 的 Teleport(传送门)
  • 10.3 Vue 3 的 Suspense 和异步组件
  • 10.4 Vue 3 中的自定义指令

11. Vue 3 项目实战

  • 11.1 开发一个待办事项应用
  • 11.2 开发一个博客网站(或类似项目)
  • 11.3 集成第三方库与插件(如 Vue Router、Vuex、Axios)

12. Vue 3 性能优化与部署

  • 12.1 性能优化策略
    • 懒加载与代码分割
    • 虚拟列表
  • 12.2 项目构建与打包
  • 12.3 部署到生产环境

13. Vue 3 与 TypeScript

  • 13.1 Vue 3 中如何使用 TypeScript
  • 13.2 类型推导与类型检查
  • 13.3 类型声明文件与接口

1. Vue 3 入门

1.1 Vue 3 简介与历史

Vue.js 是一个用于构建用户界面的渐进式框架。它采用了响应式的数据绑定和组件化的开发模式,使得开发者可以高效地构建现代化的单页面应用(SPA)。Vue 3 是 Vue.js 框架的最新版本,在 Vue 2 的基础上做了许多改进和优化,特别是在性能和可维护性方面。

Vue 3 的开发始于 2018 年,由尤雨溪(Evan You)主导,Vue 3 于 2020 年发布。Vue 3 的发布标志着 Vue.js 框架进入了一个新的时代,引入了许多新特性,如 Composition API、性能优化和更好的 TypeScript 支持。

1.2 Vue 3 与 Vue 2 的主要区别

Vue 3 与 Vue 2 相比,有几个显著的改进:

  • Composition API:Vue 3 引入了 Composition API,使得组件的代码更加模块化,易于复用和维护。与 Vue 2 的 Options API(通过 datamethodscomputed 等选项来定义组件的行为)不同,Composition API 通过 setup 函数提供了更灵活的方式来组织组件的逻辑。

  • 性能提升:Vue 3 在性能上有显著的改进,特别是在虚拟 DOM 的重绘优化、内存管理和组件生命周期上。Vue 3 的响应式系统使用 Proxy 取代了 Vue 2 的 Object.defineProperty,使得性能更加高效,特别是在大量数据变动时。

  • TypeScript 支持:Vue 3 对 TypeScript 的支持更好,开发者可以更方便地在 Vue 组件中使用 TypeScript 来提高类型安全和开发效率。

  • 更小的包体积:Vue 3 采用了 tree-shaking 优化,去除了不必要的代码,使得框架体积更小,加载速度更快。

  • 更灵活的生命周期钩子:Vue 3 为 Composition API 提供了新的生命周期钩子,如 onMountedonBeforeMount,让开发者可以在 setup 中更灵活地管理组件生命周期。

1.3 安装与项目初始化

在 Vue 3 中,我们可以使用 Vue CLI 或 Vite 来快速创建项目。

使用 Vue CLI 创建项目
  1. 安装 Vue CLI(如果尚未安装):

    npm install -g @vue/cli
    
  2. 创建一个新的 Vue 3 项目:

    vue create my-project
    

    在创建过程中,选择 Vue 3 配置选项。

  3. 进入项目目录并启动开发服务器:

    cd my-project
    npm run serve
    
使用 Vite 创建项目

Vite 是一个快速构建工具,Vue 3 推荐使用 Vite 来进行开发,因为它比 Vue CLI 更加高效。

  1. 创建一个新的 Vue 3 项目:

    npm create vite@latest my-project --template vue
    
  2. 进入项目目录并安装依赖:

    cd my-project
    npm install
    
  3. 启动开发服务器:

    npm run dev
    
1.4 Vue 3 的基本概念:响应式、组件、模板
  • 响应式:Vue 3 的核心特性之一就是响应式系统。Vue 会自动追踪数据的变化,并在数据变化时更新相关的视图。通过 refreactive,你可以使普通的 JavaScript 对象变得响应式。

  • 组件:Vue 是一个基于组件的框架。每个 Vue 应用由多个组件组成,组件可以包含模板、样式和逻辑。Vue 3 支持使用 setup 函数来定义组件的逻辑,这是 Composition API 的一部分。

  • 模板:Vue 使用基于 HTML 的模板语法来声明组件的 UI。模板与数据绑定,通过指令(如 v-ifv-for)和插值表达式来动态生成视图。

1.5 第一个 Vue 3 项目

让我们快速创建一个 Vue 3 应用来展示如何构建一个基本的 Vue 3 项目。

  1. 在终端中创建一个 Vue 3 项目:

    npm create vite@latest vue-app --template vue
    
  2. 进入项目目录:

    cd vue-app
    
  3. 安装依赖:

    npm install
    
  4. 编辑 src/App.vue,创建一个简单的组件:

    <template><div><h1>Hello, Vue 3!</h1><p>我的年龄是:{{ age }}</p><button @click="incrementAge">增加年龄</button></div>
    </template><script setup>
    import { ref } from 'vue';const age = ref(18);const incrementAge = () => {age.value++;
    };
    </script><style>
    h1 {color: #42b983;
    }
    </style>
    
  5. 启动项目:

    npm run dev
    

现在,你已经创建了一个简单的 Vue 3 项目。当点击按钮时,页面上的年龄会增加。通过这个例子,你可以看到 Vue 3 的基础组件、响应式和事件处理的简单实现。


2. Vue 3 响应式系统

2.1 什么是响应式

响应式是 Vue 的核心特性之一,意味着当数据发生变化时,视图会自动更新。Vue 的响应式系统会追踪数据的变化,并将变动反映到 DOM 上。这种机制减少了开发者手动更新 DOM 的需求,提高了开发效率。

Vue 3 引入了基于 Proxy 的响应式系统,这与 Vue 2 中基于 Object.defineProperty 的响应式实现有所不同。Proxy 能够拦截对象的操作,使得数据变化时,Vue 能够捕捉到并执行相应的更新。

2.2 refreactive 的使用

在 Vue 3 中,refreactive 是两个最常用的响应式 API,分别用于处理基本数据类型和对象/数组。

ref

ref 用于使基本数据类型变得响应式,通常用于处理原始值(如字符串、数字、布尔值等)。

  • 语法:

    const myValue = ref(0);
    
  • 使用方式:

    • 在模板中可以直接访问 myValue,但是在 JavaScript 代码中需要通过 .value 来访问或修改其值。
    <template><div>{{ myValue }}</div><button @click="increment">增加</button>
    </template><script setup>
    import { ref } from 'vue';const myValue = ref(0);const increment = () => {myValue.value++;
    };
    </script>
    
reactive

reactive 用于将对象或数组变为响应式,适合处理复杂的数据结构。

  • 语法:

    const myObject = reactive({ count: 0, name: 'Vue' });
    
  • 使用方式:

    • 通过 reactive 创建的对象可以直接访问其属性,无需 .value
    <template><div>{{ myObject.count }}</div><button @click="increment">增加</button>
    </template><script setup>
    import { reactive } from 'vue';const myObject = reactive({ count: 0 });const increment = () => {myObject.count++;
    };
    </script>
    
2.3 计算属性 (computed)

计算属性(computed)是 Vue 中用于基于已有数据进行计算并缓存结果的一种机制。计算属性与普通的方法不同,计算属性会缓存其计算结果,直到依赖的数据发生变化,才会重新计算。

  • 语法:

    const fullName = computed(() => {return `${firstName.value} ${lastName.value}`;
    });
    
  • 使用方式:

    • 计算属性通常用于当数据的计算依赖于其他数据时,自动更新视图。
    <template><div>{{ fullName }}</div>
    </template><script setup>
    import { ref, computed } from 'vue';const firstName = ref('John');
    const lastName = ref('Doe');const fullName = computed(() => `${firstName.value} ${lastName.value}`);
    </script>
    
  • 特点:

    • 计算属性是惰性求值的,只有在依赖的响应式数据发生变化时才会重新计算。
    • 适合用于逻辑上较为复杂的计算,如拼接字符串、处理日期等。
2.4 侦听器 (watch)

侦听器(watch)用于在数据变化时执行某些操作。与计算属性不同,侦听器更适合执行副作用操作,如异步请求、手动修改其他状态等。

  • 语法:

    watch(source, callback, options);
    
    • source:要观察的数据源,通常是响应式的数据或计算属性。
    • callback:当 source 改变时执行的回调函数。
    • options:可选的配置选项,如 immediate(立即执行回调)和 deep(深度观察对象)。
  • 使用方式:

    <template><div>{{ count }}</div><button @click="increment">增加</button>
    </template><script setup>
    import { ref, watch } from 'vue';const count = ref(0);const increment = () => {count.value++;
    };// 监听 count 的变化
    watch(count, (newValue, oldValue) => {console.log(`count 变化了,从 ${oldValue} 变成了 ${newValue}`);
    });
    </script>
    
  • 特点:

    • watch 适用于监控一个或多个响应式数据的变化,并做出响应。
    • 适合用来处理复杂的副作用,如异步操作、数据请求等。
    • 可以设置 deep 来深度监听对象的嵌套属性。
2.5 深入理解 Vue 3 的响应式原理

Vue 3 的响应式系统是基于 JavaScript 的 Proxy 对象实现的,相比 Vue 2 中的 Object.definePropertyProxy 提供了更强大和灵活的拦截功能。

  • 核心原理:

    • 在 Vue 3 中,reactiveref 会通过 Proxy 拦截对象的读取和写入操作。当访问对象的属性时,Proxy 会自动记录下依赖,并在属性值发生变化时,通知视图更新。

    • Proxy 可以拦截以下操作:

      • 读取属性(get
      • 设置属性(set
      • 删除属性(deleteProperty
  • 实现过程:

    • 每当我们访问一个响应式对象的属性时,Proxy 会触发 get 操作,这时 Vue 会将当前组件作为依赖进行追踪。
    • 当对象的属性发生变化时,Proxy 会触发 set 操作,Vue 会更新依赖该属性的组件。
  • Proxy 的优势:

    • Vue 3 的响应式系统通过 Proxy 使得 Vue 不需要显式地定义每个数据属性的 getter 和 setter。这样可以提高性能,简化代码,尤其是在处理嵌套数据和动态属性时。
    • Proxy 可以捕捉到更广泛的操作,包括属性的删除和原型链的继承,这在 Vue 2 中是无法实现的。

3. Vue 3 组件系统

3.1 什么是组件

组件是 Vue.js 中的核心概念之一,是 Vue 应用的构建块。每个 Vue 组件本质上是一个自包含的、可复用的单元,它包含了 HTML、CSS 和 JavaScript 代码。通过组件化的开发方式,开发者可以将复杂的 UI 拆分为多个小的独立部分,使得应用更加模块化、易于维护。

Vue 组件是基于模板、脚本和样式的组合,可以通过 props 接收父组件传递的数据,使用 data 存储内部状态,并通过 methodscomputed 定义组件的行为。组件的生命周期函数也使得我们能够在特定的时刻执行代码。

3.2 创建和使用组件

在 Vue 3 中,组件可以通过 defineComponentscript setup 来定义。这里介绍两种常见的方式:

3.2.1 使用 defineComponent 创建组件

defineComponent 是 Vue 3 提供的一个函数,用来定义一个组件,它帮助我们定义一个标准的 Vue 组件。

  • 语法:

    import { defineComponent } from 'vue';export default defineComponent({name: 'MyComponent',data() {return {message: 'Hello, Vue 3!'};},methods: {greet() {alert(this.message);}}
    });
    
3.2.2 使用 script setup 创建组件

Vue 3 的 script setup 是 Composition API 的一种简化方式,极大地减少了模板和逻辑之间的代码冗余,使得组件代码更加简洁。

  • 语法:

    <template><div>{{ message }}</div><button @click="greet">Greet</button>
    </template><script setup>
    import { ref } from 'vue';const message = ref('Hello, Vue 3!');const greet = () => {alert(message.value);
    };
    </script>
    
  • 使用方式:

    • template 中,定义组件的 HTML 结构;
    • script setup 中,定义响应式数据和方法。
3.2.3 使用组件

一旦组件被创建,我们可以在父组件中使用它。首先,确保组件被导入并注册。

  • 父组件使用子组件:

    <template><MyComponent />
    </template><script setup>
    import MyComponent from './components/MyComponent.vue';
    </script>
    
3.3 组件间的通信:props、$emit、事件总线

Vue 提供了多种方式来处理组件间的通信。

3.3.1 使用 props 传递数据

props 是子组件接收父组件传递数据的机制。父组件通过在子组件标签上使用 v-bind(或简写 :)将数据传递给子组件。

  • 父组件:

    <template><ChildComponent :message="parentMessage" />
    </template><script setup>
    import { ref } from 'vue';
    import ChildComponent from './components/ChildComponent.vue';const parentMessage = ref('Hello from Parent!');
    </script>
    
  • 子组件:

    <template><div>{{ message }}</div>
    </template><script setup>
    defineProps({message: String
    });
    </script>
    
3.3.2 使用 $emit 向父组件发送事件

子组件通过 $emit 向父组件发送事件。当子组件需要与父组件进行交互时,通常使用 $emit 发送自定义事件,父组件通过 v-on(或简写 @)监听这些事件。

  • 子组件:

    <template><button @click="sendMessage">Click me</button>
    </template><script setup>
    defineEmits(['sendMessage']);const sendMessage = () => {$emit('sendMessage', 'Hello, Parent!');
    };
    </script>
    
  • 父组件:

    <template><ChildComponent @sendMessage="receiveMessage" />
    </template><script setup>
    import ChildComponent from './components/ChildComponent.vue';const receiveMessage = (message) => {console.log('Received message:', message);
    };
    </script>
    
3.3.3 事件总线(Event Bus)

事件总线是一种跨组件通信的方式,它适用于非父子组件之间的通信。通常,我们可以使用一个中央对象来监听和触发事件。

  • 创建事件总线:

    import { reactive } from 'vue';const eventBus = reactive({emit(event, data) {this[event] && this[event](data);},on(event, callback) {this[event] = callback;}
    });export default eventBus;
    
  • 组件通信:

    <template><button @click="sendMessage">Send Message</button>
    </template><script setup>
    import eventBus from './eventBus';const sendMessage = () => {eventBus.emit('messageReceived', 'Hello from Component!');
    };
    </script>
    
3.4 插槽(Slots)

插槽是 Vue 中的一种机制,允许我们在父组件中通过占位符的方式传递 HTML 内容到子组件中,从而实现更大的灵活性和复用性。

3.4.1 默认插槽与具名插槽
  • 默认插槽:
    默认插槽是最基本的插槽类型,用于插入父组件中的内容。

    • 父组件:

      <template><ChildComponent><p>This is content passed through default slot.</p></ChildComponent>
      </template>
      
    • 子组件:

      <template><slot></slot>  <!-- 默认插槽 -->
      </template>
      
  • 具名插槽:
    具名插槽允许父组件将不同的内容传递到子组件的多个插槽中,通过插槽的 name 属性进行区分。

    • 父组件:

      <template><ChildComponent><template v-slot:header><h1>This is the header</h1></template><template v-slot:footer><footer>This is the footer</footer></template></ChildComponent>
      </template>
      
    • 子组件:

      <template><slot name="header"></slot>  <!-- 具名插槽 --><slot name="footer"></slot>
      </template>
      
3.4.2 作用域插槽

作用域插槽是具名插槽的一种扩展,允许子组件将数据暴露给父组件,从而在父组件中访问这些数据。

  • 父组件:

    <template><ChildComponent v-slot:default="{ message }"><p>{{ message }}</p></ChildComponent>
    </template>
    
  • 子组件:

    <template><slot :message="message"></slot>  <!-- 传递数据给父组件 -->
    </template><script setup>
    const message = 'Hello from Child Component!';
    </script>
    
3.5 动态组件与异步组件
3.5.1 动态组件

动态组件允许在运行时切换不同的组件。Vue 3 通过 <component :is="componentName"> 来实现动态组件。

  • 语法:

    <component :is="currentComponent"></component>
    
  • 使用方式:

    <template><button @click="switchComponent">Switch Component</button><component :is="currentComponent" />
    </template><script setup>
    import { ref } from 'vue';
    import ComponentA from './ComponentA.vue';
    import ComponentB from './ComponentB.vue';const currentComponent = ref(ComponentA);const switchComponent = () => {currentComponent.value = currentComponent.value === ComponentA ? ComponentB : ComponentA;
    };
    </script>
    
3.5.2 异步组件

异步组件是指只有在需要时才加载的组件,可以减少初始加载时间,提升应用性能。

  • 语法:

    const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'));
    
  • 使用方式:

    <template><AsyncComponent />
    </template><script setup>
    import { defineAsyncComponent } from 'vue';const AsyncComponent = defineAsyncComponent(() => import('./components/AsyncComponent.vue'));
    </script>
    

4. Vue 3 的模板语法

Vue 3 的模板语法采用基于 HTML 的声明式语法,允许开发者通过简单的标记来定义视图和逻辑的绑定。通过模板,我们可以轻松地将数据与 DOM 进行双向绑定,动态更新视图。

4.1 模板的基本语法:插值、指令(v-if、v-for、v-bind 等)

Vue 模板语法的基本组成包括插值和指令,下面是一些常见的语法。

插值

插值是指将数据绑定到模板中的某个位置。在 Vue 中,插值是通过 {{ }} 来实现的。常见的插值包括:

  • 文本插值

    <template><div>{{ message }}</div>
    </template><script setup>
    import { ref } from 'vue';const message = ref('Hello, Vue 3!');
    </script>
    
  • 属性插值

    <template><img :src="imageUrl" alt="Vue 3 Logo">
    </template><script setup>
    const imageUrl = ref('https://vuejs.org/images/logo.png');
    </script>
    
指令

Vue 提供了许多内置的指令来对 DOM 元素进行动态操作。指令以 v- 开头,用于绑定数据和控制 DOM 的行为。

  • v-bind:动态绑定属性值。

    <template><a v-bind:href="url">Visit Vue</a>
    </template><script setup>
    const url = ref('https://vuejs.org');
    </script>
    
  • v-if:条件渲染。

    <template><p v-if="isVisible">This is visible when isVisible is true.</p>
    </template><script setup>
    const isVisible = ref(true);
    </script>
    
  • v-for:列表渲染。

    <template><ul><li v-for="item in items" :key="item.id">{{ item.name }}</li></ul>
    </template><script setup>
    const items = ref([{ id: 1, name: 'Vue 3' },{ id: 2, name: 'React' },{ id: 3, name: 'Angular' }
    ]);
    </script>
    
  • v-on:监听事件。

    <template><button v-on:click="handleClick">Click me</button>
    </template><script setup>
    const handleClick = () => {console.log('Button clicked!');
    };
    </script>
    
4.2 表达式与条件渲染
表达式

Vue 允许在模板中使用 JavaScript 表达式进行计算。这些表达式会在数据变化时自动更新。常见的表达式包括算术运算、逻辑运算、字符串拼接等。

  • 基本表达式

    <template><p>{{ count + 1 }}</p>  <!-- 输出 count + 1 -->
    </template><script setup>
    const count = ref(5);
    </script>
    
  • 逻辑运算

    <template><p>{{ isActive ? 'Active' : 'Inactive' }}</p>
    </template><script setup>
    const isActive = ref(true);
    </script>
    
条件渲染

Vue 提供了 v-ifv-show 两个指令来处理条件渲染。

  • v-if:当条件为真时,渲染该元素,否则不渲染。

    <template><p v-if="isVisible">This is visible when isVisible is true.</p>
    </template><script setup>
    const isVisible = ref(true);
    </script>
    
  • v-show:和 v-if 类似,但 v-show 始终渲染元素,只是通过 display: none 来隐藏元素。这对于频繁切换显示状态的元素来说更为高效。

    <template><p v-show="isVisible">This is visible when isVisible is true.</p>
    </template><script setup>
    const isVisible = ref(true);
    </script>
    
  • v-else:和 v-if 配合使用,用于处理条件渲染的“否则”情况。

    <template><p v-if="isVisible">This is visible when isVisible is true.</p><p v-else>This is visible when isVisible is false.</p>
    </template><script setup>
    const isVisible = ref(false);
    </script>
    
4.3 列表渲染与事件处理
列表渲染

Vue 提供了 v-for 指令来循环渲染数组或对象。你可以使用 v-for 遍历数据并渲染每一项。

  • v-for 循环数组

    <template><ul><li v-for="item in items" :key="item.id">{{ item.name }}</li></ul>
    </template><script setup>
    const items = ref([{ id: 1, name: 'Vue 3' },{ id: 2, name: 'React' },{ id: 3, name: 'Angular' }
    ]);
    </script>
    
  • v-for 循环对象

    <template><ul><li v-for="(value, key) in object" :key="key">{{ key }}: {{ value }}</li></ul>
    </template><script setup>
    const object = ref({name: 'Vue 3',version: '3.0'
    });
    </script>
    
事件处理

Vue 通过 v-on 或简写 @ 来监听 DOM 事件并执行对应的事件处理方法。

  • 事件绑定

    <template><button @click="handleClick">Click me</button>
    </template><script setup>
    const handleClick = () => {alert('Button clicked!');
    };
    </script>
    
  • 事件参数

    <template><button @click="handleClick('Hello')">Click me</button>
    </template><script setup>
    const handleClick = (message) => {alert(message);
    };
    </script>
    
4.4 v-model 双向绑定的使用

Vue 通过 v-model 实现双向数据绑定,即自动同步输入控件的值和组件的数据。当输入控件的值发生变化时,数据会更新;反之,数据变化时,控件的值也会更新。

基本使用

在表单输入元素中使用 v-model 实现双向绑定。

  • 文本输入框

    <template><input v-model="message" /><p>{{ message }}</p>
    </template><script setup>
    const message = ref('Hello, Vue 3!');
    </script>
    
在组件中使用 v-model

你可以在自定义组件中使用 v-model 来实现双向数据绑定。

  • 父组件

    <template><ChildComponent v-model="message" /><p>{{ message }}</p>
    </template><script setup>
    import { ref } from 'vue';
    import ChildComponent from './components/ChildComponent.vue';const message = ref('Hello from Parent!');
    </script>
    
  • 子组件

    <template><input v-model="internalMessage" />
    </template><script setup>
    const internalMessage = ref('');defineEmits(['update:modelValue']);
    watch(internalMessage, (newValue) => {$emit('update:modelValue', newValue);
    });
    </script>
    

在 Vue 3 中,v-model 默认绑定到 modelValue 属性,并触发 update:modelValue 事件。如果需要更改默认的 modelValue,可以通过 model 选项进行自定义。


5. Vue 3 生命周期

Vue 生命周期是指从一个组件创建到销毁的过程中,Vue 会为组件提供一系列钩子函数,用于在不同的生命周期阶段执行特定的代码。这些生命周期钩子帮助开发者处理组件的初始化、数据获取、清理工作等。

在 Vue 3 中,生命周期钩子的使用发生了一些变化,特别是引入了 Composition API,使得生命周期钩子能够以更灵活的方式进行管理。

5.1 Vue 3 生命周期概述

Vue 组件的生命周期可以分为三个主要阶段:

  1. 创建阶段:组件被实例化,数据被初始化,但还没有挂载到 DOM 上。
  2. 挂载阶段:组件的模板被渲染并挂载到 DOM 上,组件已经可见,用户可以与组件进行交互。
  3. 销毁阶段:组件从 DOM 中移除,相关资源被清理,生命周期结束。

在 Vue 3 中,生命周期钩子函数允许开发者在这三个阶段的不同时间点执行代码。Vue 提供了不同的钩子函数来处理这些阶段。

5.2 Composition API 生命周期钩子

Vue 3 的 Composition API 引入了更加灵活和简洁的生命周期管理。所有生命周期钩子都通过 onXXX 的形式提供,并且它们可以直接放在 setup 函数中使用。

onMounted

onMounted 在组件挂载到 DOM 后立即调用。它对应于 Vue 2 中的 mounted 钩子。

  • 使用方式:

    <template><p>{{ message }}</p>
    </template><script setup>
    import { ref, onMounted } from 'vue';const message = ref('Hello, Vue 3!');onMounted(() => {console.log('Component has been mounted!');
    });
    </script>
    
  • 特点:

    • 仅在组件挂载之后执行一次。
onBeforeMount

onBeforeMount 在组件挂载之前调用,它对应于 Vue 2 中的 beforeMount 钩子。通常用于组件挂载之前的最后初始化。

  • 使用方式:

    <template><p>{{ message }}</p>
    </template><script setup>
    import { ref, onBeforeMount } from 'vue';const message = ref('Hello, Vue 3!');onBeforeMount(() => {console.log('Component is about to mount!');
    });
    </script>
    
onUpdated

onUpdated 在组件的响应式数据发生变化并重新渲染后调用。它对应于 Vue 2 中的 updated 钩子。它在视图更新后执行,可以用于处理更新后的状态。

  • 使用方式:

    <template><button @click="increment">Increment</button><p>{{ count }}</p>
    </template><script setup>
    import { ref, onUpdated } from 'vue';const count = ref(0);onUpdated(() => {console.log('Component has been updated!');
    });const increment = () => {count.value++;
    };
    </script>
    
  • 特点:

    • 在每次组件更新时执行。
onBeforeUnmount

onBeforeUnmount 在组件卸载之前调用,通常用于清理任务,如取消事件监听或清理定时器。

  • 使用方式:

    <template><p>{{ message }}</p>
    </template><script setup>
    import { ref, onBeforeUnmount } from 'vue';const message = ref('Goodbye, Vue 3!');onBeforeUnmount(() => {console.log('Component is about to unmount!');
    });
    </script>
    
  • 特点:

    • 在组件销毁前执行一次。
onUnmounted

onUnmounted 在组件销毁后调用,用于执行组件销毁后的清理工作。它对应于 Vue 2 中的 destroyed 钩子。

  • 使用方式:

    <template><p>{{ message }}</p>
    </template><script setup>
    import { ref, onUnmounted } from 'vue';const message = ref('Goodbye, Vue 3!');onUnmounted(() => {console.log('Component has been unmounted!');
    });
    </script>
    
  • 特点:

    • 在组件销毁后执行。
5.3 Options API 生命周期钩子

Vue 3 仍然保留了 Vue 2 的 Options API,生命周期钩子通过组件选项中的 createdmounted 等钩子来实现。这些钩子函数适合用于传统的组件结构。

created

created 在组件实例化后调用,但此时模板和 DOM 尚未挂载。通常用于初始化数据或执行异步请求。

  • 使用方式:

    <template><p>{{ message }}</p>
    </template><script>
    export default {data() {return {message: 'Hello from Vue 3!'};},created() {console.log('Component is created!');}
    };
    </script>
    
mounted

mounted 在组件挂载到 DOM 后调用,适合用于 DOM 操作、事件监听等。

  • 使用方式:

    <template><p>{{ message }}</p>
    </template><script>
    export default {data() {return {message: 'Component mounted!'};},mounted() {console.log('Component has been mounted!');}
    };
    </script>
    
beforeUpdate

beforeUpdate 在数据变化之前调用,适用于需要在数据变化前执行某些操作的场景。

  • 使用方式:

    <template><p>{{ count }}</p><button @click="increment">Increment</button>
    </template><script>
    export default {data() {return {count: 0};},beforeUpdate() {console.log('Component will update!');},methods: {increment() {this.count++;}}
    };
    </script>
    
updated

updated 在组件数据更新后调用,适用于在 DOM 更新后执行某些操作。

  • 使用方式:

    <template><p>{{ count }}</p><button @click="increment">Increment</button>
    </template><script>
    export default {data() {return {count: 0};},updated() {console.log('Component has been updated!');},methods: {increment() {this.count++;}}
    };
    </script>
    
beforeDestroy

beforeDestroy 在组件销毁之前调用,适用于组件销毁时的清理工作。

  • 使用方式:

    <template><p>{{ message }}</p>
    </template><script>
    export default {data() {return {message: 'Component will be destroyed!'};},beforeDestroy() {console.log('Component is about to be destroyed!');}
    };
    </script>
    
destroyed

destroyed 在组件销毁后调用,适用于执行销毁后的清理工作。

  • 使用方式:

    <template><p>{{ message }}</p>
    </template><script>
    export default {data() {return {message: 'Goodbye from Vue 3!'};},destroyed() {console.log('Component has been destroyed!');}
    };
    </script>
    

6. Vue 3 的 Composition API

Vue 3 引入的 Composition API 是 Vue 的一个重要特性,它允许开发者通过组合式的方式组织和管理组件的逻辑,使得代码更加清晰、灵活、易于复用,特别是对于大型项目和复杂的应用程序。Composition API 提供了一种新的开发方式,与 Vue 2 中的 Options API 相比,它将组件的功能按逻辑组织,而不是按生命周期钩子、数据、方法等传统选项组织。

6.1 Composition API 简介

Composition API 提供了一组函数,允许我们在 setup 函数内组织组件的逻辑。相比于 Options API,Composition API 通过 refreactivecomputed 等 API 将响应式数据、计算属性和副作用处理等功能拆分开来,使得代码逻辑更加集中和可复用。

Composition API 的优势在于:

  • 更好的代码复用:可以将业务逻辑提取到自定义组合函数(composables)中,方便在多个组件之间复用。
  • 更好的类型推导:由于其高度灵活性,Composition API 更容易与 TypeScript 配合使用,提供更强的类型推导和检查。
  • 更清晰的逻辑分离:不同功能的逻辑不再被分散在组件的多个选项中,而是通过函数组织,易于管理和维护。
6.2 setup 函数

setup 函数是 Composition API 的核心,它在组件实例化时调用,并且是 Vue 3 中第一个执行的函数。setup 函数的作用是为组件定义响应式数据、计算属性、方法等,并返回这些数据和方法,以便模板中使用。

  • 语法:

    <script setup>
    // Composition API setup
    import { ref } from 'vue';const count = ref(0);const increment = () => {count.value++;
    };
    </script>
    
  • 返回值:
    setup 函数必须返回一个对象,该对象包含组件的响应式数据、计算属性、方法等,这些返回的内容会自动暴露给模板使用。

  • 注意:

    • setup 中的代码是在组件实例化前执行的,因此在 setup 中不能访问 this
    • setup 函数的执行时机比 created 更早。
6.3 refreactivecomputed 在 Composition API 中的使用

Composition API 提供了 refreactivecomputed 三个常用的 API 来管理响应式数据和计算属性。

ref

ref 用于创建基本数据类型(如字符串、数字、布尔值等)的响应式数据。在模板中,我们可以直接访问 ref 返回的响应式对象,而在 JavaScript 中,需要通过 .value 来访问或修改其值。

  • 使用示例:

    <template><p>{{ count }}</p><button @click="increment">Increment</button>
    </template><script setup>
    import { ref } from 'vue';const count = ref(0);const increment = () => {count.value++;
    };
    </script>
    
reactive

reactive 用于创建对象或数组的响应式数据。与 ref 不同,reactive 返回的是一个代理对象,直接修改对象的属性时不需要使用 .value

  • 使用示例:

    <template><p>{{ user.name }}</p><button @click="changeName">Change Name</button>
    </template><script setup>
    import { reactive } from 'vue';const user = reactive({ name: 'John', age: 25 });const changeName = () => {user.name = 'Jane';
    };
    </script>
    
computed

computed 用于创建计算属性,计算属性会根据依赖的数据自动更新,并且只有在相关数据发生变化时才会重新计算。计算属性会被缓存,只有当依赖的数据变化时,计算属性才会重新计算。

  • 使用示例:

    <template><p>{{ fullName }}</p>
    </template><script setup>
    import { ref, computed } from 'vue';const firstName = ref('John');
    const lastName = ref('Doe');const fullName = computed(() => {return `${firstName.value} ${lastName.value}`;
    });
    </script>
    
6.4 watchwatchEffect

watchwatchEffect 都用于响应式数据变化时执行副作用操作,但它们之间有一些细微的区别。

watch

watch 用于监听一个或多个响应式数据的变化,并在数据变化时执行回调函数。watch 适用于需要执行复杂逻辑、异步操作或副作用的场景。

  • 语法:

    watch(source, callback, options);
    
    • source:要监听的响应式数据或计算属性。
    • callback:当 source 发生变化时执行的回调函数。
    • options:可选的配置选项,如 immediate(立即执行回调)和 deep(深度观察对象)。
  • 使用示例:

    <template><p>{{ count }}</p><button @click="increment">Increment</button>
    </template><script setup>
    import { ref, watch } from 'vue';const count = ref(0);const increment = () => {count.value++;
    };watch(count, (newValue, oldValue) => {console.log(`Count changed from ${oldValue} to ${newValue}`);
    });
    </script>
    
watchEffect

watchEffect 用于立即运行回调并追踪其内部使用的所有响应式数据。当内部的任何响应式数据发生变化时,watchEffect 会重新执行回调函数。watchEffect 不需要明确指定要观察的数据,它会自动追踪函数内部访问的响应式数据。

  • 使用示例:

    <template><p>{{ count }}</p><button @click="increment">Increment</button>
    </template><script setup>
    import { ref, watchEffect } from 'vue';const count = ref(0);watchEffect(() => {console.log(`Count is now: ${count.value}`);
    });const increment = () => {count.value++;
    };
    </script>
    
6.5 自定义组合函数(composables)

自定义组合函数(composables)是 Vue 3 中 Composition API 的一部分,它允许我们将逻辑提取到可复用的函数中,从而提高代码的可复用性和清晰度。组合函数通常以 use 开头,遵循一定的命名约定,以便其他开发者能够理解其用途。

自定义组合函数的使用
  • 创建组合函数:

    import { ref } from 'vue';export function useCounter() {const count = ref(0);const increment = () => {count.value++;};return { count, increment };
    }
    
  • 在组件中使用组合函数:

    <template><p>{{ count }}</p><button @click="increment">Increment</button>
    </template><script setup>
    import { useCounter } from './composables/useCounter';const { count, increment } = useCounter();
    </script>
    
自定义组合函数的优势
  • 逻辑复用:将复杂的逻辑提取到组合函数中,可以在多个组件之间复用。
  • 代码结构清晰:可以按功能模块拆分业务逻辑,而不是将所有逻辑混合在 datamethods 和生命周期钩子中。

7. Vue 3 路由(Vue Router)

Vue Router 是 Vue.js 官方的路由库,它用于管理 Vue 应用中的页面导航。Vue Router 使得开发者可以在 Vue 应用中实现复杂的页面跳转、动态加载和导航控制。Vue Router 与 Vue 3 完美集成,为单页面应用(SPA)提供路由管理。

7.1 安装与配置 Vue Router

在 Vue 3 中,Vue Router 是一个独立的库,使用之前需要先安装并配置。

安装 Vue Router
  1. 通过 npm 安装 Vue Router:

    npm install vue-router@4
    
  2. 配置 Vue Router:在 src 目录下创建 router 文件夹,并在其中创建 index.js 文件。

  • src/router/index.js

    import { createRouter, createWebHistory } from 'vue-router';
    import Home from '../views/Home.vue';
    import About from '../views/About.vue';const routes = [{ path: '/', component: Home },{ path: '/about', component: About }
    ];const router = createRouter({history: createWebHistory(),routes
    });export default router;
    
  • 在主入口文件 src/main.js 中导入并使用 Vue Router:

    src/main.js

    import { createApp } from 'vue';
    import App from './App.vue';
    import router from './router';createApp(App).use(router).mount('#app');
    
配置 Vue Router 历史模式

Vue Router 支持两种历史模式:

  • Hash 模式# 后缀模式(例如 /#/home),不需要服务器支持,默认情况下使用该模式。

  • History 模式:使用 HTML5 的 history.pushState API,创建干净的 URL 路径(例如 /home),需要服务器配置支持。

  • 在上述配置中,createWebHistory 用于设置历史模式。如果使用 hash 模式,可以使用 createWebHashHistory

7.2 路由的基本使用

路由的基本功能是将 URL 映射到组件。Vue Router 会根据 URL 的变化,渲染对应的组件。

配置路由映射

router/index.js 中配置路由,并在模板中使用 <router-view> 渲染路由的内容。

  • src/router/index.js(继续使用之前的配置):

    const routes = [{ path: '/', component: Home },{ path: '/about', component: About }
    ];
    
  • src/App.vue

    <template><div><router-link to="/">Home</router-link><router-link to="/about">About</router-link><router-view></router-view> <!-- 渲染匹配的组件 --></div>
    </template>
    
  • src/views/Home.vue

    <template><div><h1>Home Page</h1></div>
    </template><script setup>
    // 可以在这里写 Home 页面的相关逻辑
    </script>
    
  • src/views/About.vue

    <template><div><h1>About Page</h1></div>
    </template><script setup>
    // 可以在这里写 About 页面的相关逻辑
    </script>
    
使用 <router-link> 进行导航

<router-link> 用于创建可以点击的链接,点击链接后会触发路由导航。

  • 语法:

    <router-link to="/path">Link Text</router-link>
    
7.3 动态路由与路由参数

动态路由允许根据 URL 中的变化来渲染不同的组件,常用于需要传递参数的场景,例如用户的个人信息页。

配置动态路由

通过在路径中使用 :param 来定义动态路由参数。例如,展示用户信息时,可以使用 :id 来动态绑定用户的 ID。

  • src/router/index.js

    const routes = [{ path: '/user/:id', component: User },
    ];
    
  • src/views/User.vue

    <template><div><h1>User ID: {{ id }}</h1></div>
    </template><script setup>
    import { useRoute } from 'vue-router';const route = useRoute();
    const id = route.params.id;  // 获取动态路由参数
    </script>
    
使用动态路由

你可以通过 <router-link> 将动态参数传递给路由:

  • src/App.vue

    <router-link :to="'/user/' + userId">Go to User</router-link>
    
7.4 嵌套路由与命名视图
嵌套路由

嵌套路由允许你在一个路由组件内配置多个子路由,并在同一个页面中渲染多个视图。子路由的组件将会在父组件的 <router-view> 中渲染。

  • 父路由配置

    const routes = [{path: '/parent',component: Parent,children: [{ path: 'child', component: Child }]}
    ];
    
  • 父组件(Parent.vue

    <template><h1>Parent Component</h1><router-view></router-view> <!-- 子路由渲染位置 -->
    </template>
    
  • 子组件(Child.vue

    <template><div><h2>Child Component</h2></div>
    </template>
    
命名视图

命名视图允许你在同一个页面中渲染多个 <router-view>,并为它们指定不同的视图内容。

  • 父路由配置

    const routes = [{path: '/dashboard',components: {default: Dashboard,sidebar: Sidebar}}
    ];
    
  • 父组件(Dashboard.vue

    <template><router-view></router-view>  <!-- 默认视图 --><router-view name="sidebar"></router-view>  <!-- 命名视图 -->
    </template>
    
  • Sidebar 组件(Sidebar.vue

    <template><div>Sidebar Content</div>
    </template>
    
7.5 路由守卫与导航钩子

路由守卫可以在路由跳转之前或之后执行特定的操作,常用于权限控制、数据预加载等场景。

全局路由守卫

全局守卫应用于所有路由,在路由跳转前后都会被触发。

  • 使用方式:

    router.beforeEach((to, from, next) => {console.log('Global beforeEach guard');next();  // 必须调用 next() 来继续路由导航
    });router.afterEach((to, from) => {console.log('Global afterEach guard');
    });
    
路由独享守卫

路由独享守卫仅在某个特定路由的导航过程中触发,适用于特定页面的权限控制等操作。

  • 使用方式:

    const routes = [{path: '/protected',component: Protected,beforeEnter: (to, from, next) => {const isAuthenticated = checkAuth();if (isAuthenticated) {next();} else {next('/login');}}}
    ];
    
路由钩子

路由钩子允许你在路由生命周期的不同阶段执行代码。例如,beforeRouteEnter 在路由进入前被调用,beforeRouteLeave 在离开当前路由时被调用。

  • 使用方式:

    <script setup>
    import { onBeforeRouteLeave } from 'vue-router';onBeforeRouteLeave((to, from) => {console.log('Leaving route');
    });
    </script>
    

8. Vue 3 状态管理(Vuex)

Vuex 是 Vue.js 官方的状态管理库,用于管理和集中存储应用的所有组件的状态。Vuex 适用于 Vue 3 中单页面应用(SPA)的大型应用或复杂的状态管理。Vuex 提供了一种集中式的状态管理模式,使得组件间的状态共享变得更加简单和高效。

8.1 Vuex 的基本概念

Vuex 的核心概念包括:

  • State:应用的状态数据,是 Vuex 中存储的唯一数据源。所有组件都可以访问这些数据。
  • Getters:Vuex 的计算属性,用于从 State 中派生出数据。Getters 类似于组件中的计算属性,但它们的作用范围是整个应用。
  • Mutations:同步操作状态的唯一方式。Mutations 用于直接修改 State 中的数据,并且必须是同步函数。
  • Actions:处理异步操作的地方,可以在 Actions 中调用 Mutations。Actions 不能直接修改 State,而是通过调用 Mutations 来修改数据。
  • Modules:Vuex 支持将状态、mutations、actions 和 getters 拆分成模块,从而让状态管理更具可维护性,特别是在大型应用中。
8.2 安装与配置 Vuex
  1. 安装 Vuex

在 Vue 3 中,Vuex 4 是与 Vue 3 兼容的版本,需要通过 npm 安装:

npm install vuex@4
  1. 配置 Vuex

src 目录下创建 store 文件夹,并在其中创建 index.js 文件来配置 Vuex。

  • src/store/index.js

    import { createStore } from 'vuex';const store = createStore({state() {return {count: 0};},mutations: {increment(state) {state.count++;}},actions: {incrementAsync({ commit }) {setTimeout(() => {commit('increment');}, 1000);}},getters: {getCount(state) {return state.count;}}
    });export default store;
    
  1. 在主应用中使用 Vuex

src/main.js 中导入并注册 Vuex store。

  • src/main.js

    import { createApp } from 'vue';
    import App from './App.vue';
    import store from './store'; // 导入 storecreateApp(App).use(store).mount('#app');
    
8.3 State、Getters、Mutations、Actions 的使用
State

State 是 Vuex 中的核心数据存储,用于存放应用的全局状态。任何组件都可以访问 State 中的数据。

  • 使用示例:

    <template><p>{{ count }}</p>
    </template><script setup>
    import { useStore } from 'vuex';const store = useStore();
    const count = computed(() => store.state.count);  // 访问 Vuex state
    </script>
    
Getters

Getters 类似于计算属性,它是对 State 中数据的派生和过滤。Getters 可以用于将多个 State 数据组合,或根据特定条件返回一个计算结果。

  • 使用示例:

    <template><p>{{ getCount }}</p>
    </template><script setup>
    import { useStore } from 'vuex';const store = useStore();
    const getCount = computed(() => store.getters.getCount);  // 访问 Vuex getters
    </script>
    
Mutations

Mutations 用于修改 State 中的数据。它们是同步操作,必须通过 commit 提交,不能在 mutations 中执行异步操作。

  • 使用示例:

    <template><button @click="increment">Increment</button>
    </template><script setup>
    import { useStore } from 'vuex';const store = useStore();
    const increment = () => {store.commit('increment');  // 调用 Vuex mutation
    };
    </script>
    
Actions

Actions 用于处理异步操作或复杂的逻辑,并且可以在 action 中通过 commit 调用 mutations。Actions 可以使用 dispatch 在组件中调用。

  • 使用示例:

    <template><button @click="incrementAsync">Increment Async</button>
    </template><script setup>
    import { useStore } from 'vuex';const store = useStore();
    const incrementAsync = () => {store.dispatch('incrementAsync');  // 调用 Vuex action
    };
    </script>
    
8.4 Vuex 模块化

Vuex 提供了模块化的机制,使得在大型应用中,能够将 store 分为多个模块,每个模块拥有自己的 state、mutations、actions 和 getters。

  • 模块化配置

    import { createStore } from 'vuex';const store = createStore({modules: {counter: {state() {return {count: 0};},mutations: {increment(state) {state.count++;}},actions: {incrementAsync({ commit }) {setTimeout(() => {commit('increment');}, 1000);}},getters: {getCount(state) {return state.count;}}}}
    });export default store;
    
  • 访问模块中的数据

    <template><p>{{ count }}</p><button @click="incrementAsync">Increment Async</button>
    </template><script setup>
    import { useStore } from 'vuex';const store = useStore();
    const count = computed(() => store.state.counter.count);  // 访问模块中的 state
    const incrementAsync = () => {store.dispatch('counter/incrementAsync');  // 调用模块中的 action
    };
    </script>
    
8.5 与组件的结合使用

将 Vuex 与 Vue 组件结合使用时,通常会使用 useStore 钩子来访问 store。在组件中,通过 store.state 访问状态,通过 store.commit 提交 mutations,通过 store.dispatch 调用 actions,或者通过 store.getters 获取计算结果。

在组件中访问 State 和 Getters
  • 访问 State:

    <template><p>{{ count }}</p>
    </template><script setup>
    import { useStore } from 'vuex';const store = useStore();
    const count = computed(() => store.state.count);  // 访问 Vuex state
    </script>
    
  • 访问 Getters:

    <template><p>{{ getCount }}</p>
    </template><script setup>
    import { useStore } from 'vuex';const store = useStore();
    const getCount = computed(() => store.getters.getCount);  // 访问 Vuex getters
    </script>
    
在组件中提交 Mutations 和调用 Actions
  • 提交 Mutations:

    <template><button @click="increment">Increment</button>
    </template><script setup>
    import { useStore } from 'vuex';const store = useStore();
    const increment = () => {store.commit('increment');  // 提交 Vuex mutation
    };
    </script>
    
  • 调用 Actions:

    <template><button @click="incrementAsync">Increment Async</button>
    </template><script setup>
    import { useStore } from 'vuex';const store = useStore();
    const incrementAsync = () => {store.dispatch('incrementAsync');  // 调用 Vuex action
    };
    </script>
    

9. Vue 3 异常处理与调试

在开发复杂的 Vue 3 应用时,异常处理和调试是不可忽视的重要部分。Vue 提供了多种方法来捕获和处理错误,同时,调试工具和性能分析也能帮助我们高效地找到和解决问题。下面将详细介绍如何在 Vue 3 中进行异常处理、调试和性能分析。

9.1 错误捕获与处理

Vue 3 提供了多种方式来捕获和处理错误,包括全局错误捕获、组件级错误捕获和异步错误处理。

全局错误捕获

Vue 3 允许你通过 config.errorHandler 全局配置来捕获所有组件中的错误。这是在应用级别处理错误的有效方式,适用于那些未能在组件中处理的错误。

  • 使用示例:

    const app = createApp(App);app.config.errorHandler = (err, vm, info) => {console.error('Caught an error:', err);console.log('Component:', vm);console.log('Info:', info);
    };app.mount('#app');
    
  • 参数解释:

    • err: 捕获到的错误对象。
    • vm: 错误发生的组件实例。
    • info: 额外的信息(例如 Vue 生命周期钩子)。
组件级错误捕获

Vue 3 也支持组件级的错误捕获,允许你在单个组件内使用 errorCaptured 生命周期钩子来捕获错误。

  • 使用示例:

    <template><div><button @click="throwError">Throw Error</button></div>
    </template><script setup>
    const throwError = () => {throw new Error('An error occurred');
    };defineOptions({errorCaptured(err, vm, info) {console.error('Error captured:', err);console.log('Component:', vm);console.log('Info:', info);return false;  // 如果返回 false,则继续向上冒泡错误}
    });
    </script>
    
异步错误捕获

Vue 3 对于异步操作中的错误也提供了捕获机制,可以通过 try-catch 语句来捕获异步函数中的错误。

  • 使用示例:

    <template><button @click="fetchData">Fetch Data</button>
    </template><script setup>
    const fetchData = async () => {try {const response = await fetch('https://api.example.com/data');const data = await response.json();console.log(data);} catch (error) {console.error('Error fetching data:', error);}
    };
    </script>
    
9.2 使用 Vue DevTools 调试

Vue DevTools 是 Vue 官方提供的浏览器插件,用于调试 Vue 应用。它允许我们查看组件树、查看响应式数据、调试 Vuex 状态以及检测性能瓶颈等。

安装 Vue DevTools
  1. 在浏览器中访问 Vue DevTools 官方网站,并根据你的浏览器下载并安装对应的插件。
  2. 安装完成后,打开开发者工具(通常按 F12Ctrl + Shift + I),在浏览器的插件栏中找到 Vue DevTools 面板。
使用 Vue DevTools
  • 查看组件树:在 Vue DevTools 中,可以看到整个 Vue 应用的组件树,查看每个组件的状态和属性。
  • 查看响应式数据:通过 VuexReactive 标签,你可以查看 Vuex 中的状态,或直接查看组件的响应式数据。
  • 调试 Vuex:Vue DevTools 提供了 Vuex 状态管理的调试功能,允许你查看状态、mutations 和 actions,并且可以跳过或回溯操作。
  • 性能分析:在 Vue DevTools 中的 “性能” 面板,可以查看每次组件渲染的时间,帮助你定位性能瓶颈。
调试生命周期钩子

Vue DevTools 也可以查看各个组件的生命周期钩子,帮助你分析应用的生命周期流程。你可以看到组件何时创建、更新、销毁等操作。

9.3 日志记录与性能分析

在开发过程中,记录日志和分析性能是非常重要的。Vue 提供了一些内建工具以及与第三方库的集成,帮助开发者进行日志记录和性能分析。

日志记录

Vue 3 的 console 方法可以结合应用的生命周期进行日志记录,帮助开发者追踪应用的状态和行为。

  • 使用示例

    <template><button @click="increment">Increment</button>
    </template><script setup>
    import { ref } from 'vue';const count = ref(0);const increment = () => {count.value++;console.log('Current count:', count.value);  // 日志记录
    };
    </script>
    

在实际应用中,开发者可以使用 console.logconsole.warnconsole.error 方法来打印不同类型的日志。对于更复杂的应用,可以使用更专业的日志库,如 loglevelwinston 来管理日志的级别和输出。

性能分析

Vue 3 提供了内建的性能工具,可以帮助开发者分析应用的性能瓶颈。例如,使用浏览器的开发者工具进行性能分析,或借助 Vue DevTools 来查看组件的渲染时间。

  • 性能分析工具

    • 浏览器开发者工具:现代浏览器提供了强大的性能分析工具,你可以使用它们来分析页面加载时间、网络请求和渲染性能等。
    • Vue DevTools:如前所述,Vue DevTools 中的“性能”面板可以帮助开发者查看组件渲染时间、性能瓶颈以及不必要的组件更新。
    • performance.now():通过原生 JavaScript 的 performance.now() 方法,你可以精确地计算代码执行的时间,并进行性能优化。
  • 使用示例

    const start = performance.now();// 一些操作const end = performance.now();
    console.log(`Operation took ${end - start} milliseconds`);
    

通过 performance.now(),你可以精准地衡量操作的执行时间,从而找到可能的性能瓶颈。

第三方性能分析工具

对于更深入的性能分析,你可以集成第三方性能监控工具,如:

  • Lighthouse:Lighthouse 是由 Google 提供的开源工具,用于分析 Web 应用的性能、可访问性和 SEO 等方面。
  • Sentry:Sentry 是一个错误监控工具,可以帮助开发者捕获应用中的错误并跟踪性能问题。
  • New Relic:New Relic 提供了全面的应用性能监控工具,可以帮助开发者跟踪应用的性能瓶颈和优化点。

10. Vue 3 的其他功能

Vue 3 提供了一些额外的功能,使得开发者能够构建更加灵活和高效的应用。以下是 Vue 3 中的一些进阶特性,包括过渡与动画、Teleport、Suspense、异步组件以及自定义指令等。

10.1 过渡与动画

Vue 3 提供了强大的过渡和动画系统,可以让你为元素的插入、移除和更新添加动画效果,提升应用的视觉体验。

基本用法

Vue 使用 <transition> 标签来包裹需要添加过渡效果的元素。当元素的状态发生变化时,Vue 会自动应用指定的过渡效果。

  • 语法:

    <transition name="fade"><div v-if="isVisible">Hello, Vue!</div>
    </transition>
    
过渡类名

Vue 提供了默认的过渡类名,这些类名会在元素的生命周期内自动切换,具体包括:

  • v-enter: 元素插入前
  • v-enter-active: 元素插入时
  • v-enter-to: 元素插入后
  • v-leave: 元素移除前
  • v-leave-active: 元素移除时
  • v-leave-to: 元素移除后

你可以通过 CSS 自定义这些类来实现动画效果。

  • CSS 过渡效果:

    <style>
    .fade-enter-active, .fade-leave-active {transition: opacity 1s;
    }
    .fade-enter, .fade-leave-to {opacity: 0;
    }
    </style>
    
动画与 JavaScript

如果你需要更复杂的动画效果,可以使用 JavaScript 钩子来控制过渡过程。

  • JavaScript 钩子:

    <transition @before-enter="beforeEnter" @enter="enter" @leave="leave"><div v-if="isVisible">Hello, Vue!</div>
    </transition><script setup>
    const beforeEnter = (el) => {console.log('Before Enter');
    };const enter = (el, done) => {el.offsetHeight; // Trigger reflow to enable transitiondone();
    };const leave = (el, done) => {console.log('Leaving');done();
    };
    </script>
    
10.2 Vue 3 的 Teleport(传送门)

Vue 3 引入了 Teleport 组件,允许你将一个组件的内容渲染到 DOM 中的另一个位置,而不是其父组件的默认位置。这在需要将元素渲染到页面其他位置时非常有用,比如模态框、弹出层等。

  • 使用示例:

    <template><Teleport to="body"><div class="modal">This is a modal</div></Teleport>
    </template><style>
    .modal {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background: white;padding: 20px;border-radius: 8px;
    }
    </style>
    
  • to 属性:
    to 属性用于指定要渲染到的目标元素,可以是一个 CSS 选择器字符串或一个 DOM 元素。

  • 应用场景:

    • 模态框:将模态框渲染到 body 元素中,而不是当前的父组件。
    • 通知:可以将通知组件渲染到页面的顶部,而不是原本的组件树结构中。
10.3 Vue 3 的 Suspense 和异步组件

Suspense 是 Vue 3 中用于处理异步组件加载的一种机制,它使得组件可以在异步加载数据或组件时显示加载状态。Suspense 组件允许你指定一个等待的状态,直到所有子组件加载完成后再渲染它们。

使用 Suspense
  • 语法:

    <Suspense><template #default><AsyncComponent /></template><template #fallback><p>Loading...</p></template>
    </Suspense>
    
  • 解释:

    • default 插槽用于渲染异步组件。
    • fallback 插槽用于渲染加载过程中的状态。
异步组件

在 Vue 3 中,异步组件是按需加载的组件。这些组件只有在真正需要时才会被加载,从而减少初始加载时的资源消耗。

  • 定义异步组件:

    const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'));
    
  • 使用异步组件:

    <template><AsyncComponent />
    </template><script setup>
    import { defineAsyncComponent } from 'vue';const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'));
    </script>
    
  • 异步组件的加载状态:
    使用 Suspense 可以为异步组件添加加载指示器,并在异步组件加载完成后渲染。

10.4 Vue 3 中的自定义指令

Vue 3 允许开发者创建自定义指令,以扩展 Vue 的功能。指令通常用于操作 DOM,例如处理样式、添加事件监听器或进行 DOM 操作等。

创建自定义指令

自定义指令的创建过程非常简单,你只需要定义一个对象并提供 beforeMountmountedupdatedunmounted 等生命周期钩子来操作 DOM。

  • 使用示例:

    const vFocus = {beforeMount(el) {el.focus();}
    };const app = createApp(App);
    app.directive('focus', vFocus);
    
  • 组件中使用自定义指令:

    <template><input v-focus />
    </template>
    
自定义指令的钩子

Vue 3 的自定义指令可以使用以下生命周期钩子:

  • beforeMount:指令绑定到元素时调用。
  • mounted:指令已经绑定到元素并插入 DOM 时调用。
  • updated:指令所在的元素及其子元素更新时调用。
  • beforeUnmount:指令解绑前调用。
  • unmounted:指令解绑后调用。
自定义指令的参数

自定义指令支持动态参数、修饰符和钩子中的传入值。你可以在指令上使用动态参数和修饰符来处理不同的 DOM 操作。

  • 使用参数和修饰符:

    <template><p v-color:blue>Change my color!</p>
    </template><script setup>
    app.directive('color', {beforeMount(el, binding) {el.style.color = binding.arg || 'red';  // 使用动态参数设置颜色}
    });
    </script>
    

11. Vue 3 项目实战

在学习 Vue 3 的过程中,实际项目的开发是一个重要的步骤,能够帮助你巩固知识并掌握更高阶的技巧。下面我们将展示如何使用 Vue 3 来开发一些常见的应用,包括一个待办事项应用、一个博客网站,以及如何集成一些常见的第三方库和插件(如 Vue Router、Vuex 和 Axios)来增强功能。

11.1 开发一个待办事项应用

待办事项应用是一个非常经典的项目,适合初学者进行练习。通过这个项目,你将学习如何管理数据、处理用户输入、进行数据绑定以及实现增、删、改、查功能。

1.1.1 项目结构

项目可以分为以下几个部分:

  • 一个输入框,用于输入待办事项。
  • 一个列表,用于展示所有待办事项。
  • 一个删除按钮,用于删除已完成的待办事项。
1.1.2 实现代码
<template><div><h1>待办事项</h1><input v-model="newTask" @keyup.enter="addTask" placeholder="输入新的任务" /><ul><li v-for="(task, index) in tasks" :key="index"><span :style="{ textDecoration: task.completed ? 'line-through' : '' }">{{ task.text }}</span><button @click="toggleCompletion(index)">完成</button><button @click="removeTask(index)">删除</button></li></ul></div>
</template><script setup>
import { ref } from 'vue';const newTask = ref('');
const tasks = ref([]);const addTask = () => {if (newTask.value.trim()) {tasks.value.push({ text: newTask.value, completed: false });newTask.value = '';}
};const toggleCompletion = (index) => {tasks.value[index].completed = !tasks.value[index].completed;
};const removeTask = (index) => {tasks.value.splice(index, 1);
};
</script><style scoped>
input {margin: 10px;padding: 5px;font-size: 16px;
}button {margin-left: 10px;
}
</style>
1.1.3 代码解析
  • 使用 v-model 来实现双向数据绑定,用户输入的内容会自动更新到 newTask 中。
  • 通过 v-for 渲染任务列表,每个任务有一个按钮用来标记完成或删除任务。
  • toggleCompletion 方法用来切换任务的完成状态,removeTask 方法用来删除任务。
11.2 开发一个博客网站(或类似项目)

博客网站通常需要实现用户认证、文章展示、评论功能、以及后台管理系统等。在 Vue 3 中,你可以使用 Vue Router 来实现页面导航,使用 Vuex 来管理状态,并且通过 Axios 来进行数据请求。

1.2.1 项目结构

一个简单的博客应用包括以下页面和功能:

  • 首页:展示所有文章。
  • 文章详情页:查看某篇文章的内容。
  • 登录/注册页面:用户可以登录或注册。
  • 后台管理页面:用于创建、编辑和删除文章。
1.2.2 安装依赖

首先,使用 Vue CLI 或 Vite 创建项目并安装必要的依赖:

npm install vue-router@4 vuex@4 axios
1.2.3 配置 Vue Router
import { createRouter, createWebHistory } from 'vue-router';
import HomePage from './components/HomePage.vue';
import ArticlePage from './components/ArticlePage.vue';
import LoginPage from './components/LoginPage.vue';const routes = [{ path: '/', component: HomePage },{ path: '/article/:id', component: ArticlePage },{ path: '/login', component: LoginPage }
];const router = createRouter({history: createWebHistory(),routes
});export default router;
1.2.4 配置 Vuex
import { createStore } from 'vuex';const store = createStore({state() {return {articles: [],user: null};},mutations: {setArticles(state, articles) {state.articles = articles;},setUser(state, user) {state.user = user;}},actions: {fetchArticles({ commit }) {axios.get('/api/articles').then((response) => {commit('setArticles', response.data);});},login({ commit }, user) {commit('setUser', user);}}
});export default store;
1.2.5 使用 Axios 获取数据
<template><div><h1>博客文章</h1><ul><li v-for="article in articles" :key="article.id"><router-link :to="'/article/' + article.id">{{ article.title }}</router-link></li></ul></div>
</template><script setup>
import { useStore } from 'vuex';
import { onMounted } from 'vue';const store = useStore();
const articles = computed(() => store.state.articles);onMounted(() => {store.dispatch('fetchArticles');
});
</script>
1.2.6 代码解析
  • 使用 Vue Router 来管理页面的跳转。
  • 使用 Vuex 来存储应用的全局状态(如文章列表和用户信息)。
  • 使用 Axios 来从后台获取文章数据,并在组件加载时通过 onMounted 调用 Vuex action 来获取数据。
11.3 集成第三方库与插件(如 Vue Router、Vuex、Axios)

在 Vue 3 中,集成第三方库和插件非常简单。以下是常见的集成方式。

1.3.1 使用 Vue Router 实现页面导航
  • 安装 Vue Router:

    npm install vue-router@4
    
  • 创建路由并在 main.js 中配置:

    import { createApp } from 'vue';
    import App from './App.vue';
    import router from './router';createApp(App).use(router).mount('#app');
    
1.3.2 使用 Vuex 进行状态管理
  • 安装 Vuex:

    npm install vuex@4
    
  • 创建并配置 store:

    import { createStore } from 'vuex';const store = createStore({state() {return {user: null};},mutations: {setUser(state, user) {state.user = user;}}
    });const app = createApp(App);
    app.use(store);
    
1.3.3 使用 Axios 进行 API 请求
  • 安装 Axios:

    npm install axios
    
  • 发送 HTTP 请求:

    import axios from 'axios';axios.get('https://api.example.com/data').then(response => {console.log(response.data);}).catch(error => {console.error('API request failed:', error);});
    

通过这些第三方库和插件,你可以轻松地构建更为复杂的应用,整合 Vue Router、Vuex 和 Axios 后,你的 Vue 3 项目将变得更加高效、功能齐全,能够处理更复杂的应用需求。


12. Vue 3 性能优化与部署

在开发复杂的 Vue 3 应用时,性能优化和部署是非常重要的环节。良好的性能可以提升用户体验,确保应用在不同设备上流畅运行。与此同时,部署到生产环境时需要考虑如何有效地进行打包、构建和优化。

12.1 性能优化策略

Vue 3 提供了多种优化策略,帮助我们提升应用的加载速度、响应速度和整体性能。以下是一些常见的优化技术:

12.1.1 懒加载与代码分割

懒加载(Lazy Loading) 是一种按需加载的技术,可以将应用程序的代码分成多个较小的块,只在需要时加载。这有助于减少初始加载的时间。

  • 懒加载组件:
    Vue Router 和 Vue 3 支持异步组件,允许在需要时加载特定的组件,而不是在应用启动时加载所有组件。

    const MyComponent = defineAsyncComponent(() => import('./components/MyComponent.vue'));
    
  • 路由懒加载:
    在 Vue Router 中,我们可以通过懒加载来按需加载页面组件,这样可以减少应用的初始包大小。

    const routes = [{path: '/home',component: () => import('./views/Home.vue')  // 异步加载 Home 组件}
    ];
    
  • 配置 Webpack 进行代码分割:
    Webpack 会自动根据 import() 的动态导入来分割代码。你可以在组件中按需引入其他模块,Webpack 会为这些模块生成单独的包。

    // 动态导入
    const module = () => import('./module');
    
12.1.2 虚拟列表

虚拟列表(Virtual Scrolling)是一种优化长列表渲染性能的技术。它通过只渲染视口范围内的元素,而不是一次性渲染整个列表,从而大大减少了 DOM 节点的数量,提升渲染性能。

  • 虚拟滚动实现:
    使用虚拟滚动时,我们只渲染视口可见部分的内容,随着用户滚动,新的内容才会被渲染到视图中。

    可以使用第三方库来实现虚拟列表,例如 vue-virtual-scroller。

    npm install vue-virtual-scroller
    

    然后在应用中使用:

    <template><virtual-scroller :items="items" :item-height="50"><template v-slot="{ item }"><div>{{ item }}</div></template></virtual-scroller>
    </template><script setup>
    import { ref } from 'vue';
    import { VirtualScroller } from 'vue-virtual-scroller';const items = ref(Array.from({ length: 1000 }, (_, i) => `Item ${i + 1}`));
    </script>
    
12.2 项目构建与打包

Vue 3 项目通常使用现代的构建工具进行打包和优化,最常用的是 Vite 和 Webpack。

12.2.1 使用 Vite 构建与打包

Vite 是一个快速的构建工具,基于原生 ES 模块,在开发时非常高效。它提供了开箱即用的代码分割、热模块替换(HMR)等功能,非常适合用于 Vue 3 项目的构建和打包。

  • 安装 Vite:
    使用 Vue 3 和 Vite 创建项目:

    npm create vite@latest vue-app --template vue
    
  • 构建项目:
    package.json 文件中配置 Vite 的构建命令:

    {"scripts": {"build": "vite build"}
    }
    
  • 优化配置:
    Vite 默认支持代码分割和懒加载,但你可以进一步优化构建,例如配置更精细的分包策略,减少 bundle 大小。

    // vite.config.js
    export default {build: {rollupOptions: {output: {manualChunks(id) {if (id.includes('node_modules')) {return 'vendor';}}}}}
    };
    
12.2.2 使用 Webpack 构建与打包

Webpack 是一个功能强大的构建工具,广泛用于 Vue 2 项目,但它也支持 Vue 3 项目。Webpack 提供了很多插件和功能,用于优化构建和打包过程。

  • 安装 Webpack:
    使用 Vue CLI 创建项目时,Webpack 会自动安装并配置。

    vue create my-project
    
  • 打包项目:
    package.json 文件中配置 Webpack 的构建命令:

    {"scripts": {"build": "webpack --config webpack.config.js"}
    }
    
  • Webpack 优化:
    Webpack 提供了多种优化选项,例如:

    • splitChunks:用于将第三方库从应用代码中分离,减少主包的大小。
    • Tree Shaking:移除未使用的代码。
    • Minification:压缩代码,减小文件体积。
    // webpack.config.js
    module.exports = {optimization: {splitChunks: {chunks: 'all'}}
    };
    
12.3 部署到生产环境

在 Vue 3 项目完成构建和打包后,接下来就是将应用部署到生产环境。Vue 3 项目通常部署到静态文件服务器,或通过云服务(如 Netlify、Vercel、GitHub Pages)进行托管。

12.3.1 打包 Vue 3 项目

无论使用 Vite 还是 Webpack,打包后的文件会生成在 dist/ 目录下。你可以使用以下命令来构建项目:

  • Vite:

    npm run build
    
  • Webpack:

    npm run build
    
12.3.2 部署到静态服务器

dist/ 目录中的内容上传到静态文件托管服务,常见的静态服务器包括:

  • Nginx:部署到 Nginx 服务器,设置静态文件托管。
  • Apache:部署到 Apache 服务器,配置 .htaccess 以支持 Vue Router 的 history 模式。
12.3.3 部署到云服务

现代的云服务提供了一键部署的功能,使得部署变得更加简单。常见的云服务包括:

  • Netlify:直接将 GitHub 仓库与 Netlify 连接,自动构建并部署。
  • Vercel:类似于 Netlify,Vercel 支持从 GitHub 或 GitLab 自动部署。
  • GitHub Pages:适用于小型项目,将 Vue 项目部署到 GitHub Pages。
12.3.4 配置 CDN

对于大型应用,可以通过 CDN(内容分发网络)优化静态资源的加载速度。将 JS、CSS 和图片等静态文件上传到 CDN,可以大幅提高全球用户的访问速度。

12.3.5 环境变量与配置

在部署时,确保使用正确的环境变量来控制生产和开发环境的不同配置。Vue CLI 和 Vite 都支持环境变量管理。

  • Vite 配置环境变量:
    .env 文件中设置环境变量:

    VITE_API_URL=https://api.example.com
    
  • 使用环境变量:

    const apiUrl = import.meta.env.VITE_API_URL;
    

13. Vue 3 与 TypeScript

Vue 3 从一开始就全面支持 TypeScript,允许开发者在开发过程中利用 TypeScript 的类型检查、类型推导和类型安全等功能,提升开发效率和代码质量。在 Vue 3 中使用 TypeScript,不仅能获得更强大的类型支持,还能增强代码的可维护性和可扩展性。

13.1 Vue 3 中如何使用 TypeScript

在 Vue 3 中,使用 TypeScript 非常简单。你只需要通过 Vue CLI 或 Vite 创建一个 TypeScript 项目,或者手动配置 TypeScript。

使用 Vue CLI 创建 TypeScript 项目
  1. 安装 Vue CLI(如果尚未安装):

    npm install -g @vue/cli
    
  2. 创建 Vue 项目并选择 TypeScript:

    vue create my-vue-project
    

    在提示中选择 TypeScript 模板。

  3. 项目创建完成后,你会看到项目中已经包含了 TypeScript 配置文件 (tsconfig.json),并且 Vue 组件默认是 .vue 文件,其中的 <script> 标签会自动识别为 TypeScript。

使用 Vite 创建 TypeScript 项目

Vite 是一个现代的构建工具,特别适合 Vue 3 项目,并且内置对 TypeScript 的支持。

  1. 创建项目并选择 Vue 3 + TypeScript 模板:

    npm create vite@latest my-vue-project --template vue-ts
    
  2. 安装依赖:

    cd my-vue-project
    npm install
    
  3. 项目结构会自动配置好 TypeScript 和 Vue 3,接下来你就可以开始编写 TypeScript 代码。

手动配置 TypeScript

如果你已经有一个 Vue 3 项目,并且想要添加 TypeScript 支持,你需要手动配置以下几个步骤:

  1. 安装 TypeScript 和相关类型:

    npm install typescript @types/node
    
  2. 在项目根目录下创建一个 tsconfig.json 文件,配置 TypeScript:

    {"compilerOptions": {"target": "esnext","module": "esnext","moduleResolution": "node","jsx": "preserve","strict": true,"esModuleInterop": true,"skipLibCheck": true,"forceConsistentCasingInFileNames": true,"noImplicitAny": true,"resolveJsonModule": true,"isolatedModules": true,"allowSyntheticDefaultImports": true,"baseUrl": "./","paths": {"@/*": ["src/*"]}},"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],"exclude": ["node_modules"]
    }
    
  3. 修改 .vue 文件中的 <script> 标签,指定为 lang="ts"

    <template><div>{{ message }}</div>
    </template><script lang="ts">
    import { defineComponent } from 'vue';export default defineComponent({data() {return {message: 'Hello, TypeScript in Vue 3!'};}
    });
    </script>
    
13.2 类型推导与类型检查

TypeScript 的类型推导和类型检查功能可以帮助开发者捕获潜在的错误和问题。Vue 3 与 TypeScript 的结合使得我们能够在组件中享受到类型安全和智能提示的好处。

组件中的类型推导
  • 响应式数据的类型推导:
    在 Vue 3 中使用 refreactive 创建响应式数据时,TypeScript 会自动推导类型。例如:

    import { ref } from 'vue';const count = ref(0);  // TypeScript 会推导出 count 的类型是 `Ref<number>`
    
  • 计算属性的类型推导:
    Vue 3 的 computed 函数同样支持类型推导,它可以自动推导计算结果的类型:

    import { ref, computed } from 'vue';const count = ref(0);
    const doubleCount = computed(() => count.value * 2);  // doubleCount 的类型是 `ComputedRef<number>`
    
类型检查

TypeScript 会检查数据类型和方法类型,帮助我们在编写代码时避免类型错误。例如,Vue 3 会对方法中的参数进行类型检查:

import { ref } from 'vue';const message = ref('Hello, TypeScript!');const updateMessage = (newMessage: string) => {message.value = newMessage;  // TypeScript 会检查 newMessage 是否为 string 类型
};
13.3 类型声明文件与接口

在 Vue 3 和 TypeScript 中,类型声明文件和接口非常重要,它们帮助我们更好地定义组件、props、state 和方法的类型。

使用接口定义组件的 props 类型

你可以通过接口定义 props 的类型,这样 TypeScript 就能检查组件传入的 props 是否符合预期。

import { defineComponent } from 'vue';interface Props {name: string;age: number;
}export default defineComponent({props: {name: String,age: Number},setup(props: Props) {console.log(props.name);  // TypeScript 会检查 props.name 是否为 string 类型}
});
类型声明文件

类型声明文件(.d.ts)用于在项目中声明模块或全局变量的类型,以便 TypeScript 识别这些类型。

  • 示例: 创建一个全局类型声明文件 src/shims-vue.d.ts,让 TypeScript 知道 .vue 文件的类型:

    declare module "*.vue" {import { DefineComponent } from "vue";const component: DefineComponent<{}, {}, any>;export default component;
    }
    
使用类型声明文件扩展全局类型

你可以通过类型声明文件来扩展 Vue 的全局类型,例如为 Vue 组件的实例添加类型定义。

  • 示例:src/types.d.ts 文件中添加 Vue 实例的类型声明:

    declare module '@vue/runtime-core' {interface ComponentCustomProperties {$myCustomMethod: () => void;}
    }
    

    然后,你可以在 Vue 组件中访问 $myCustomMethod

    import { defineComponent } from 'vue';export default defineComponent({mounted() {this.$myCustomMethod();  // TypeScript 知道 $myCustomMethod 的类型}
    });
    

http://www.dtcms.com/a/273609.html

相关文章:

  • DOM编程实例(不重要,可忽略)
  • 分享|2025年机器学习工程师职业技术证书报考指南
  • 论容器化 | 分析Go和Rust做医疗的后端服务
  • 在vue中使用Three.js渲染FBX模型
  • arcgis api for js 设置地图服务请求带有请求头信息
  • 录音实时上传
  • uniapp
  • Claude Code是什么?国内如何使用到Claude Code?附国内最新使用教程
  • 基于定制开发开源AI智能名片与S2B2C商城小程序的旅游日志创新应用研究
  • uniapp小程序tabbar跳转拦截与弹窗控制
  • Elasticsearch混合搜索深度解析(上):问题发现与源码探索
  • Excel 转 JSON by WTSolutions API 文档
  • 较为深入的了解c++中的string类(2)
  • MyBatis 从入门到实战:代理 Dao 模式下的 CRUD 全解析
  • Netplan 配置网桥(Bridge)的模板笔记250711
  • excel如何只保留前几行
  • 提示工程:解锁大模型潜力的核心密码
  • 基于redis的分布式session共享管理之销毁事件不生效问题
  • 这个方法的目的是检查一个给定的项目ID(projectId)是否在当前数据库中被使用(搜索全库)
  • SortByCustomOrder 根据指定的顺序对任意类型的列表进行排序
  • Python七彩花朵
  • 【实时Linux实战系列】实时系统测试与合规认证指南
  • 二刷 黑马点评 商户查询缓存
  • <script>标签对HTML文件解析过程的影响以及async和defer属性的应用
  • 在 React Three Fiber 中实现 3D 模型点击扩散波效果
  • 车企战略投资项目管理的实践与思考︱中国第一汽车集团进出口有限公司战略部投资管理专家庞博
  • 台球 PCOL:极致物理还原的网页斯诺克引擎(附源码深度解析)
  • 软件设计师中级逻辑公式题
  • Ubuntu 24.04上安装 Intelligent Pinyin 中文输入法
  • Java算法 -蓝桥云课 -卖货