0


【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的旅程:

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Vue 3 Hello World</title></head><body><divid="app">{{ message }}</div><scriptsrc="https://unpkg.com/[email protected]"></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安装:

npminstall-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
npminstall
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

开头,例如

onMounted

onUpdated

onUnmounted

等。

示例代码:

<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

更加直接,尤其是在处理复杂对象时。

对比
ref

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

ref

是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';exportdefault{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>

在模板中,你可以直接使用

count

message

,就像它们是使用

ref

创建的响应式引用一样。这保证了即使在结构分解后,你依然可以保持组件的响应性。

toRefs

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

使用

toRefs

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

reactive

对象的部分属性时非常有用。

到目前为止,我们已经讨论了Vue 3的组合式API中的基本响应式API——

ref

reactive

toRefs

。这些工具为开发复杂组件提供了灵活性和强大的状态管理能力。

接下来,我们将进一步探讨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

对象

person

firstName

lastName

。当

person

的属性改变时,

fullName

会自动更新。

2. 高级用法
computed

也支持一个带有

get

set

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

示例代码:

<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.firstName

person.lastName

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

接下来,我们将探讨Vue 3中的侦听器(

watch

watchEffect

),它们提供了一种方法来响应数据的变化。

九、Watch监听

Vue 3的组合式API提供了

watch

watchEffect

两种方式来侦听响应式数据的变化,并执行相应的副作用。这两种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>
watch

watchEffect

提供了灵活且强大的方式来对响应式数据的变化作出反应,它们是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>

在这个例子中,父组件通过

message

prop向

ChildComponent

传递了一个字符串。

2. 子传父 - 自定义事件

子组件可以通过触发事件来向父组件传递信息。Vue 3中,使用

$emit

方法触发事件已被废弃,推荐使用

defineEmits

context.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-model

v-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-if

v-else-if

v-else

的使用

这一系列的指令在Vue 3中保持不变,用于条件渲染。

v-if

v-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改进,包括

Teleport

Suspense

以及对Composition API的进一步增强。

十二、Vue 3中的TypeScript支持

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

类型增强

Vue 3利用Composition API提供了更好的类型推断。当你使用

ref

reactive

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

示例代码:

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

在这个例子中,我们明确声明了

count

是一个数字类型的响应式引用(

Ref<number>

)。这种类型声明让TypeScript能够提供准确的类型检查和代码提示。

使用
defineComponent

进行类型推断

Vue 3推荐使用

defineComponent

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

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

通过

defineComponent

,Vue 3可以准确地推断

props

data

computed

等选项的类型,大大提高了开发体验。

十三 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插槽中使用骨架屏,提供更加丰富和直观的加载状态反馈,进一步提升用户体验。


本文转载自: https://blog.csdn.net/wanghaoyingand/article/details/137272537
版权归原作者 接着奏乐接着舞。 所有, 如有侵权,请联系我们删除。

“【2024最新】vue3的基本使用(超详细)”的评论:

还没有评论