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


从 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. nvidia jetson xavier 风扇开机自启动

    作者声明 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 原文链接:https://www.cnblogs.com/phoenixash/p/15 ...

  2. 一个关于MySQL指定编码实现的小坑

    写在前面 环境:MySQL5.7+,MySQL数据库字符编码实现为utf8,表也为utf8 场景:微信授权获取用户信息(包括昵称)并保存到数据库,有的用户成功了,少数用户却失败了 那么为什么会失败呢? ...

  3. 分片利器 AutoTable:为用户带来「管家式」分片配置体验

    在<DistSQL:像数据库一样使用 Apache ShardingSphere>一文中,Committer 孟浩然为大家介绍了 DistSQL 的设计初衷和语法体系,并通过实战操作展示了 ...

  4. Longhorn 云原生容器分布式存储 - 故障排除指南

    内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生容器分布式存储 - 设计架构和概念 Longhorn 云原生容器分布式存储 - ...

  5. PHP文件上传漏洞与一句话木马

    靶子代码: 前端效果: 这是个没有任何防护的文件上传代码,同时还热心的附上了上传文件的路径. 我们写好php木马后,什么额外工作也不需要做,直接上传就行了.上传后在浏览器里访问该文件,其就会被执行. ...

  6. 整数划分为k份

    题目 将整数n分成k份,且每份不能为空,任意两个方案不能相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是相同的. 1,1,5; 1,5,1; 5,1,1; 问有多少种不同的分法. 输入 ...

  7. UltraSoft - Alpha - Scrum Meeting 2

    Date: Apr 09th, 2020. 会议内容为完成初步的任务分工. Scrum 情况汇报 进度情况 组员 负责 昨日进度 后两日任务 CookieLau PM.后端 继续Django tuto ...

  8. 基于websocket实现的一个简单的聊天室

    本文是基于websocket写的一个简单的聊天室的例子,可以实现简单的群聊和私聊.是基于websocket的注解方式编写的.(有一个小的缺陷,如果用户名是中文,会乱码,不知如何处理,如有人知道,请告知 ...

  9. 字符串匹配(kmp+trie+aho-corasic automaton+fail tree)

    目录 kmp 那么怎么快速求最长前缀后缀呢 trie aho-corasic automaton fail tree kmp 对于一个字符串\(s_{0\dots n}\),称\(s_{0\dots ...

  10. 如何清理history

    工作中,需要清理history 清理当前会话历史命令    history -c 清理当前用户所有历史命令     echo > .bash_history     #在用户主目录执行此操作