当前位置: 首页 > 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项目往往需要处理大量数…...

`require`与`import`的区别

require与import的区别主要体现在以下几个方面&#xff1a; 1.加载时间不同。require是在运行时加载模块&#xff0c;这意味着模块的加载和执行可以在代码的任何地方进行&#xff0c;也可以在运行时根据条件动态地加载不同的模块&#xff1b;import是在编译时加载模块&#xf…...

中介者模式:优雅解耦的利器

在软件设计中&#xff0c;随着系统功能的不断扩展&#xff0c;对象之间的依赖关系往往会变得错综复杂&#xff0c;导致系统难以维护和扩展。为了降低对象之间的耦合度&#xff0c;提高系统的可维护性和可扩展性&#xff0c;设计模式应运而生。中介者模式&#xff08;Mediator P…...

Ubuntu20.04安装MatlabR2018a

一、安装包 安装包下载链接 提取码&#xff1a;kve2 网上相关教程很多&#xff0c;此处仅作为安装软件记录&#xff0c;方便后续软件重装&#xff0c;大家按需取用。 二、安装 1. 相关文件一览 下载并解压文件后&#xff0c;如下图所示&#xff1a; 2. 挂载镜像并安装 2…...

基于SpringBoot的图书馆管理系统设计与实现

介绍 基于&#xff1a;java8 SpringBoot thymeleaf MySQL8.0.17 mybatis-plus maven Xadmin 实现图书馆管理系统 系统要实现如下的基本管理功能&#xff1a; &#xff08;1&#xff09;用户分为两类&#xff1a;管理员&#xff0c;一般用户。 &#xff08;2&#xff09…...

网易云首页单页面html+css

网页设计与网站建设作业htmlcss 预览 源码查看https://hpc.baicaitang.cn/2083.html...

acwing算法提高之图论--最小生成树的典型应用

目录 1 介绍2 训练 1 介绍 本专题用来记录使用prim算法或kruskal算法求解的题目。 2 训练 题目1&#xff1a;1140最短网络 C代码如下&#xff0c; #include <iostream> #include <cstring>using namespace std;const int N 110, INF 0x3f3f3f3f; int g[N][N…...

springcloud基本使用二(远程调用)

创建两个springboot maven子项目 子项目名称分别为order-server和user-server 配置user-server子项目: 所需依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependenc…...

代码随想录刷题day42| 01背包理论基础分割等和子集

文章目录 day41学习内容一、 01背包之二维数组解法1.1、什么是01背包1.2、动态规划五部曲1.2.1、 确定dp数组&#xff08;dp table&#xff09;以及下标的含义1.2.2、确定递推公式1.2.3、 dp数组如何初始化1.2.4、确定遍历顺序1.2.5、计算并返回最终结果 二、 01背包之一维数组…...

Python文件操作命令

文件操作 我知道你最近很累&#xff0c;是那种看不见的、身体上和精神上的疲惫感&#xff0c;但是请你一定要坚持下去。就算无人问津也好&#xff0c;技不如人也好&#xff0c;千万别让烦躁和焦虑毁了你的热情和定力。别贪心&#xff0c;我们不可能什么都有&#xff0c;也别灰心…...

CSS面试题---基础

1、css选择器及优先级 选择器优先级&#xff1a;内联样式>id选择器>类选择器、属性选择器、伪类选择器>标签选择器、微元素选择器 注意&#xff1a; !important优先级最高&#xff1b; 如果优先级相同&#xff0c;则最后出现的样式生效&#xff1b; 继承得到的样式优先…...

用c做网站/百度推广怎么做免费

近几年以来&#xff0c;Python 的应用场景越来越多&#xff0c;几乎可以应用于自然科学、工程技术、金融、通信和商业等各种领域。究其原因在于 Python 的简单易学、功能强大。 想系统地学点东西&#xff0c;发现很多不错的技术文档都是英文资料&#xff0c;发现英文竟然成为了…...

wordpress建设的是模板网站吗/网站seo排名优化工具

idle connect ( 已经建立完成了TCP三次握手 ) open sent open confirm establish connect 和 active 都是 TCP 连接阶段, active 是发起方, connect 是应答方 Idle State 1 BGP 通常以 Idle State 开始( 此时拒绝接收所有入连接 )。当一个开始事件出现, BGP 过程初始化所…...

安徽建设通网站/seo网站结构优化的方法

http://video.jessetalk.cn/转载于:https://www.cnblogs.com/lkd3063601/p/8547733.html...

wordpress网站攻击/seo比较好的公司

Windows下修改Android手机的hosts 1.首先&#xff0c;手机是Root过的。 2.连接手机和电脑&#xff0c;adb shell 进入命令行。3.获取root用户权限&#xff1a;su -root4.不知道为何不能直接修改/etc/hosts的内容&#xff0c;所以修改的是/system/hosts的内容&#xff0c;/etc/h…...

怎么做网站建设的ppt/网站都有哪些

最近重新学习数据结构和算法&#xff0c;刚刚看完java版的这几个数据结构&#xff0c;比较浅显易懂&#xff0c;有兴趣的可以自己去调试学习&#xff0c;关于这几个的介绍网上很多。 二叉搜索树&#xff0c;比较简单的树结构了 package com.jwetherell.algorithms.data_structu…...

下拉框代码自做生成网站/百度智能小程序怎么优化排名

一直非常喜欢Bootstrap的按钮风格&#xff0c;仿照Bootstrap做了一套按钮。在ie6/7/8/9/10/11、chrome、firefox下能正常使用。ie6/7/8不支持css3的样式。按钮在这些模式下没有圆角效果。在ie6/7下使用button标签能显示正常效果&#xff0c;使用其它标签存在文字偏移和背景显示…...