欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > Vue3教程 - 4 Vue3的API

Vue3教程 - 4 Vue3的API

2025/2/22 16:33:28 来源:https://blog.csdn.net/Satur6ay/article/details/142865401  浏览:    关键词:Vue3教程 - 4 Vue3的API

更好的阅读体验:点这里 ( www.foooor.com

4 Vue3的API

4.1 Vue2和Vue3的API风格

通过前面的 HelloWorld 程序,你如果学习过 Vue2,会发现 Vue3 的 API 和 Vue2 的区别很大。

Vue2 中的称为选项式 API (Options API):

<!-- Vue2 -->
<script>
export default {data() {  // 组件中用到的数据return {count: 0}},methods: {  // 组件中用到的方法increment() {this.count++}},watch:{},  // 监听器computed:{}  // 计算属性
}
</script>

组件中的 datamethodswatchcomputed 相当于一个个选项,选项式 API 可能会存在的问题是,一个功能的实现可能分布在多个选项中,不够集中,如果要修改就要分别修改多个选项,所以不易维护。

在 Vue3 中的称为组合式 API (Composition API),后面我们将以这种方式来学习,其实在 Vue3 中也是可以以选项式 API 来编程的,也就是 Vue3 是兼容 Vue2 的语法。

在 HelloWorld 中使用了 setup 选项,setup 选项的执行时机是很早的,比组件生命周期函数 beforeCreate 还要早(生命周期后面再讲),所以在 Vue2 的选项式 API 中是可以获取到 setup 返回的信息的,但是 setup 中无法获取 Vue2 选项中的数据。

举个栗子:

如果你有 Vue2 的基础,肯定能看得懂下面的代码;如果你没有 Vue2 的基础,也没有关系,这里是一个比较,后面我们还是以 Vue3 中的组合式 API 进行学习,但是老的项目肯定是 Vue2 的,如果有时间,可以多了解一些。

看一下下面的代码,在 Vue2 的选项式 API 中获取 Vue3 组合式 API 中的数据:

<template><!-- 结构 --><div class="my-app"><button @click="printMsg">打印msg</button></div>
</template><script lang="ts">// 脚本export default {name: "App",methods: {printMsg() {console.log(this.msg);  // 通过this.name获取}},setup() {let msg = "Hello world";return {"msg": msg,}}}
</script>

4.2 setup

前面 HelloWorld 中已经使用了 setup, 它是 Vue3 中新的配置项,它的值是一个函数,在 Vue3 中,组件的数据、方法、计算属性、监视器等等,都配置在 setup 中。

setup 主要有以下特点,前面也介绍了几个:

  • setup 函数返回的对象,可以直接在<template>模板中使用;
  • setup 函数会在 beforeCreate 之前执行,也就是在所有的生命周期回调函数之前执行;
  • setup 函数中是没有 this 的,这个和 Vue2 中的有区别;

下面来实现一个功能,点击页面的按钮,计数+1。

代码如下:

<template><!-- 结构 --><div class="my-app"><div>{{ count }}</div><button @click="increment">增加</button></div>
</template><script lang="ts">import { ref } from 'vue'// 脚本export default {name: "App",setup() {// 响应式状态const count = ref(0)// 用来修改状态、触发更新的函数function increment() {count.value++}return {count, increment}}}
</script>

在上面的代码中:

  • const count = ref(0) 定义一个响应式变量 count,初始值为 0。count 实际上是一个对象,这个对象内部有一个.value属性,它持有实际的数值(在这个例子中是0)。
  • 在 setup 中将 countincrement() 函数返回,这样就可以在 HTML 模板中使用它们了。
  • 在模板中,通过差值表达式 {{ count }} 读取到 count 的值,通过 @click 给元素绑定事件(后面再讲),当点击按钮时,调用 increment 函数,修改 count 的值,count 是响应式变量,修改 count 的值,页面会自动渲染。

通过上面的代码可以看到,使用响应式编程,我们不用去获取和操作 DOM 元素,只需要修改数据,就可以实现页面的自动渲染,和传统的前端开发相比,非常的方便。

4.3 setup语法糖

在前面使用 setup 的时候,需要将模板中使用的变量和方法返回,这样会很麻烦,因为不小心就忘掉了。

针对这种情况,可以使用 setup 语法糖。

需要单独使用一个 <script> 标签, 举个栗子:

<template><!-- 结构 --><div class="my-app"><div>{{ count }}</div><button @click="increment">增加</button></div>
</template><script lang="ts">// 脚本export default {name: "App"}
</script><!-- setup -->
<script lang="ts" setup>
import { ref } from 'vue'// 响应式状态
const count = ref(0)// 用来修改状态、触发更新的函数
function increment() {count.value++
}
</script>

在上面的代码中,只是将 setup 中的内容放到了一个新的 <script> 标签中,这个标签的类型需要和之前的类型一致 lang="ts" 并添加 setup 属性。setup 的 <script> 标签中变量和方法自动返回。


但是上面有两个 <script> 标签,显得很冗余啊,可以将第一个标签删掉:

<template><!-- 结构 --><div class="my-app"><div>{{ count }}</div><button @click="increment">增加</button></div>
</template><!-- setup -->
<script lang="ts" setup>
import { ref } from 'vue'// 响应式状态
const count = ref(0)// 用来修改状态、触发更新的函数
function increment() {count.value++
}
</script>

删掉以后,是可以正常工作的,但是删掉以后,组件的名称没有办法定义了,组件的名称默认就是文件的名称,也就是 App.vueApp 。正常情况下,这是没问题的。


但是非得要自定义名称,或者不同模块有相同的 .vue 文件,就会出现问题,导致组件名称相同,所以如何定义组件名称呢?

需要借助 vite-plugin-vue-setup-extend 插件,首先安装插件

# 安装插件
npm install -D vite-plugin-vue-setup-extend 

然后在项目的 vite.config.ts 文件中添加配置:

import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 1. 导入
import VueSetupExtend from 'vite-plugin-vue-setup-extend'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),// 2. 调用VueSetupExtend()],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}}
})

导入并调用插件。

最后在 <script> 标签上添加 name 属性:

<!-- setup -->
<script lang="ts" setup name="App123">
// ...略
</script>

通过浏览器开发者工具就可以看到组件的名称了:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.4 ref

在 Vue2 中,只需要将数据放在 data(){} 中,就可以实现响应式数据。

在 Vue3 中需要使用 refreactive (待会再讲)来创建响应式数据。

使用 ref 来创建基本类型对象类型的响应式数据,如果你想让哪个数据是响应式数据,使用 ref 包裹一下。

举个栗子:

创建基本类型的响应式数据。

<template><div>{{ name }}</div><div>{{ age }}</div><div>{{ phoneNumber }}</div><div><button @click="changeName">修改姓名</button><button @click="changeAge">修改年龄</button></div></template><!-- setup --><script lang="ts" setup>import { ref } from 'vue'let name = ref("doubi");  // 使用ref创建响应式数据let age = ref(13);  // 使用ref创建响应式数据let phoneNumber = "137xxxxxxxx";  // 不需要变化,则不需要ref// 修改姓名function changeName() {name.value = "niubi";}// 修改年龄function changeAge() {age.value = 14;}</script>

创建对象类型的响应式数据,一样的用法:

<template><div> {{ person.name }} - {{ person.age }}</div><div><button @click="changePerson">修改Person</button></div>
</template><!-- setup -->
<script lang="ts" setup>
import { ref } from 'vue'// 对讲对象类型的响应式数据
let person = ref({"name": "doubi", "age": 13, "phoneNumber": "137xxxxxxxx"})// 修改person
function changePerson() {person.value.name = "niubi"person.value.age = 15
}
</script>

在上面的代码中,使用 ref 创建响应式的数据,ref 将实际的数据包裹起来,实际变成了一个新的对象。

注意:在代码中修改的时候,修改的是 变量.value 的值,但是在模板中引用的时候,引用的是变量的名称,不需要 .value


如果觉得每次首先 .value 很麻烦,可以通过插件自动添加。

点击 VSCode 左下角的设置按钮 -> 设置 -> 扩展 -> Vue -> Auto Insert:Dot Value

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

勾选配置后,每次写响应式扩展名,会自动补全 .value

4.5 reactive

reactive 只能用来定义对象类型(数组、函数等都是对象)的响应式数据。

用法和上面使用 ref 一样,将对象包裹起来就可以。

举个栗子:

<template><div>{{ person.name }}</div><div>{{ person.age }}</div><div><button @click="changeName">修改姓名</button><button @click="changeAge">修改年龄</button></div>
</template><!-- setup -->
<script lang="ts" setup>
import { reactive } from 'vue'  // 1.引入reactive// 2.通过reactive定义响应式数据
let person = reactive({"name": "doubi", "age": 13})// 修改姓名
function changeName() {person.name = "niubi"
}// 修改年龄
function changeAge() {person.age = 14;
}
</script>

在上面的代码中,使用 reactive 将对象包裹起来,此时打印 person 变成了 Proxy 代理的对象。

其实 ref 在创建对象类型的响应式数据的时候,底层使用的也是 reactive

这样修改对象的数据,就可以让 Vue 重新渲染页面了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


在使用 reactive 的时候,有一个地方需要注意,就是重新分配一个新对象,会失去响应式。

举个栗子:

下面的 person 在创建的时候是响应式数据,如果重新给 person 赋值,会失去响应式。

<template><div> {{ person.name }} - {{ person.age }}</div><div><button @click="changePerson">修改Person</button></div>
</template><!-- setup -->
<script lang="ts" setup>
import { reactive } from 'vue'// 对讲对象类型的响应式数据
let person = reactive({ "name": "doubi", "age": 13, "phoneNumber": "137xxxxxxxx" })// 修改person
function changePerson() {// 页面不更新,不是响应式数据// person = {"name": "niubi", "age": 15, "phoneNumber": "137xxxxxxxx"}// 页面也不行,也是不可以的// person = reactive({"name": "niubi", "age": 15, "phoneNumber": "186xxxxxxxx"})// 需要单独修改person的属性,但是如果有很多的属性,依次赋值就很麻烦// person.name = "niubi"// 可以使用assign函数,将一个对象的属性赋值给另一个对象let newPerson = { "name": "niubi", "age": 15, "phoneNumber": "137xxxxxxxx" }Object.assign(person, newPerson)  // 将newPerson的属性赋值给person
}
</script>

所以需要使用 Object.assign 来进行属性赋值。

如果使用的是 ref ,就可以这个问题,应为直接是给 value 赋值:

// 使用ref,是给.value赋值,不是失去响应式
person.value = { "name": "niubi", "age": 15, "phoneNumber": "137xxxxxxxx" }

后面在创建响应式数据的时候,如果是基本数据类型,使用 ref,对象类型使用 refreactive 都可以。

4.6 toRefs和toRef

在 Vue 3 中,toRefstoRef 是两个用于响应式转换的 API,它们提供了将对象或对象的某个属性转换为响应式引用(refs)的方法。

1 toRefs

toRefs 用于将一个响应式对象的所有属性转换为响应式引用(refs),可以帮助我们解构响应式对象时保持其响应性。

举个例子,先查看一下下面的代码:

下面的代码将响应式对象 person 结构赋值给变量。

<template><div> {{ person.name }} </div><div> {{ person.age }} </div><div> {{ name }} </div><div> {{ age }} </div><div><button @click="changePerson">修改Person</button><button @click="changeNameAndAge">修改name和age</button></div>
</template><!-- setup -->
<script lang="ts" setup>
import { reactive } from 'vue'// 对讲对象类型的响应式数据
let person = reactive({ "name": "doubi", "age": 13})// 结构对象给变量赋值!!!
let {name, age} = person// 修改person
function changePerson() {person.name = "niubi"person.age = 15
}function changeNameAndAge() {name = "niubi"age = 15
}</script>

此时 name 和 age 变量不是响应式变量了,修改 person 对象和修改变量本身,页面都不会有响应。

此时可以使用 toRefs,将结构的属性变成响应式变量。

举个栗子:

<template><div> {{ person.name }} </div><div> {{ person.age }} </div><div> {{ name }} </div><div> {{ age }} </div><div><button @click="changePerson">修改Person</button><button @click="changeNameAndAge">修改name和age</button></div>
</template><!-- setup -->
<script lang="ts" setup>
import { reactive, toRefs } from 'vue'// 对讲对象类型的响应式数据
let person = reactive({ "name": "doubi", "age": 13})// 结构对象给变量赋值
let {name, age} = toRefs(person)  // 转换为响应式变量// 修改person
function changePerson() {person.name = "niubi"person.age = 15
}function changeNameAndAge() {name.value = "niubi"  // 修改为.valueage.value = 15
}</script>

此时修改 person 对象还是 name 和 age 变量,person 的数据还是 name 和 age 变量都会同步变化。

通过 toRefs 的转换,不只是person对象,person 对象中的属性都变成了响应式对象

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2 toRef

toRef 和 toRefs 功能是一样的,只是用来将对象的单个属性的响应式对象。

// 将person对象的name属性转换为响应式对象
let name = toRef(person, "name") 

举个栗子:

<template><div> {{ person.name }} </div><div> {{ name }} </div><div><button @click="changePerson">修改Person</button><button @click="changeNameAndAge">修改name和age</button></div>
</template><!-- setup -->
<script lang="ts" setup>
import { reactive, toRef } from 'vue'// 对讲对象类型的响应式数据
let person = reactive({ "name": "doubi", "age": 13})// 将person对象的name属性转换为响应式对象
let name = toRef(person, "name")  // 修改person
function changePerson() {person.name = "niubi"
}function changeNameAndAge() {name.value = "niubi"  // 修改为.value
}</script>

平时可能 toRefs 用的多一些

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词