Vue3-拉开序幕的setup

Vue3 中的 setup 是一个新的配置项,值是一个函数。

export default {name: 'App',setup: function () {}
}
</script>

和 Vue2 中的 data 一样,我也可以将 setup 简写成为

export default {name: 'App',setup() {}
}

setup函数的使用

与 Vue2 不一样的是,setup 中包含了 data 数据,methods方法,computed计算属性,watch监听器等等一系列的属性,也就是说,在 Vue3 中,我们不会显式的把这些属性配置到 setup 中,而是直接将属性内部的数据或方法直接暴露在 setup 中

ps:本章所讲内容,不涉及响应式,也就是说 在 setup 中定义的数据,不是响应式的,如何转为响应式数据,下一章节 ref 会讲到。但是 props 传递的数据是响应式的。

setup() {// 类似于data属性中的数据,不过不用显式的声明data,而是直接设置变量let name = 'al'let age = 18// 类似于methods属性中的方法function hello() {// 因为这是直接在 setup 函数中访问变量,直接访问就行,不用 thisalert(`我的名字是${name},我的年龄是${age}`) }}

 setup 的参数

 setup 函数接收两个参数,分别是 props上下文 context

props 是响应式的数据,且在传入新的 props 时,会同步更新现有的 props。例如

export default {// 如果这里接收到的 props 改变了props: {title: String},// 那么这里的接使用的props也会同步改变setup(props) {console.log(props.title)}
}

同时需要注意的是,在使用props传递的数据时时,尽量采取 props.xxx的方式进行。

对于传递的 props尽量不要解构,因为解构得出的变量将会丢失响应式。如果确实需要解构,或者将 props中的某一项数据传递的同时保持响应式,可以采用 torefs 和 toref 来进行转化。

import { toRefs, toRef } from 'vue'export default {setup(props) {// 将 `props` 转为一个其中全是 ref 的对象,然后解构const { title } = toRefs(props)// `title` 是一个追踪着 `props.title` 的 refconsole.log(title.value)// 或者,将 `props` 的单个属性转为一个 refconst title = toRef(props, 'title')}
}

第二个参数则是上下文 context ,其中暴露了一些在setup 中可能会用到的值,例如:

export default {setup(props, context) {// 透传 Attributes(非响应式的对象,等价于 $attrs)console.log(context.attrs)// 插槽(非响应式的对象,等价于 $slots)console.log(context.slots)// 触发事件(函数,等价于 $emit)console.log(context.emit)// 暴露公共属性(函数)console.log(context.expose)}
}

这个 context 不是响应式的,可以直接解构,

export default {setup(props, { attrs, slots, emit, expose }) {...}
}

其中 attrs 和 slots 都是有状态的对象,会随着组件自身更新而更新,但是二者都不是响应式数据,所以在使用时,同样避免解构,而是尽量通过 attrs.x 或 slots.x 方式。如果想要基于 attrs 或 slots的改变来执行副作用,那么可以在 onBeforeUpdate 声明周期中编写逻辑。

emit则是用来触发函数,和 Vue2 中作用一致。

expose 的作用则是显式的限制向外暴露的属性。当父组件引用子组件时,只能访问到通过可 expose 暴露特定的方法。当 expose 不传递参数时,代表不暴露任何东西,当传递对象时,则有选择的暴露局部状态。

import { h, ref } from 'vue'export default {setup(props, { expose }) {const count = 0const increment = () => ++count.valueexpose({increment})return () => h('div', count.value)}
}

setup 的返回值

setup 存在两种返回值:

  1. 返回一个同步对象,对象中的属性、方法在模板中均可直接使用,例如
    export default {name: 'App',setup() {// 类似于data属性中的数据,不过不用显式的声明data,而是直接设置变量let name = 'al'let age = 18// 类似于methods属性中的方法function hello() {alert(`我的名字是${name},我的年龄是${age}`) }return {name,age,hello}}
    }
    <template><h1>我是app组件</h1><p>姓名:{{ name }}</p><p>年龄:{{ age }}</p><button @click="hello()">个人信息</button>
    </template>

  2. 返回一个渲染函数 ,可以自定义渲染内容(
    <script>
    import { h } from 'vue'
    export default {name: 'App',setup() {// 类似于data属性中的数据,不过不用显式的声明data,而是直接设置变量let name = 'al'let age = 18// Vue2 中的 main.js 中,在使用 render 函数时,就使用了 h 这个方法,// 第一个参数是节点,第二个参数是渲染内容// 当使用 返回 render 函数之后,html 模板中的内容都会被忽略,只会执行 h 函数的渲染内容return () => h('div','我改名字了')}
    }
    </script>

ps:返回一个渲染函数将会阻止我们返回其他东西。对于组件内部来说,这样没有问题,但如果我们想通过模板引用将这个组件的方法暴露给父组件,那就有问题了。因为此时除了渲染函数之外,暴露不了别的数据和方法了,为了解决这一问题,Vue3采用了 expose 来暴露方法或属性,然后返回渲染函数 

setup(props,{ expose }) {// 类似于data属性中的数据,不过不用显式的声明data,而是直接设置变量let name = 'al'let age = 18// 类似于methods属性中的方法function hello() {alert(`我的名字是${name},我的年龄是${age}`) }// 通过 expose 暴露方法或属性expose({name,hello})// Vue2 中的 main.js 中,在使用 render 函数时,就使用了 h 这个方法,// 第一个参数是节点,第二个参数是渲染内容// 当使用 返回 render 函数之后,html 模板中的内容都会被忽略,只会执行 h 函数的渲染内容return () => h('div','我改名字了')
}
}

 注意事项

1、Vue2 和 Vue3 不要混用。Vue3 是向下兼容的,所以即使是在 Vue3 项目中,也可以使用 Vue2 的语法,但是也会带来一些问题。

  1. 兼容性:在 Vue3 项目中也可以使用 Vue2 的写法
    <template><p>在Vue3中访问 Vue2 写法下的属性或方法</p><p>姓名:{{ newName }}</p><p>年龄:{{ newAge }}</p><button @click="getVue3Data">点击获取Vue2写法中的数据</button>
    </template><script>
    export default {name: 'App',data() {return {newName: '汤圆',newAge:1}},methods: { testVue2(){alert(`我的名字是${this.newName},我的年龄是${this.newAge}`)}},
    }
    </script>
    

2、Vue2 的配置项( data、methods、computed... )中可以访问 Vue3 中 setup 中的属性、方法

<button @click="testVue3">点击后再Vue2写法中获取Vue3写法中setup的数据</button><script>
export default {name: 'App',methods: { testVue3() {console.log(this.name);console.log(this.age);console.log(this.hello);}},setup() {// 类似于data属性中的数据,不过不用显式的声明data,而是直接设置变量let name = 'al'let age = 18// 类似于methods属性中的方法function hello() {alert(`我的名字是${name},我的年龄是${age}`) }return {name,age,hello}}
}
</script>

点击按钮之后,控制台上打印出了 Vue3 setup 中定义的变量和方法。

3、但是在 Vue3 中的setup 中调用 Vue2 声明的变量或方法时,会无法找到

setup() {// 类似于data属性中的数据,不过不用显式的声明data,而是直接设置变量let name = 'al'let age = 18// 类似于methods属性中的方法function hello() {alert(`我的名字是${name},我的年龄是${age}`) }function testVue4() {console.log(name);console.log(age);console.log(hello);// 因为这些属性或方法不是在 setup 内部定义的,而是按照Vue2 的配置语法定义的,所以按照Vue2的访问模式 通过 this.xxx 访问console.log(this.newName);console.log(this.newAge);console.log(this.testVue2);}return {name,age,hello,testVue4}
}

从这里可以看到,在 Vue3 的 setup 中访问 Vue2 中的方法或属性时,得到的是undefined,这是因为  setup() 自身并不含对组件实例的访问权,即在 setup() 中访问 this 会是 undefined。你可以在选项式 API 中访问组合式 API 暴露的值(在 Vue2 中访问 Vue3的属性或方法),但反过来则不行。

但是但是这里其实还存在一个问题,如果我直接在 setup 中访问 this,得到的是undefined,但是如果我是在 setup 中定义的函数中访问 this,得到的是一个 Proxy 代理对象

setup() {console.log(this, 'this111');function testVue4() {console.log(this,'this');console.log(this.newName);console.log(this.newAge);console.log(this.testVue2);}return {testVue4}
}

 首先说 直接在 setup 中访问 this,问什么会是undefined?这是因为setup函数执行时,不依赖于Vue实例,换句话说就是 setup 函数在Vue实例化之前就执行了,所以无法直接访问到this。

然后再说为什么setup 中的方法作为组件模板内容使用时(例如作为事件处理函数被调用时),那么Vue会将这个方法绑定到Vue实例上。当该函数被调用时,this指向的就是Vue组件实例。

也就是说 Vue3中无法在 setup 内部直接访问到 this,但是通过 return 出去的函数 或者绑定到模板的数据时可以访问到this。

4、如果 Vue2 和 Vue3 混用时,数据或方法出现重名情况,以 setup 中的数据优先

<template><p>{{ name }}</p><button @click="hello">点击查看</button>
</template><script>
export default {name: "App",data() {return {name: "aha",};},methods: {hello() {alert(`我的名字是${this.name}`);},},setup() {let name = "al";// 类似于methods属性中的方法function hello() {alert(`我的名字是${name}`) }return {// eslint-disable-next-line vue/no-dupe-keyshello,// eslint-disable-next-line vue/no-dupe-keysname,};},
};
</script>

5、setup() 应该同步地返回一个对象。唯一可以使用 async setup() 的情况是,该组件是 Suspense 组件的后裔。

具体理解就是 setup 在一般情况下,不能使用  async 包裹,因为被 async 包裹之后,即使你返回的还是原来的对象,但是 async 会对象外部包裹一层 Promise,如果想要拿取数据的话,还需要通过.then() 来获取 ,模板中时无法直接看到并且使用 return 对象中的属性或方法的。而 Vue 是不会自动帮你做这件事的。

但是 也存在一直特殊情况,那就是  该组件是 Suspense 组件的后裔( 这个后在讲,我现在也没研究到这里来 )。

总结 

 1、Vue2 和 Vue3 的配置尽量不要混用

2、如果混用了,

  • Vue2 中的配置 (例如:data、methods、compute、watch等)可以访问到 setup 中的属性和方法
  • Vue3 中的setup 不能访问到 Vue2 中的配置项
  • 存在重名情况,以 Vue3 setup 中优先

3、setup 一般不用  async,因为 setup 需要同步的返回一个对象,以此来保证 模板中数据或方法正常绑定,如果用了 async 那么返回的数据对象 会被 Promise 包裹,模板中无法看到对象中的属性,无法绑定。但是 当该组件是 Suspense 组件的后裔时,可以使用  async setup()

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/51226.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详细介绍MLP的原理

什么是MLP MLP&#xff08;Multi-Layer Perceptron&#xff09;&#xff0c;即多层感知机&#xff0c;是一种前馈型人工神经网络。它由一个输入层、一个输出层以及至少一个隐藏层&#xff08;输入层和输出层中间的层&#xff09;组成。每个神经元&#xff08;或称为节点&#x…

【Django】 js实现动态赋值、显示show隐藏hide效果

文章目录 需要达到的前端效果预览&#xff1a;实现步骤复制bootstrp代码&#xff08;buttons&#xff09;复制bootstrp代码&#xff08;Alert警告框&#xff09;写js测试效果 需要达到的前端效果预览&#xff1a; {% load static %} <!DOCTYPE html> <html lang"…

十分钟速通 MySQL —— CRUD

表格的结构 在之前的课程中我们已经学习了关系型数据库的表格&#xff0c;我们再来回顾-下表格由哪些元素构成 表由表名、行、列、列名构成表名是表的名称列名表示列的名字&#xff0c;列名不可以重复表格实质上是一个二维数组&#xff0c;行和列都是从0开始数的(数组的特性) …

【软考】广义表

目录 1. 说明2. 基本操作3. 特点4. 存储结构5. 例题5.1 例题1 1. 说明 1.广义表是线性表的推广&#xff0c;是由0个或多个单元素或子表组成的有限序列。2.广义表与线性表的区别在于:线性表的元素都是结构上不可分的单元素&#xff0c;而广义表的元素既可以是单元素&#xff0c…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第六十二章 定时器按键消抖实验

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

shardingsphere的学习(一):shardingsphere的基本概念和水平分表例子

简介 关于shardingsphere的基本相关概念的学习和使用shardingjdbc进行水平分表的例子 shardingsphere 是一套开源的分布式关系型数据库中间件解决方案&#xff0c;由sharding-jdbc&#xff0c;sharding-proxy&#xff0c;sharding-sidecar三个项目组成。 定位为关系型数据库…

日期类的实现(C++实现)

完整呈现 Date.h #include <iostream> using namespace std; //日期类 class Date { public:int GetMonthDays(int year, int month) const;//构造函数Date(int year 0, int month 1, int day 1);//拷贝构造Date(const Date& d);//打印void Print();//析构函数~…

Redis与MySQL数据一致性问题的策略模式及解决方案

目录 一、策略模式 1、旁路缓存模式&#xff08;Cache Aside Pattern&#xff09; 2、读写穿透&#xff08;Read-Through/Write-Through&#xff09; 3、异步缓存写入&#xff08;Write Behind&#xff09; 二、一致性解决方案 1、缓存延迟双删 2、删除重试机制 3、读取…

【python】sklearn基础教程及示例

【python】sklearn基础教程及示例 Scikit-learn&#xff08;简称sklearn&#xff09;是一个非常流行的Python机器学习库&#xff0c;提供了许多常用的机器学习算法和工具。以下是一个基础教程的概述&#xff1a; 1. 安装scikit-learn 首先&#xff0c;确保你已经安装了Python和…

Unity 资源 之 Pop It 3D 解压玩具与双人AI游戏 Unity 资源包分享

精彩呈现&#xff1a;Pop It 3D 解压玩具与双人AI游戏 Unity 资源包分享 一、Pop It 3D 解压玩具的魅力二、双人游戏的互动乐趣三、Unity 游戏资源包的优势四、如何获取资源包 亲爱的游戏爱好者们&#xff0c;今天为大家带来一款令人兴奋的游戏资源——Pop It 3D 解压玩具双人带…

数字陷波器的设计和仿真(Matlab+C)

目录 一、数字陷波器的模型 二、Matlab仿真 1. 示例1 2. 示例2 三、C语言仿真 1. 由系统函数计算差分方程 2. 示例代码 一、数字陷波器的模型 二、Matlab仿真 1. 示例1 clear clc f0=100;%滤掉的100Hz fs=1000;%大于两倍的信号最高频率 r=0.9; w0=2*pi*f0/fs;%转换到…

[图解]《分析模式》漫谈19-Midjourney、Sora

1 00:00:02,360 --> 00:00:03,360 今天的漫谈 2 00:00:03,370 --> 00:00:04,560 我们来说一下 3 00:00:04,570 --> 00:00:08,720 人工智能&#xff0c;还是前言 4 00:00:08,890 --> 00:00:11,840 这里有一句话 Kent Beck 5 00:00:12,630 --> 00:00:13,750 W…

Spring Boot配置文件的语法规则

主要介绍两种配置文件的语法和格式&#xff0c;properties和yml 目录 1.配置文件的作用 2.创建配置文件 3.properties语法 4.yml语法 5.配置文件格式 1.配置文件的作用 对于配置文件&#xff0c;也有独立的文件夹去存放&#xff0c;主要用来存放一些需要经过变动的数据&a…

python绘制方波信号

python绘制方波信号 1、效果 2、导入库 pip install numpy pip install matplotlib3、实现代码 # -*- coding: utf-8 -*-""" @contact: 微信 1257309054 @file: test.py @time: 2024/7/28 14:48 @author: LDC """ import numpy as np import …

IOS-04 Swift 中数组、集合、字典、区间、元组和可选类型

在 Swift 编程语言中&#xff0c;数据结构和类型的合理运用对于高效编程至关重要。接下来&#xff0c;我们将深入探讨数组、集合、字典、区间、元组和可选类型的相关知识。 一、数组&#xff08;Array&#xff09; &#xff08;一&#xff09;元素定义 可以通过多种方式定义数…

Hello 算法:动画图解、一键运行的数据结构与算法教程

Hello 算法 《Hello 算法》是一份开源、免费的数据结构与算法入门教程&#xff0c;特别适合新手。全书采用动画图解&#xff0c;内容清晰易懂&#xff0c;学习曲线平滑&#xff0c;引导初学者探索数据结构与算法的知识地图。源代码可以一键运行&#xff0c;帮助读者通过练习提…

C#中的同步编程和异步编程

1. 简单描述一下同步编程和异步编程 同步编程&#xff1a;按照代码的顺序一行一行执行&#xff0c;如果某个操作需要等待&#xff08;比如读取文件、网络请求、数据库操作等&#xff09;&#xff0c;那么当前的线程就会停下来&#xff0c;一直到这个操作完成了之后&#xff0c…

git学习(一)

一、代码仓库的初始化 1、先在本地操作&#xff0c;不涉及到远程服务器&#xff0c;创建目录mkdir git demo 想要本地创建的目录成为一个远程仓库就需要初始化git init git init 后会发生什么&#xff1f; 2、watch -n 1 -d tind每隔1s打印当前文件目录并且刷新 左边命令 wa…

搞DDR,你是可以看看我的这篇笔记(三)

关于DDR PHY这个部分,是数模混合器件,工作涉及到了很多信号完整性,眼图,模拟等相关的东西我就没讲了。因为确实不太熟悉,只能站在架构、功能、使用上去聊聊。 上一篇我们看了这个图片,简化就是下面这个样子: 其实这个也不太合适~~~ 这样舒服多了,一般DDRC和DDRPHTY都会…

被工信部认可的开源软件治理解决方案

近日&#xff0c;工信部网络安全产业发展中心正式发布了“2023年信息技术应用创新解决方案”&#xff0c;开源网安凭借“基于SCA技术开源软件治理解决方案”顺利入选&#xff0c;成为经工信部认可的优秀解决方案&#xff0c;这是开源网安连续两届荣获此荣誉。 工业和信息化部网…