本篇文章干货较多,建议收藏!


从 vue2 升级到 vue3,vue3 是可以兼容 vue2 的,所以 vue3 可以采用 vue2 的选项式API。由于选项式API一个变量存在于多处,如果出现问题时,就需要去多个函数内检查,项目较大时,遇到问题,增加排故的难度。所以 vue3 中新增了 setup 配置项,用它来写组合式API。

一、选项式API 和 组合式API 区别

有些同学稀里糊涂用了vue一年了,竟然不知道选项式api !你是那个同学吗?是的话,赶紧收藏起来。

vue2 中的 Options API 就是选项式api,一个中文,一个英文,怎么叫都可以。

在一个 vue 文件内,会有 data、methods、mounted、computed、watch 等等用来定义属性和方法,共同来处理页面逻辑,我们把这种方式称为 Options API。

示例1:计数器

<template>
<div>
<button @click="add">+</button>
{{num}}
<button @click="reduce">-</button>
</div>
</template>
<script>
export default {
data(){
return {
num:0
}
},
methods:{
add(){
this.num++
},
reduce(){
this.num--
}
}
}
</script>

观察上述示例,我们发现 num 值的处理涉及到 data 和 methods 两个选项,业务处理的比较分散,项目小了看着清晰明了,但是项目变大之后,data 和 methods会包含很多属性和方法,此时就很难分清哪个属性对应哪个方法。所以 vue3 新增 setup 写组合式API。

Vue3 的 Composition API 就是组合式api。

组合式api 就是一个功能所定义的 api 会放在一起,这样子即使项目变大,功能增大,我们能够很快找到功能相关的所有api,不像 Options API 功能分散,需要改动时,需要多处查找过程比较困难。

示例2:计数器

<template>
<div>
<button @click="add">+</button>
{{num}}
<button @click="reduce">-</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default{
setup(){
const num = ref(1)
return{
num,
add(){
num.value++
},
reduce(){
num.value--
}
}
}
}
</script>

ref 是让基础数据类型具备响应式的,下篇文章具体介绍它的用法,需要的同学可以点个关注不迷路!

用一张图告诉你它们的区别:

二、setup 具体怎么用?

2.1、setup 什么时候执行?

setup 用来写组合式 api,从生命周期钩子函数角度分析,相当于取代了 beforeCreate 。会在 creted 之前执行。

<script>
export default{
created(){
console.log('created');
},
setup(){
console.log('setup');
}
}
</script>

执行之后,setup 打印结果始终在前边。

2.2、setup 数据和方法如何使用?

示例3:直接定义使用变量

<template>
{{a}}
</template>
<script>
export default{
setup(){
const a = 0
}
}
</script>

运行后发现结果异常:
runtime-core.esm-bundler.js?5c40:6584 [Vue warn]: Property "a" was accessed during render but is not defined on instance.

提示我们访问的属性 a 并没有挂载到实例上。

setup 内部的属性和方法,必须 return 暴露出来,将属性挂载到实例上,否则没有办法使用,上述代码添加 return:

<script>
export default{
setup(){
const a = 0
return{
a
}
}
}
</script>

2.3、setup 内部有 this 吗?

自己在 setup 中打印下 this ,返回结果 是undefined 。说明在 setup 内部是不存在 this ,不能挂载 this 相关的东西。

2.4、setup 内钩子函数如何使用?

vue3 是可以兼容 vue2 的选项式写法,所以 钩子函数可以与 setup 并列存在,就相当于 Options API。

示例4:

export default{
setup(){
console.log('setup');
},
mounted(){
console.log('mounted');
}
}

vue3 新增的 setup() 函数用来写组合式 api,所以不建议这样写代码。所以需要使用 onXXX 一族的函数来注册钩子函数,注册成功之后调用时传递的是一个回调函数。

示例5:

import { onMounted } from "vue";
export default{
setup(){
const a = 0
return{
a
},
onMounted(()=>{
console.log("执行");
})
}
}

注册的这些生命周期钩子函数只能在 setup 期间同步使用,因为它们依赖全局内部状态来定位当前组件实例,不在当前组件下调用函数时会抛出错误。

其他的钩子函数是一样的,根据需要引入就好了。

2.5、setup与钩子函数关系

setup 与钩子函数并列时,setup 不能调用生命周期相关函数,但生命周期可以调用 setup 相关的属性和方法。

示例6:

<template>
<button @click="log">点我</button>
</template>
<script>
export default{
setup(){
const a = 0
return{
a
}
},
methods:{
log(){
console.log( this.$options.setup() );//返回一个对象
}
}
}
</script>

this.$options.setup() 返回的是一个大对象,该对象内包含了 setup 内的所有属性和方法。

三、setup 参数

使用setup 时,它将接收两个参数:props 和 context 。

3.1、props

第一个参数是 props ,表示父组件给子组件传值,props 是响应式的,当传入新的 props 时,自动更新。

示例7:

export default{
props: {
msg: String,
ans: String,
},
setup(props,context){
console.log(props);//Proxy {msg: "着急找对象", ans: "你有对象吗?"}
},
}

因为 props 是响应式的,不能使用 ES6 解构,会消除prop的响应特性,此时需要借用 toRefs 解构。示例8:

import { toRefs } from "vue";
export default{
props: {
msg: String,
ans: String,
},
setup(props,context){
console.log(props);
const { msg,ans } = toRefs(props)
console.log(msg.value); //着急找对象
console.log(ans.value); //你有对象吗?
},
}

使用组件时,经常会遇到可选参时,有些地方需要传递某个值,有些时候不需要,该如何处理呢?

如果 ans 是一个可选参数,则传入 props 中可能没有 ans 。在这种情况下 toRefs 将不会为 ans 创建一个 ref ,需要使用 toRef 代替它。

import { toRef } from "vue";
setup(props,context){
let ans = toRef(props ,'ans')// 不存在时,创建一个ans
console.log(ans.value);
}

3.2、context

context 上下文环境,其中包含了 属性、插槽、自定义事件三部分。

setup(props,context){
const { attrs,slots,emit } = context
// attrs 获取组件传递过来的属性值,
// slots 组件内的插槽
// emit 自定义事件 子组件
}

attrs 是一个非响应式对象,主要接收 no-props 属性,经常用来传递一些样式属性。

slots 是一个 proxy 对象,其中 slots.default() 获取到的是一个数组,数组长度由组件的插槽决定,数组内是插槽内容。

setup 内不存在this,所以 emit 用来替换 之前 this.$emit 的,用于子传父时,自定义事件触发。

示例9:

<template>
<div :style="attrs.style">
<slot></slot>
<slot name="hh"></slot>
<button @click="emit('getVal','传递值')">子向父传值</button>
</div>
</template>
<script>
import { toRefs,toRef } from "vue";
export default{
setup(props,context){
const { attrs,slots,emit } = context
// attrs 获取组件传递过来 style 属性
console.log('slots',slots.default());//插槽数组
console.log('插槽属性',slots.default()[1].props); //获取插槽的属性
return{
attrs,
emit
}
},
}
</script>

四、setup 特性总结

1、这个函数会在 created 之前执行,上述已解释。

2、setup 内部没有 this,不能挂载 this 相关的东西。

3、setup 内部的属性和方法,必须 return 暴漏出来,否则没有办法使用。

4、setup 内部数据不是响应式的。

5、setup不能调用生命周期相关函数,但生命周期函数可以调用setup内的函数。

vue3 学习笔记 (四)——vue3 setup() 高级用法的更多相关文章

  1. vue3 学习笔记(九)——script setup 语法糖用了才知道有多爽

    刚开始使用 script setup 语法糖的时候,编辑器会提示这是一个实验属性,要使用的话,需要固定 vue 版本. 在 6 月底,该提案被正式定稿,在 v3.1.3 的版本上,继续使用但仍会有实验 ...

  2. vue3 学习笔记 (五)——vue3 的 setup 如何实现响应式功能?

    setup 是用来写组合式 api ,内部的数据和方法需要通过 return 之后,模板才能使用.在之前 vue2 中,data 返回的数据,可以直接进行双向绑定使用,如果我们把 setup 中数据类 ...

  3. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  4. redis学习笔记(详细)——高级篇

    redis学习笔记(详细)--初级篇 redis学习笔记(详细)--高级篇 redis配置文件介绍 linux环境下配置大于编程 redis 的配置文件位于 Redis 安装目录下,文件名为 redi ...

  5. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  6. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  7. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  8. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  9. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

随机推荐

  1. 100台机器上海量IP如何查找出现频率 Top 100?

    场景题 有 100 机器,每个机器的磁盘特别大,磁盘大小为 1T,但是内存大小只有 4G,现在每台机器上都产生了很多 ip 日志文件,每个文件假设有50G,那么如果计算出这 100 太机器上访问量最多 ...

  2. 实现js读取Excel数据

    如何通过js去读取excel中的数据 <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  3. 6.堆和GC

    一. 堆和GC介绍 1.java堆的特点 <深入理解java虚拟机>是怎么描述java堆的 Java堆(Java Heap)是java虚拟机所管理的内存中最大的一块 java堆被所有线程共 ...

  4. 洛谷4299首都(LCT维护动态重心+子树信息)

    这个题目很有意思 QWQ 根据题目描述,我们可以知道,首都就是所谓的树的重心,那么我们假设每颗树的重心都是\(root\)的话,对于每次询问,我们只需要\(findroot(x)\)就可以. 那么如何 ...

  5. Python - faker

    安装 faker pip install Faker pip install Dumper 设置生成器 from faker import Faker fake = Faker() 它可以通过访问以想 ...

  6. PTA实验4-2-3 验证“哥德巴赫猜想” (20分)

    实验4-2-3 验证"哥德巴赫猜想" (20分) 数学领域著名的"哥德巴赫猜想"的大致意思是:任何一个大于2的偶数总能表示为两个素数之和.比如:24=5+19, ...

  7. flask操作(增删改查操作)

    增加数据 from .models import Goods from app.extensions import db goods1 = Goods(name='魅族18s', price=3400 ...

  8. TCC分布式事务的实现原理

    目录 一.写在前面 二.业务场景介绍 三.进一步思考 四.落地实现TCC分布式事务 (1)TCC实现阶段一:Try (2)TCC实现阶段二:Confirm (3)TCC实现阶段三:Cancel 五.总 ...

  9. 【UE4】GAMES101 图形学作业5:光线与物体相交(球、三角面)

    总览 在这部分的课程中,我们将专注于使用光线追踪来渲染图像.在光线追踪中最重要的操作之一就是找到光线与物体的交点.一旦找到光线与物体的交点,就可以执行着色并返回像素颜色. 在这次作业中,我们要实现两个 ...

  10. 第二次Scrum Metting

    日期:2021年4月25日会议主要内容概述:前后端针对WebAPI进行协调与统一工作,商量接下来两日计划:敲定部分设计细节. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中 ...