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

【2024最新】vue3的基本使用(超详细)

一、Vue 3 概述

1. 为什么要学习Vue 3

Vue 3是Vue.js的最新主要版本,它带来了许多改进和新特性,包括但不限于:

  • 性能提升:Vue 3提供了更快的渲染速度和更低的内存使用率。
  • Composition API:引入了一个新的API,允许更灵活的代码组织和复用,特别适合构建大型应用。
  • 更好的TypeScript支持:Vue 3从头开始就考虑了TypeScript的支持,使得使用TypeScript开发Vue应用更加顺畅。
  • 更小的体积:通过优化和树摇(tree-shaking),Vue 3的体积更小,使得加载时间更短。

学习Vue 3可以让你利用最新的Web开发技术构建高效、可维护的前端应用。

2. Vue 3的新变化

Vue 3带来了很多重要的新变化,包括:

  • Composition API:提供了一种新的方式来组织组件的逻辑,使得功能更容易被提取和复用。
  • 响应式系统的重写:使用Proxy对象重写了响应性系统,提高了性能并减少了内存占用。
  • 片段(Fragments):组件可以有多个根节点,而不再限于单一根节点。
  • Teleport组件:允许将子节点渲染到DOM树的其他位置。
  • Suspense组件:提供了一种新的方式来处理异步组件的加载状态。
3. 破坏性语法的更新

Vue 3也引入了一些破坏性更新,以提高性能和开发体验,比如:

  • 废除了一些不再推荐使用的API,如Vue.extendVue.mixin等。
  • EventBus的使用方式发生了变化,推荐使用提供/注入(provide/inject)模式或是Vuex来进行全局状态管理。

接下来,让我们用一个简单的示例开始Vue 3的旅程:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue 3 Hello World</title>
</head>
<body>
<div id="app">{{ message }}</div><script src="https://unpkg.com/vue@3.4.0"></script>
<script>const { createApp } = Vue;createApp({data() {return {message: 'Hello Vue 3!'}}}).mount('#app');
</script>
</body>
</html>

这个示例创建了一个最基本的Vue 3应用,展示了如何使用createApp方法创建一个新的Vue应用,并将其挂载到页面上的指定元素。

二、Vue 3 开发环境搭建

搭建Vue 3开发环境是开始学习和开发Vue 3应用的第一步。这一部分将引导你如何创建Vue 3项目,并简要介绍项目结构的变化。

1. 创建Vue 3项目

Vue 3项目可以通过Vue CLI或Vite这两种方式创建。Vue CLI是Vue的官方命令行工具,而Vite是一个现代化的前端构建工具,提供了更快的开发服务器启动和热重载。

使用Vue CLI创建项目:

首先,确保你安装了最新版的Vue CLI。如果尚未安装,可以通过npm安装:

npm install -g @vue/cli

然后,创建一个新的Vue 3项目:

vue create my-vue-app

在创建过程中,CLI会让你选择预设配置。为了使用Vue 3,你可以选择“Manually select features”来自定义功能,确保选择了“Vue 3”选项。

使用Vite创建项目:

Vite是一个建立在现代Web标准之上的新一代前端构建工具。使用Vite创建Vue 3项目,可以获得极速的服务启动和模块热更新。安装Vite并创建一个新项目:

npm init vite@latest my-vue-app -- --template vue

接下来,进入项目目录并安装依赖:

cd my-vue-app
npm install
2. 创建Vue 2和Vue 3项目的文件变化

Vue 3项目的文件结构在大体上保持了与Vue 2类似的结构,但也有一些关键的变化和改进:

  • main.js:Vue 3使用createApp函数来创建一个Vue应用实例,而Vue 2使用new Vue()构造函数。
  • 单文件组件(.vue文件):在Vue 3中,<script setup>语法糖允许更简洁的组合式API代码,使得组件的编写更加高效。
3. Vue 3中的App单文件不再强制要求必须有根元素

在Vue 2中,每个单文件组件(.vue文件)必须有一个单独的根元素。而在Vue 3中,这一限制被取消,允许组件有多个根元素,这为组件的布局提供了更大的灵活性。

示例代码:创建Vue 3项目

以下是一个简单的Vue 3项目的main.js示例,演示了如何使用createApp来创建一个Vue应用:

import { createApp } from 'vue';
import App from './App.vue';createApp(App).mount('#app');

这里,App.vue是根组件,它可以是这样的:

<template><div>Hello Vue 3!</div><div>This is a multi-root component!</div>
</template><script>
export default {name: 'App'
}
</script>

三、组合式API(Composition API)和选项式API(Options API)

Vue 3引入了一个新的API——组合式API(Composition API),这是一个重大的创新,旨在解决在使用Vue 2中的选项式API(Options API)时遇到的一些限制,尤其是在处理大型和复杂组件时。我们来看看这两种API的主要差异和它们的应用场景。

选项式API(Options API)

在Vue 2中,我们主要通过选项式API来组织组件的代码,比如data, methods, props, computed, watch等选项。这种方式很直观,因为它将不同类型的组件选项分门别类地组织起来。

<template><div>{{ fullName }}</div>
</template><script>
export default {data() {return {firstName: 'Jane',lastName: 'Doe'}},computed: {fullName() {return this.firstName + ' ' + this.lastName;}}
}
</script>
组合式API(Composition API)

Vue 3的组合式API提供了一种更灵活的组织组件逻辑的方式。它通过setup()函数允许你将相关功能组织在一起,而不是基于选项类型分开。这使得代码重用和逻辑提取变得更加简单,尤其是在构建复杂组件时。

<template><div>{{ fullName }}</div>
</template><script>
import { ref, computed } from 'vue';export default {setup() {const firstName = ref('Jane');const lastName = ref('Doe');const fullName = computed(() => firstName.value + ' ' + lastName.value);return { fullName };}
}
</script>
API比较
  • 代码组织:组合式API使得按逻辑组织代码变得更加容易,特别是在处理复杂组件时,可以将相关的逻辑放在一起,而不是分散在不同的选项中。
  • 类型推断:组合式API提供了更好的TypeScript集成,因为它能够利用TypeScript的类型推断,使得在使用TypeScript开发Vue应用时更加顺畅。
  • 代码复用:通过组合式API,可以更容易地将组件逻辑抽取到可复用的函数中,这对于保持代码的干净和维护性是非常有帮助的。
示例代码:使用Composition API
<template><button @click="increment">Count is: {{ count }}</button>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}return { count, increment };}
}
</script>

这个例子展示了如何使用ref来创建一个响应式的计数器,以及如何将逻辑(如增加计数)组织在setup函数中。

组合式API和选项式API各有优势,Vue 3提供了这两种API,以便开发者可以根据具体项目和个人偏好选择最适合的方式。

四、组合式API(Composition API)

Vue 3的组合式API是一组基于函数的API,让你能够更灵活地组织和重用组件逻辑。通过组合式API,你可以更容易地将组件逻辑按功能组织,而不是分散在不同的Vue选项中。下面我们来详细看看组合式API的核心特性。

1. setup函数

setup函数是组合式API的入口点,它在组件创建之前执行,此时组件的props已经解析完成。你可以在这个函数里定义响应式状态、计算属性和函数,然后返回它们,使其在模板中可用。

示例代码:

<template><div>{{ message }}</div>
</template><script>
import { ref } from 'vue';export default {setup() {const message = ref('Hello Vue 3!');// 返回的对象中的属性和函数在模板中可用return { message };}
}
</script>

在这个例子中,我们使用ref函数创建了一个响应式的数据message,并在模板中使用它。

2. 生命周期钩子

在组合式API中,你可以使用特定的函数来访问组件的生命周期钩子,这些函数名称以on开头,例如onMountedonUpdatedonUnmounted等。

示例代码:

<script>
import { onMounted, ref } from 'vue';export default {setup() {const count = ref(0);onMounted(() => {console.log('Component is mounted!');});return { count };}
}
</script>

这个例子展示了如何在组件挂载完成后使用onMounted生命周期钩子。

组合式API的优势在于它提供了更大的灵活性和逻辑复用的能力。使用setup函数,你可以按照逻辑而不是选项类型来组织代码,这在管理大型或复杂组件时特别有用。同时,通过直接使用生命周期钩子的函数,你可以更直接地控制组件的行为。

接下来,我们将探讨组合式API中的响应式引用(ref)和响应式对象(reactive),这两个是组合式API中最常用的响应式状态管理工具。

五、响应式Ref函数

在Vue 3的组合式API中,ref函数用于创建一个响应式的引用对象。这个对象内部有一个.value属性,通过这个属性可以获取或设置该引用的值。ref是处理基本数据类型(如字符串、数字、布尔值)的响应式状态时非常有用的工具。

1. 不使用ref函数

在不使用ref的情况下,如果你尝试直接在setup函数内使用基本类型的数据,那么这些数据不会是响应式的。这意味着当数据变化时,视图不会自动更新。

let count = 0; // 这不是响应式的
2. 使用ref函数

使用ref可以让基本数据类型变成响应式的。这是因为ref返回的是一个响应式对象,我们通过操作这个对象的.value属性来读写实际的值。

示例代码:

<template><button @click="increment">Count is: {{ count }}</button>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}return { count, increment };}
}
</script>

在这个示例中,count是通过ref创建的响应式引用。我们在模板中直接使用count而不是count.value,Vue内部会自动处理这些引用。但是在JavaScript逻辑中,我们通过count.value来读写这个值。

3. ref引用

ref不仅可以用于基本数据类型,也可以用于引用类型数据(如对象或数组)。当用于引用类型时,Vue会递归地将这些数据转换为响应式数据。

示例代码:

<script>
import { ref } from 'vue';export default {setup() {const state = ref({count: 0,message: "Hello"});function increment() {state.value.count++;}return { state, increment };}
}
</script>

在这个例子中,state是一个包含多个属性的对象。通过ref创建的响应式引用,我们可以保持对这个对象内部属性的响应式更新。

通过使用ref,Vue 3的组合式API使状态管理变得简单而直接,无论是基本数据类型还是引用类型数据。ref是构建响应式数据的基础,是理解和使用Vue 3必须掌握的概念之一。

接下来,我们将讨论reactive函数,它是另一个在Vue 3中管理响应式状态的重要工具,特别适用于复杂的对象。

六、Reactive函数

在Vue 3的组合式API中,除了ref之外,reactive函数是另一个核心功能,用于创建响应式的复杂数据结构,如对象或数组。reactive提供了一种更自然的方式来处理对象和数组,使其成为响应式数据,而无需使用.value属性进行访问。

使用reactive函数

reactive接收一个普通对象并返回该对象的响应式代理。与ref不同,当你修改使用reactive创建的对象的属性时,不需要使用.value

示例代码:

<template><div>{{ state.count }}</div><button @click="increment">Increment</button>
</template><script>
import { reactive } from 'vue';export default {setup() {const state = reactive({count: 0});function increment() {state.count++;}return { state, increment };}
}
</script>

在这个例子中,我们创建了一个响应式对象state,并在模板中直接使用了它的属性。这比使用ref更加直接,尤其是在处理复杂对象时。

对比refreactive
  • 基本类型ref适用于基本数据类型,可以通过.value进行读写。reactive不能直接用于基本数据类型。
  • 引用类型reactive直接作用于对象或数组,使其成为响应式。对于复杂的数据结构,reactiveref更加适用。
  • 模板中的使用:无论是ref还是reactive创建的响应式数据,都可以直接在模板中使用,Vue 会自动处理。
深度响应式和浅响应式
  • 默认情况下reactive会递归地把一个对象内部的所有属性都转换为响应式数据。
  • 浅响应式:如果你不希望对象内部的所有属性都是响应式的,可以使用shallowReactive函数,它只会使最外层的属性成为响应式,而不会影响嵌套对象。
import { shallowReactive } from 'vue';const state = shallowReactive({innerObject: { count: 0 }
});
// `state`是响应式的,但`state.innerObject`不是响应式的。

reactiveref是Vue 3中组合式API的两大支柱,理解它们之间的差异以及如何选择使用它们,对于高效开发Vue 3应用至关重要。

接下来,我们将讨论toRefs函数,它允许我们从reactive对象中提取出多个响应式引用,以保持结构分解赋值的响应性。

七、toRefs函数

在Vue 3的组合式API中,toRefs函数用于将reactive对象转换为一个普通对象,其中每个属性都是一个ref,这对于保持响应式状态在结构分解赋值(destructuring)时特别有用。

为什么需要toRefs

当你从reactive对象中结构出属性时,这些属性会失去响应性。这是因为结构赋值是基于值的拷贝,所以拷贝出来的值不会和原始的reactive对象保持响应连接。toRefs可以解决这个问题,它允许你在结构分解时保持属性的响应性。

示例代码:

假设我们有一个reactive对象:

import { reactive, toRefs } from 'vue';export default {setup() {const state = reactive({count: 0,message: "Hello Vue 3"});// 尝试直接结构,会导致失去响应性// let { count, message } = state;// 使用toRefs来保持响应性let { count, message } = toRefs(state);return { count, message };}
}
如何使用toRefs

toRefs接收一个响应式对象,并返回一个新的对象。返回的对象中的每个属性都是一个指向原始对象相应属性的ref

<template><div>{{ count }}</div><div>{{ message }}</div>
</template>

在模板中,你可以直接使用countmessage,就像它们是使用ref创建的响应式引用一样。这保证了即使在结构分解后,你依然可以保持组件的响应性。

toRefsref
  • toRefs适用于将reactive对象转换成一个包含多个ref属性的普通对象,每个ref都是响应式的。
  • ref用于创建单个响应式数据。

使用toRefs可以非常方便地在保持响应性的同时,使用JavaScript的结构分解功能,这对于在多个地方使用或传递reactive对象的部分属性时非常有用。

到目前为止,我们已经讨论了Vue 3的组合式API中的基本响应式API——refreactivetoRefs。这些工具为开发复杂组件提供了灵活性和强大的状态管理能力。

接下来,我们将进一步探讨Vue 3中的计算属性(computed)和侦听器(watch)。这些功能使得我们可以更细致地控制响应式状态的变化和更新。

八、Computed计算属性

在Vue 3中,计算属性(computed)是一种基于响应式依赖进行缓存的计算值。当计算属性依赖的响应式状态发生变化时,计算属性会重新计算。这非常适合用于执行开销较大的计算操作或派生状态。

1. 基本用法

使用computed函数可以创建一个计算属性。computed接收一个函数作为参数,这个函数的返回值就是计算属性的值。当依赖的响应式状态改变时,这个函数会被重新执行。

示例代码:

<template><div>{{ fullName }}</div>
</template><script>
import { reactive, computed } from 'vue';export default {setup() {const person = reactive({firstName: 'John',lastName: 'Doe'});const fullName = computed(() => {return `${person.firstName} ${person.lastName}`;});return { fullName };}
}
</script>

在这个例子中,fullName是一个计算属性,它依赖于reactive对象personfirstNamelastName。当person的属性改变时,fullName会自动更新。

2. 高级用法

computed也支持一个带有getset函数的对象,允许你创建可写的计算属性。这在需要执行额外逻辑来处理更新操作时非常有用。

示例代码:

<template><div>{{ fullName }}</div><button @click="changeName">Change Name</button>
</template><script>
import { reactive, computed } from 'vue';export default {setup() {const person = reactive({firstName: 'John',lastName: 'Doe'});const fullName = computed({get() {return `${person.firstName} ${person.lastName}`;},set(newValue) {const names = newValue.split(' ');person.firstName = names[0];person.lastName = names[1] || '';}});function changeName() {fullName.value = 'Jane Doe';}return { fullName, changeName };}
}
</script>

在这个高级用法中,我们定义了一个可写的计算属性fullName。当尝试设置fullName.value时,设置函数(setter)会被调用,允许我们将一个新值分解并赋值给person.firstNameperson.lastName

计算属性是Vue响应系统的重要部分,它使得管理复杂逻辑和依赖变得简单高效。

接下来,我们将探讨Vue 3中的侦听器(watchwatchEffect),它们提供了一种方法来响应数据的变化。

九、Watch监听

Vue 3的组合式API提供了watchwatchEffect两种方式来侦听响应式数据的变化,并执行相应的副作用。这两种API都非常强大,可以用于执行数据变化时的异步操作、资源清理或复杂的业务逻辑。

1. 单个数据监听 - watch

watch函数用于侦听单个或多个响应式引用(ref)或响应式对象(reactive)的属性,并在它们变化时执行回调函数。watch的回调函数接收新值和旧值作为参数。

示例代码:

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

在这个例子中,每当count的值变化时,我们都会在控制台打印出一条消息。

2. 多个数据监听

watch也可以同时侦听多个数据源。你需要将它们放在一个数组里,并在回调函数中接收一个数组形式的新值和旧值。

watch([ref1, ref2], ([newVal1, newVal2], [oldVal1, oldVal2]) => {// 响应变化
});
3. 复杂数据类型监听

对于复杂数据类型,如使用reactive创建的响应式对象,你可能希望在嵌套属性变化时也能触发侦听器。这时,可以直接将响应式对象传递给watch,Vue会进行深度监听。

4. 监听复杂数据类型中的属性

如果你只想监听响应式对象的某个属性,可以使用一个函数来返回这个属性的值。

watch(() => state.someNestedProperty,(newValue, oldValue) => {// 响应变化}
);
5. 开启深度监听

使用watch侦听响应式对象时,默认情况下不会深度侦听。如果需要深度侦听,可以通过传递一个配置对象,将deep属性设置为true

watch(state,(newValue, oldValue) => {// 深度响应变化},{ deep: true }
);
watchEffect的使用

watchEffect函数会立即执行传递给它的回调函数,并响应式地追踪回调函数中使用的任何响应式状态的变化。当依赖的响应式状态发生变化时,watchEffect会再次执行。

<script>
import { ref, watchEffect } from 'vue';export default {setup() {const count = ref(0);watchEffect(() => console.log(count.value));return { count };}
}
</script>

watchwatchEffect提供了灵活且强大的方式来对响应式数据的变化作出反应,它们是Vue组合式API中不可或缺的一部分。

接下来,如果你准备好了,我们可以讨论Vue 3中组件之间的通信,包括父子通信和提供/注入机制。

十、父子通信

在Vue 3中,组件之间的通信是构建应用时的关键部分。Vue 提供了多种方式来实现不同场景下的组件通信,包括但不限于props、自定义事件、提供/注入机制等。我们首先讨论最常见的父子通信方式。

1. 父传子 - Props

Props是父组件向子组件传递数据的主要方式。子组件需要显式声明它期望接收的props。

子组件(ChildComponent.vue):

<!-- 子组件 -->
<template><div>{{ parentMessage }}</div>
</template><script setup>
const props = defineProps({parentMessage: String
});
</script>
<!-- 父组件 -->
<template><div><ChildComponent :parentMessage="message" /></div>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';const message = ref('Hello from parent');
</script>

在这个例子中,父组件通过messageprop向ChildComponent传递了一个字符串。

2. 子传父 - 自定义事件

子组件可以通过触发事件来向父组件传递信息。Vue 3中,使用$emit方法触发事件已被废弃,推荐使用defineEmitscontext.emit

子组件(ChildComponent.vue):

<template><button @click="notifyParent">Click Me</button>
</template><script>
import { defineEmits } from 'vue';export default {setup() {const emit = defineEmits(['custom-event']);function notifyParent() {emit('custom-event', 'Some data');}return { notifyParent };}
}
</script>

父组件:

<template><ChildComponent @custom-event="handleCustomEvent" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},methods: {handleCustomEvent(data) {console.log(data); // 输出: Some data}}
}
</script>

在这个例子中,子组件通过触发custom-event事件,并传递数据来与父组件通信。父组件监听这个事件,并定义了一个处理函数handleCustomEvent来接收数据。

这两种方法是Vue中实现父子通信的基础。通过Props,父组件可以向子组件传递数据,而通过自定义事件,子组件可以向父组件发送消息。

Vue还提供了更高级的通信方式,如提供/注入机制,它允许祖先组件向所有子孙组件传递数据,而无需通过每一层的props来显式传递。

十一、Vue 3中的指令变化

Vue 3引入了一些新指令并更新了一些现有指令的用法,以提高开发效率和应用性能。这里我们重点讨论v-modelv-if系列指令的变化。

1. v-model的变化

在Vue 2中,v-model主要用于在表单控件和应用状态之间创建双向数据绑定。Vue 3扩展了v-model的用法,允许在自定义组件上使用多个v-model绑定。

Vue 2用法:

<input v-model="message" />

Vue 3用法:

Vue 3允许自定义组件上使用多个v-model

<CustomComponent v-model:title="pageTitle" v-model:content="pageContent" />

在自定义组件内部,可以通过defineProps来接收这些属性:

<script setup>
const props = defineProps({title: String,content: String
});
</script>

并使用emit来更新这些属性:

const emit = defineEmits(['update:title', 'update:content']);
2. v-ifv-else-ifv-else的使用

这一系列的指令在Vue 3中保持不变,用于条件渲染。v-ifv-else-if需要跟一个表达式,v-else不需要。这三个指令必须紧跟在彼此后面使用。

<template><div v-if="type === 'A'">A</div><div v-else-if="type === 'B'">B</div><div v-else>C</div>
</template>

这些更新和变化反映了Vue 3在灵活性和功能性方面的提升,使得开发者能够更有效地构建复杂且高性能的应用。

Vue 3还引入了其他的新特性和API改进,包括TeleportSuspense以及对Composition API的进一步增强。

十二、Vue 3中的TypeScript支持

Vue 3从一开始就把TypeScript支持作为其核心特性之一。这意味着Vue 3不仅能够提供更好的类型推断和代码智能提示,而且还能让开发者利用TypeScript的全部功能来构建应用。这种一流的TypeScript支持为开发大型应用和提高代码质量带来了巨大的好处。

类型增强

Vue 3利用Composition API提供了更好的类型推断。当你使用refreactive等API时,Vue 3能够准确地推断出相应的类型,这使得在使用TypeScript开发应用时能够获得更为准确的代码提示和类型检查。

示例代码:

<script lang="ts">
import { defineComponent, ref, Ref } from 'vue';export default defineComponent({setup() {const count: Ref<number> = ref(0); // `count`被推断为一个数字类型的响应式引用function increment() {count.value++;}return { count, increment };}
});
</script>

在这个例子中,我们明确声明了count是一个数字类型的响应式引用(Ref<number>)。这种类型声明让TypeScript能够提供准确的类型检查和代码提示。

使用defineComponent进行类型推断

Vue 3推荐使用defineComponent函数来定义组件,这不仅使得组件支持TypeScript,而且还能提供更好的类型推断和组件选项的类型检查。

<script lang="ts">
import { defineComponent } from 'vue';export default defineComponent({props: {message: String},setup(props) {console.log(props.message); // `props.message`被正确推断为`string`}
});
</script>

通过defineComponent,Vue 3可以准确地推断propsdatacomputed等选项的类型,大大提高了开发体验。

十三 Suspense

Vue 3引入的Suspense组件是一个用于处理异步组件加载和异步数据的特殊内置组件。它提供了一种新的方式来处理在等待异步操作完成时的UI渲染,特别适用于控制如数据获取、异步组件(或其依赖)加载等场景的用户体验。

工作原理

当一个组件需要进行异步操作,比如数据请求或异步导入另一个组件时,Suspense允许你定义一个“备用”内容(例如加载指示器),在异步操作完成之前显示。这意味着你可以提供一个平滑的用户体验,避免在数据加载时显示一个空白或不完整的页面。

基本用法

Suspense通过两个插槽来工作:

  • default 插槽:包含异步加载的组件。
  • fallback 插槽:在等待异步操作完成时显示的内容。
<template><Suspense><template #default><AsyncComponent /></template><template #fallback><div>Loading...</div></template></Suspense>
</template><script>
import { defineAsyncComponent } from 'vue';export default {components: {AsyncComponent: defineAsyncComponent(() =>import('./components/AsyncComponent.vue'))}
}
</script>

在这个例子中,AsyncComponent是通过defineAsyncComponent定义的一个异步组件。在AsyncComponent加载过程中,用户会看到“Loading…”信息。一旦组件加载完成,Suspense将渲染该组件,替换掉加载提示。

高级场景

Suspense也支持更复杂的使用场景,比如在组件内部进行异步数据获取。这通常通过组合式API中的async setup()函数实现。

<template><Suspense><template #default><div>{{ data }}</div></template><template #fallback><div>Loading...</div></template></Suspense>
</template><script>
import { defineComponent } from 'vue';
import { fetchData } from './api'; // 假设的API请求函数export default defineComponent({async setup() {const data = await fetchData();return { data };}
});
</script>

在这个场景中,组件利用async setup()函数来获取数据。在数据未到达之前,用户将看到“Loading…”提示。

虽然Suspense和骨架屏都是提升加载体验的手段,但Suspense更多的是从组件和逻辑层面提供支持,而骨架屏更侧重于视觉和用户感知层面。在实际应用中,二者可以结合使用,即在Suspense的fallback插槽中使用骨架屏,提供更加丰富和直观的加载状态反馈,进一步提升用户体验。

相关文章:

【2024最新】vue3的基本使用(超详细)

一、Vue 3 概述 1. 为什么要学习Vue 3 Vue 3是Vue.js的最新主要版本&#xff0c;它带来了许多改进和新特性&#xff0c;包括但不限于&#xff1a; 性能提升&#xff1a;Vue 3提供了更快的渲染速度和更低的内存使用率。Composition API&#xff1a;引入了一个新的API&#xf…...

【xinference】(8):在autodl上,使用xinference部署qwen1.5大模型,速度特别快,同时还支持函数调用,测试成功!

1&#xff0c;关于xinference Xorbits Inference (Xinference) 是一个开源平台&#xff0c;用于简化各种 AI 模型的运行和集成。借助 Xinference&#xff0c;您可以使用任何开源 LLM、嵌入模型和多模态模型在云端或本地环境中运行推理&#xff0c;并创建强大的 AI 应用。 Xor…...

YARN集群 和 MapReduce 原理及应用

YARN集群模式 本文内容需要基于 Hadoop 集群搭建完成的基础上来实现 如果没有搭建&#xff0c;请先按上一篇: <Linux 系统 CentOS7 上搭建 Hadoop HDFS集群详细步骤> 搭建&#xff1a;https://mp.weixin.qq.com/s/zPYsUexHKsdFax2XeyRdnA 配置hadoop安装目录下的 etc…...

C++算法——滑动窗口

一、长度最小的子数组 1.链接 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 2.描述 3.思路 本题从暴力求解的方式去切入&#xff0c;逐步优化成“滑动窗口”&#xff0c;首先&#xff0c;暴力枚举出各种组合的话&#xff0c;我们先让一个指针指向第一个&…...

Rust---有关介绍

目录 Rust---有关介绍变量的操作Rust 数值库&#xff1a;num某些基础数据类型序列(Range)字符类型单元类型 发散函数表达式&#xff08;&#xff01; 语句&#xff09; Rust—有关介绍 得益于各种零开销抽象、深入到底层的优化潜力、优质的标准库和第三方库实现&#xff0c;Ru…...

vue项目双击from表单限制重复提交 添加全局注册自定义函数

第一步: 找到utils文件夹添加directive.js文件 import Vue from vue //全局防抖函数 // 在vue上挂载一个指量 preventReClick const preventReClick Vue.directive(preventReClick, {inserted: function (el, binding) {console.log(el.disabled)el.addEventListener(click,…...

WebPack的使用及属性配、打包资源

WebPack(静态模块打包工具)(webpack默认只识别js和json内容) WebPack的作用 把静态模块内容压缩、整合、转译等&#xff08;前端工程化&#xff09; 1️⃣把less/sass转成css代码 2️⃣把ES6降级成ES5 3️⃣支持多种模块文件类型&#xff0c;多种模块标准语法 export、export…...

机器学习实战17-高斯朴素贝叶斯(GaussianNB)模型的实际应用,结合生活中的生动例子帮助大家理解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下机器学习实战17-高斯朴素贝叶斯(GaussianNB)模型的实际应用&#xff0c;结合生活中的生动例子帮助大家理解。GaussianNB&#xff0c;即高斯朴素贝叶斯模型&#xff0c;是一种基于概率论的分类算法&#xff0c;广泛应…...

数据处理库Pandas数据结构DataFrame

Dataframe是一种二维数据结构&#xff0c;数据以表格形式&#xff08;与Excel类似&#xff09;存储&#xff0c;有对应的行和列&#xff0c;如图3-3所示。它的每列可以是不同的值类型&#xff08;不像 ndarray 只能有一个 dtype&#xff09;。基本上可以把 DataFrame 看成是共享…...

中国发展新能源的核心驱动力是什么?其原理是如何运作的?

中国发展新能源的核心驱动力是推进能源消费方式变革、构建多元清洁能源供应体系、实施创新驱动发展战略、深化能源体制改革和持续推进国际合作。 新能源的发展背后有多重经济、政策及环境因素的推动&#xff1a; 经济发展需求&#xff1a;随着中国经济的快速发展&#xff0c;…...

skywalking

部署&#xff1a; docker部署方式 docker-compose.yaml version: 3 services:elasticsearch:build:context: elasticsearchrestart: alwaysnetworks:- skywalking_netcontainer_name: elasticsearchimage: elasticsearch:7.17.6environment:- "discovery.typesingle-no…...

江苏开放大学2024年春《大学英语(D) 060108》第二次过程性考核作业参考答案

答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 单选题 1从选项中选出翻译最为准确的一项。 We cannot help …...

dockerfile制作-pytoch+深度学习环境版

你好你好&#xff01; 以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 文档内容docker相关术语docker常用命令容器常用命令根据dockerfile创建容器dokerfile文件内容 docker问题&#xff1a;可能的原因和解决方法示例修改修改后的D…...

YOLOv8结合SCI低光照图像增强算法!让夜晚目标无处遁形!【含端到端推理脚本】

这里的"SCI"代表的并不是论文等级,而是论文采用的方法 — “自校准光照学习” ~ 左侧为SCI模型增强后图片的检测效果,右侧为原始v8n检测效果 这篇文章的主要内容是通过使用SCI模型和YOLOv8进行算法联调,最终实现了如上所示的效果:在增强图像可见度的同时,对图像…...

视频监控/云存储/AI智能分析平台EasyCVR集成时调用接口报跨域错误的原因

EasyCVR视频融合平台基于云边端架构&#xff0c;可支持海量视频汇聚管理&#xff0c;能提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、智能分析等视频服务。平台兼容性强&#xff0c;支持多协议、多类型设备接入&#xff0c;包括&#xff1a;国标G…...

VuePress基于 Vite 和 Vue 构建优秀框架

VitePress 是一个静态站点生成器 (SSG)&#xff0c;专为构建快速、以内容为中心的站点而设计。简而言之&#xff0c;VitePress 获取用 Markdown 编写的内容&#xff0c;对其应用主题&#xff0c;并生成可以轻松部署到任何地方的静态 HTML 页面。 VitePress 附带一个用于技术文档…...

冒泡排序,选择排序,插入排序,希尔排序,基数排序,堆排序代码分析(归并排序和快速排序后续更新)

所有的算法都是这样&#xff0c;算法思想最重要&#xff0c;其次是实现过程&#xff0c;最后才是实现的代码 上战伐谋&#xff0c;我们只要明确了其算法思想和实现过程&#xff0c;所有算法都是纸老虎&#xff0c;所有算法题都是纸老虎 笔者才疏学浅&#xff0c;也算是刚刚接…...

从入门到精通:NTP卫星时钟服务器技术指南

从入门到精通&#xff1a;NTP卫星时钟服务器技术指南 从入门到精通&#xff1a;NTP卫星时钟服务器技术指南 一、 产品功能 卫星时钟服务器是一款采用GPS或北斗卫星提供高精度网络时间服务的产品。卫星天线安装简便&#xff08;根据天线所放位置提示实时卫星颗数&#xff09;&a…...

OpenResty基于来源IP和QPS来限流

Nginx 经典限流法 ngx_http_limit_req_module 和 ngx_http_limit_conn_module&#xff0c;可以在代理层面对服务进行限流和熔断。 http {# 请求限流定义1:# - $binary_remote_addr&#xff1a;限制对象(客户端)# - zone&#xff1a;定义限制(策略)名称# - 10m&#xff1a;用十…...

面对AI技术创业的挑战以及提供给潜在创业者的一些建议

面对AI创业的挑战 AI技术创业虽然机遇众多&#xff0c;但也面临不少挑战&#xff0c;理解这些挑战并寻找应对策略是创业成功的关键。 技术挑战 AI技术的快速发展意味着创业者需要持续学习和更新知识库&#xff0c;以保持技术竞争力。同时&#xff0c;AI项目往往需要处理大量数…...

N76E003烧录避坑指南:Nu-Link与ICP工具实战技巧

N76E003烧录避坑指南&#xff1a;Nu-Link与ICP工具实战技巧 对于嵌入式开发者而言&#xff0c;N76E003作为新唐科技&#xff08;Nuvoton&#xff09;推出的高性能8051内核微控制器&#xff0c;凭借其丰富的外设资源和优异的性价比&#xff0c;在工业控制、智能家居等领域广受欢…...

SpringBoot+VUE宠物医院管理系统:从零到一构建多角色业务中台【源码剖析】

1. 为什么选择SpringBootVUE开发宠物医院管理系统 宠物医疗行业近年来发展迅猛&#xff0c;传统的纸质化管理方式已经无法满足现代化宠物医院的需求。我去年为本地一家连锁宠物医院开发管理系统时&#xff0c;就深刻体会到SpringBootVUE技术栈的优越性。这套组合拳不仅能快速搭…...

SenseVoice-small部署教程:ONNX量化版WebUI保姆级实战指南

SenseVoice-small部署教程&#xff1a;ONNX量化版WebUI保姆级实战指南 1. 引言&#xff1a;为什么你需要一个本地化的语音识别工具&#xff1f; 想象一下&#xff0c;你正在参加一个重要的线上会议&#xff0c;需要实时生成字幕&#xff0c;但网络信号时好时坏&#xff0c;云…...

Flux.1-Dev深海幻境开发环境搭建:Git版本控制与协作指南

Flux.1-Dev深海幻境开发环境搭建&#xff1a;Git版本控制与协作指南 你是不是也遇到过这种情况&#xff1f;团队里几个人一起折腾一个AI生成项目&#xff0c;今天你改了下提示词&#xff0c;明天他调整了参数&#xff0c;结果没过几天&#xff0c;谁也说不清哪个版本的代码能生…...

嵌入式事件驱动+状态机轻量级框架设计

1. 嵌入式系统软件架构演进&#xff1a;从轮询到事件驱动状态机在资源受限的嵌入式系统中&#xff0c;软件架构的选择直接决定了系统的实时性、可维护性与可扩展性。早期单片机程序多采用简单的主循环轮询&#xff08;Polling&#xff09;模式&#xff1a;while(1)中依次检查各…...

Mirage Flow与STM32CubeMX集成开发:自动化代码生成与模型调用

Mirage Flow与STM32CubeMX集成开发&#xff1a;自动化代码生成与模型调用 最近在做一个智能家居的语音控制项目&#xff0c;需要在STM32单片机上跑一个简单的语音唤醒模型。一开始&#xff0c;光是硬件初始化、外设配置、内存管理这些底层代码就让我头疼不已&#xff0c;更别提…...

2025论文阅读-TSCMamba如何用“多视角”和“探戈舞步”提升分类精度?

Ahamed和Cheng - 2025 - TSCMamba Mamba meets multi-view learning for time series classification 论文&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S1566253525001526 代码&#xff1a;https://github.com/Atik-Ahamed/TSCMamba 什么是时间序列…...

c# 特性

1.c# 特性在 C# 中&#xff0c;特性 (Attributes) 是一种强大的机制&#xff0c;允许你将元数据&#xff08;Metadata&#xff09;声明性地附加到代码元素上&#xff08;如类、方法、属性、参数、程序集等&#xff09;。这些元数据可以在运行时通过反射 (Reflection) 读取&…...

G-Helper轻量级硬件调控工具:让华硕笔记本性能释放更简单

G-Helper轻量级硬件调控工具&#xff1a;让华硕笔记本性能释放更简单 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目…...

OpenClaw核心内容总结

目录 一、OpenClaw 是什么 二、核心概念与架构 1. 基础核心机制 2. 架构与核心组件 三、安装与基础配置 1. 环境要求与安装 2. 初始化配置 四、进阶配置 1. 模型接入与切换 2. 接入飞书&#xff08;国内推荐&#xff09; 3. 安装技能&#xff08;Skills&#xff09; …...