【Vue3】Vue3核心内容(上)

news2024/11/27 11:48:35

🎀个人主页:努力学习前端知识的小羊
感谢你们的支持:收藏🎄 点赞🍬 加关注🪐

文章目录

  • 常用的Composition API
    • setup函数
    • ref函数
    • reactive函数
    • vue3中的响应式原理
      • vue2的响应式
      • Vue3的响应式
    • reactive对比Ref
    • setup的注意点
    • 计算属性与监视
      • computed函数
      • watch函数
      • watchEffect函数
    • 生命周期
    • 自定义hook函数
    • toRef

常用的Composition API

setup函数

1.组件中所用的:数据,方法等等,均要配置在setup中
2.setup函数的俩种返回值:
(1)若返回一个对象,则对象中的属性,方法,在模板中均可以直接使用
(2)若返回一个渲染函数:则可以自定义渲染内容

注意点:
1.尽量不要与vue2的配置使用

  • vue2配置(data,methods,computed …)中可以访问到setup中的属性、方法
  • 但在setup中不能访问到vue2配置(data,methods,computed…)
  • 如果有重名,setup优先

2.setup不能是一个async函数,因为返回值不再是return的对象,而不是promise,模板看不到return对象中的属性(后期也可以返回一个Promise函数,但需要Suspense和异步组件的配合)

ref函数

  • 作用:定义一个响应式的数据
  • 语法:const xxx = ref(initvalue)
    • 创建一个包含响应式数据的引用对象(reference对象,简称ref对象)
    • JS中操作数据:xxx.value
    • 模板中读取数据:不需要 .value,直接:
      {{xxx}}

备注:

  • 接受的数据可以是:基本类型、也可以是对象类型
  • 基本类型的数据:响应式依然是靠object.defineProperty()的get和set完成
  • 对象类型的数据:内部’求助’了Vue3.0的一个新函数——reactive函数

reactive函数

  • 作用:定义一个对象类型的响应式数据(基本类型不能使用,基本类型使用ref函数)
  • 语法:const 代理对象 = reactive (源对象)接受一个对象(或数组),返回一个代理对象(proxy的实例对象,简称proxy对象)
  • reactive定义的响应式数据是深层次
  • 内部基于ES6的proxy实现,通过代理对象操作源对象内部数据进行操作

vue3中的响应式原理

vue2的响应式

  • 实现原理:

    • 对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)。

    • 数组类型:通过诚信更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包装)

      Object.defineProperty(data,'count',{
      	get(){},
      	set(){}
      })
      
  • 存在问题:

    • 新增属性、删除属性,界面不会更新
    • 直接通过下表修改数组,界面不会自动更新

Vue3的响应式

  • 实现原理

    • 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性的读写、添加、删除等
    • 通过Reflect(反射):对源对象的属性进行操作
    const p = new Proxy(person,{
                // 有人读取p的某个属性时调用
                get(target,propName){
                    console.log(`有人读取了p身上的${propName}属性`,target,propName);
                    return Reflect.get(target,propName)
                },
                // 有人修改p的某个属性、或给p追加某个属性时调用
                set(target,propName,value){
                    console.log(`有人修改了p身上的${propName}属性,我要去更新页面`);
                    return Reflect.set(target,propName,value)
                },
                // 有人删除p的某个属性时调用
                deleteProperty(target,propName){
                    console.log(`有人删除了p身上的${propName}属性,我要去更新页面`);
                    
                    return Reflect.deleteProperty(target,propName)
                }
            })
    

reactive对比Ref

  • 从定义角度对比:
    • ref用来定义:基本类型数据
    • reactive用来定义:对象(或数组)类型数据
    • ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象
  • 从原理角度:
    • ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。
    • reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据。
  • 从使用角度:
    • ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。
    • reactive定义的数据:操作数据与读取数据:均不需要.value。

setup的注意点

  • setup执行的时机
  • beforeCreate之前执行一次,this值是undefined,
  • setup的参数:
  • props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
  • context: 上下文对象
    • attrs:值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于this.$attrs
    • slots:收到的插槽内容,相当于this.$slots
    • emit:分发自定义事件的函数,相当于this.$emit

计算属性与监视

computed函数

  • 与vue2.x中computed配置功能一致

  • 写法:

    import { reactive,computed } from "vue";
    
    setup() {
            let person = reactive({
                firstName:"张",
                lastName:"三"
            })
            // 计算属性--简写(没有考虑计算属性被修改的情况)
             person.fullName = computed(()=>{
                 return person.firstName + '-' + person.lastName
             })
    
            // 计算属性--完整写法(考虑读和写)
            person.fullName = computed({
                get(){
                    return person.firstName + '-' + person.lastName
                },
                set(value){
                    const nameArr= value.split('-')
                    person.firstName = nameArr[0]
                    person.lastName = nameArr[1]
                }
            })
    

watch函数

两个注意点

  • 监视reactive定义的响应式对象时:oldValue无法正确获取,强制开启deep(深度监视)
  • 监视reactive定义的响应式数据中某个对象时:deep配置有效
    setup(){
        let sum = ref(0)
        let msg = ref('你好啊')
        let person = reactive({
            name:"张三",
            age:"18",
            Job:{
                j1:{
                    salary:20
                }
            }
        })

        //情况一:监视ref所定义的响应式数据
      /*   watch(sum,(newValue,oldValue)=>{
            console.log('sum变了',newValue,oldValue);
        },{immediate:true}) */
        
        // 情况二:监视ref定义的多个响应式数据
       /*  watch([sum,msg],(newValue,oldValue)=>{
            console.log('msg变了',newValue,oldValue);
        },{immediate:true}) */

        // 情况三:监视reactive定义的一个响应式对象,
        // 注意:1.此处无法正确的获取oldValue
        //       2.强制开启了深度监视(deep配置无效)
        /* watch(person,(newValue,oldValue)=>{
            console.log('person变化了',newValue,oldValue);
        },{deep:false}) */
        // 情况四:监视reactive定义的一个响应式数据的某个属性

        /* watch(()=>person.age,(newValue,oldValue)=>{
            console.log('perosn的age变了',newValue,oldValue);
        }) */

        // 情况五:监视reactiva定义的一个响应式数据的某些对象
      /*   watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
            console.log("person的name或者age变了",newValue,oldValue);
        }) */


        // 特殊情况
        /* watch(()=>person.Job,(newValue,oldValue)=>{
            console.log("person的job变了",newValue,oldValue);
        },{deep:true})
        //由于监视的是reactive所定义的对象中的某个属性,所以deep配置有效 */

watchEffect函数

  • watch:既要指明监视的属性,也要指明监视的回调
  • watchEffect:不用指明监视的属性,监视的回调中用到那个属性,那就监视那个属性
  • watchEffect有点像computed:
    • computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值
    • watchEffect更注重的是过程(回调函数的函数体),所以不同写返回值
//watchEffect所指定的回调中的数据只要发生变化,则直接重新执行回调
watchEffect(()=>{
    const x1 = sum.value
    const sa = person.Job.j1.salary
    console.log('watchEffect执行了',x1,sa);
 })  //监视sum 和person.Job.j1.salary的数值

生命周期

组件生命周期图示

  • vue3的生命周期钩子与vue2一样,只是有两个名字发生改变
  • beforeDestory------> beforeUnmounted
  • destoryed -------> unmounted
  • vue3也提供了Composition API形式的生命周期钩子,对应关系如下:
  • beforeCreated ===> setup()
  • created ===> setup()
  • beforeMount ===> onBeforeMount
  • mounted ===> onMounted
  • beforeUpdate ===> onBeforeUpdate
  • update ===> onUpdated
  • beforeUnmount ===> onBeforeUnmount
  • unmounted ====> onUnmounted

自定义hook函数

  • 自定义hook函数——本质是一个函数,把setup函数中使用的组件化API进行了封装

优势:复用代码,让setup中的逻辑更清晰易懂

toRef

  • 作用:创建一个ref对象,其value值指向另一个对象中的某个属性
  • 语法:const name = toRef(person,'name')
  • 应用:要将响应式对象中的某个属性单独提供给外部使用
  • 扩展:toReftoRefs功能一致,但可以批量创建多个ref对象,语法:toRefs(person)

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

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

相关文章

数据结构---手撕图解七大排序(含动图演示)

文章目录 插入排序直接插入排序希尔排序 选择排序选择排序堆排序 交换排序冒泡排序快速排序hoare版挖坑法前后指针法快速排序的递归展开图快速排序的优化三数取中法 快速排序的非递归实现 归并排序 插入排序 插入排序分为直接插入排序和希尔排序,其中希尔排序是很值…

xxl-job分布式任务调度器的学习

先看一下原生的任务调度器 package com.xxl.job.executor.service.jobhandler;import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;Compone…

3.Docker网络和资源控制

文章目录 Docker操作二Docker网络实现原理端口映射查看日志 网络模式host模式container模式none模式bridge模式自定义网络 Docker资源控制CPU资源控制设置CPU使用率上限设置CPU资源占用比(设置多个容器才有效)设置容器绑定指定CPU 内存使用限制设置磁盘I…

RK3399移植u-boot

RK3399移植u-boot 0.前言一、移植1.交叉工具链安装2.获取bl31.elf3.移植u-boot1)下载:2)配置:修改串口波特率:修改emmc:配置FIT:配置boot delay:(可选) 3)编译:4)生成idbloader.img文件&#xf…

使用 Docker 快速上手中文版 LLaMA2 开源大模型

本篇文章,我们聊聊如何使用 Docker 容器快速上手朋友团队出品的中文版 LLaMA2 开源大模型,国内第一个真正开源,可以运行、下载、私有部署,并且支持商业使用。 写在前面 感慨于昨天 Meta LLaMA2 模型开放下载之后,Git…

实验五 分支限界法

实验五 分支限界法 01背包问题的分治限界法的实现 剪枝函数 限界函数 1.实验目的 1、理解分支限界法的剪枝搜索策略,掌握分支限界法的算法框架 2、设计并实现问题,掌握分支限界算法。 2.实验环境 java 3.问题描述 给定n种物品和一背包。物品i的重…

JMeter基础入门教程之CSV数据文件设置CSV Data Set Config

最近在做压力测试,登录功能用到了配置元件:CSV 数据文件设置,可以将登录用户名和密码放在一个csv文件中,然后通过CSV数据文件设置元件读取出来,用来做压测。 一、CSV文件 CSV文件小知识分享:是指"逗号…

Linux内核--内存管理

MMU的产生背景 在计算机出现的早期,其内存资源十分有限,一般只有几十几百KB,当时的程序规模也小,对于当时的程序而言,KB级的内存资源尚足够使用。但随着计算机技术的发展,应用程序的规模不断膨胀&#xff…

k8s部署wordpress+mysql博客平台

k8s部署wordpressmysql博客平台 1、yaml文件准备1.1 wordpress-db.yaml1.2 wordpress.yaml 2、部署安装2.1 先创建wordpress命名空间2.2 部署wordpress-db2.3部署wordpress 3、访问测试 1、yaml文件准备 1.1 wordpress-db.yaml apiVersion: apps/v1kind: Deploymentmetadata:…

【flink】ColumnarRowData

列式存储 在调试flink读取parquet文件时,读出来的数据是ColumnarRowData,由于parquet是列式存储的文件格式,所以需要用一种列式存储的表示方式,ColumnarRowData就是用来表示列式存储的一行数据,它包含多个数组的数据结…

Matlab求解基于RRT算法的自定义垛型的路径避障

目录 背景 1 RRT搜索算法 2 基于Matlab的RRT搜索算法 3 基于Matlab的自定义垛型绘制 4 基于RRT算法的自定义垛型的路径避障 背景 在码垛机械臂路径规划过程中,需要根据现有箱子的码垛状态,给出下一个箱子的最佳码放无碰撞路径。RRT 快速搜索随机…

vue2项目 自定义详情组件

vue2项目 自定义详情组件 效果组件代码组件引入以及传参格式寄语 效果 组件代码 DetailFormRow.vue已经封装好&#xff0c;根据数据格式直接引用即可。 <template><div class"detail-form"><el-row class"detail-form-row" style"ma…

基本函数、常见曲线图像

基本函数图像是指一些常见的数学函数的图像&#xff0c;这些函数在数学和工程等领域中经常被使用。下面是一些常见的基本函数及其图像&#xff1a; 参考文献&#xff1a;同济版高等数学【第七版】上下册教材

几张表格搞定Mysql的SQL语句

一、数据库的登录与退出 登录Mysqlmysql -uroot -p123退出Mysqlexit 二、对数据库的操作 查询所有数据库show databases;创建数据库create database 数据库名字;删除数据库drop database 数据库名字;查询创建数据库的具体语句show create database 数据库名字;使用数据库use…

自学网络安全(黑客),遇到问题怎么解决

自学网络安全很容易学着学着就迷茫了&#xff0c;找到源头问题&#xff0c;解决它就可以了&#xff0c;所以首先咱们聊聊&#xff0c;学习网络安全方向通常会有哪些问题&#xff0c;看到后面有惊喜哦 1、打基础时间太长 学基础花费很长时间&#xff0c;光语言都有几门&#xf…

RocketMQ的系统设计

消息存储 下图为producer、broker、consumer的交互过程 1.消息存储整体架构 CommitLog&#xff1a;消息主体以及元数据的存储主体&#xff0c;存储Producer端写入的消息主体内容(即Producer端投递的消息都会先写入CommitLog中)&#xff0c;消息内容不是定长的。单个文件大小默…

代码随想录day8 | KMP 28.实现strStr() 459.重复的子字符串

文章目录 一、实现strStr()二、重复的子字符串 一、实现strStr() 先学学KMP算法&#xff0c;代码随想录 28.实现strStr() class Solution { public:void getNext(int* next, const string& s) {int j -1;next[0] j;for(int i 1; i < s.size(); i) { // 注意i从1开始…

win 安装虚拟机 再安装macos

0 视频教程 windows虚拟机一键安装苹果系统macos&#xff0c;轻松拥有xcode环境_哔哩哔哩_bilibili在windows环境下vmware虚拟机一键安装macos Catalina10.15.7苹果系统&#xff0c;帮助学习ios编程的朋友们实现xcode环境。文字教程&#xff1a;https://www.dhzy.fun/archives…

【Matlab】基于遗传算法优化 BP 神经网络的数据分类预测(Excel可直接替换数据)

【Matlab】基于遗传算法优化 BP 神经网络的数据分类预测&#xff08;Excel可直接替换数据&#xff09; 1.模型原理2.文件结构3.Excel数据4.分块代码4.1 arithXover.m4.2 delta.m4.3 ga.m4.4 gabpEval.m4.5 initializega.m4.6 maxGenTerm.m4.7 nonUnifMutation.m4.8 normGeomSel…

Qt ComboBox 下拉框设置多列

Qt ComboBox 下拉框设置多列 通过设置listview实现。 class MultiColumnComboBoxItemDelegate; class MultiColumnComboBoxListView;class MultiColumnComboBox : public QComboBox {Q_OBJECT public:explicit MultiColumnComboBox(QWidget *parent nullptr);~MultiColumnCo…