vue3记录(第一版)

devtools/2024/11/8 3:35:39/

vue2与vue3的区别

vue2属于选项式API,vue3属于组合式API

setup概述

setup是vue3中一个新的配置项,值是一个函数,组件中所用到的数据,方法,计算属性,监视等等,均配置在setup中

vue3中的setup和vue2的data,methods之间有什么关系呢?
因为setup比data解析的早,所以在data中可以读到setup中的数据,但是要用this指向
如果两者有冲突的话,优先于setup

setup语法糖

将setup写在script里面,则不用返回所定义的变量和函数

ref 定义基本类型的数据响应式变化

let 属性名= ref(值)
形成一个refImpl实例对象,object.defineProperty()内部的get,set进行实现
使用ref进行响应式数据的时候,数据要从value中捞取 ref也可以包裹复杂数据类型

reactive定义对象类型的数据响应式变化

reactive定义对象类型的数据变化
使用reactive定义时要修改对象中的全部属性,需要使用Object.assign(对象1,对象2)
表示将对象2中的数据全都赋给对象1 而使用ref定义的对象类型的数据可以直接赋值
区别:reactive替换整体时地址并未发生变化,而是将对象二中的属性值分别赋值给对象一中的属性
ref替换整体时采用字面量的方式进行赋值,改变了原先的地址

vue2与vue3响应式数据的区别

vue2响应数据原理:
vue2通过object.defineproperty()给每个数据都添加一个set与get,用于对数据的读取与修改
但是在对象和数组中通过索引值或者直接添加,删除的方式并不能进行响应数据页面变化
原因:因为object.defineproperty()中的set与get只控制数据的读取和修改,对于新增和删除并不理会,所以当我们通过索引值或.的方式添加数据时,不会更新页面,因为新添加的数据并没有get与set函数,删除也是同理

vue3响应数据原理:
vue3很好的解决了vue2所出现的问题,使用proxy对象进行代理数据,给数据整体加上get与set,并且有对应的deleteProperty方法,用于数据的删除,get管理数据的读取,set管理数据的修改与新增,完全实现了数据的响应式变化
底层是通过Reflect反射对象,使用get,set,与deleteProperty对源数据进行操作
Reflect不会阻塞代码的正常运行(不会报错),成功返回true,失败返回false,但是通过object.defineProperty()添加的数据会阻塞代码往下运行,

使用原则

1.若需要一个基本类型的响应式数据,必须使用ref
2.若需要一个响应式对象,层级不深,ref,reactive都可以
3.若需要一个响应式对象,且层级较深,推荐使用reactive
4.ref定义的对象类型实现响应式原理底层还是借助了reactive中的proxy来实现

computed

const 变量名 = computed(() => {return 需要计算的过程
})

在vue2中我们都已经知道,方法和计算属性的区别:

  • 方法需要调用才执行,可以实现和计算属性一样的效果
  • 但是唯一不同是计算属性有缓存,方法并没有
  • 计算属性是当它所依赖的数据发生改变的时候才会重新计算
  • 而方法会在每次调用的时候就触发

计算属性一般用来通过已有的属性计算出一个新的属性,默认是只读的,通过get函数读取
当你试图修改通过计算属性得得到的值时,会收到一个警告,当需要修改计算属性值时,计算属性可以变为可修改的,需要在里面配置一个set函数,用于接收修改后的值

注意:计算属性的意义是由其他值来派生出另一个值,重点是进行计算的过程和返回结果值,要避免在其中参杂其他的逻辑(修改DOM,异步请求)

const 变量名 = computed({// getter 用于读取get() {return },// setter 用于修改set(newValue) {}
})

watch

作用:监视数据的变化

watch本质是一个函数
第一个参数,要监视的对象或属性
第二个参数是一个回调函数,参数为newValue,oldValue
第三个参数可以配置,例如开启深度监视,或者一上来就监视一次

特点:Vue3中的watch只能监视以下四种数据
1.ref定义的数据
2.reactive定义的数据
3.函数返回一个值(getter函数)
4.一个包含上述内容的数组

watch监视返回值本质上是一个函数,当需要解除监视时直接调用该函数即可

监视ref定义的基本类型数据

import {reactive, toRefs,ref,watch} from 'vue'
let sum = ref(0)watch(sum,(newValue,oldValue)=>{if(newValue > 200){//操作逻辑}
})
const changeSum = ()=>{sum.value += 100
}

监视ref定义的对象类型的基本数据

1.当使用ref定义对象类型时,监视整体时,默认监视的是person的地址值,只有当person里的值全都变化了,才可以监视的到
若是需要某一个值变化就能监测到,需要开启深度监视,但是这时新旧值都显示为新值,因为对象中的一个值改变了,并未引发地址的改变,还是原来的对象

const person =ref( {name:'hangsan',age:10
})const changeName =()=>{
person.value.name += '-'
console.log(person.value.name);
}
const changeAge =()=>{
person.value.age += 1
}
const changeALL =()=>{
person.value = {name:'lisi',age:111} // 直接通过字面量赋值的方式修改,地址变化了
}
watch(person,(newValue,oldValue)=>{    console.log(newValue,oldValue,'2');  
},{deep:true})

2.当使用reactive定义对象数据类型的数据时,会隐式地创建一个深层侦听器,监视时默认开启深度监视,即对象中的一个值变化就会触发监视

const person =reactive( {name:'hangsan',age:10
})const changeName =()=>{
person.name += '-'
console.log(person.name);
}
const changeAge =()=>{
person.age += 1
}
const changeALL =()=>{
Object.assign(person,{name:'wasa',age:12})  //里面值都变了,但是地址并未变化
}
watch(()=>person.name,(newValue,oldValue)=>{console.log(newValue,oldValue,'1'); 
})
watch(person,(newValue,oldValue)=>{   console.log(newValue,oldValue,'2'); //newValue,oldValue两者的值相同,因为他们是一个对象(地址未变)
})

监视ref或者reactive定义的对象类型中的某一个属性

const person =reactive( {name:'hangsan',age:10
})const changeName =()=>{
person.name += '-'
console.log(person.name);
}
const changeAge =()=>{
person.age += 1
}
const changeALL =()=>{
Object.assign(person,{name:'wasa',age:12}) 
}
watch(()=>person.name,(newValue,oldValue)=>{console.log(newValue,oldValue,'1'); 
})

当监视ref或者reactive定义的对象类型中的某一个值时,watch函数的第一个参数为监视的值,不能直接写对象.属性名
因为此时获取的是对象中的一个数据值,并不符合watch所监视的四种情况中的一种
这时需要使用get函数来返回所要监视的对象中的属性值

若该属性不是对象类型,则需要写成get函数

若该属性是对象类型:
可直接写,若直接写当整个对象发生变化时监测不到,因为watch监测的只是原对象,当整体改变时,相当于原对象已经不存在了,换成了另一个全新的对象
也可写成函数式,不会出现上述情况

监视多个属性

// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY],[oldX, oldY]) => {console.log(`x is ${newX} and y is ${newY}`)
})

当监视多个时,使用数组包裹,只要有一个数据变化时会触发监视,newValue和oldValue值相同,且都为数组

watchEffect

let sum = ref(0)
let count = ref(20)
//使用watch监视属性,当达到某个限制时实现相应逻辑watch([sum,count],(value)=>{ let [sum,count] = valueif(sum>40){console.log('111');}
})
//使用watchEffect监视属性,当达到某个限制时实现相应逻辑
watchEffect(()=>{if(sum.value > 40 || count.value > 40){console.log('111');}
})
const changeSum = ()=>{sum.value += 20
}
const changeCount = ()=>{count.value += 10
}

watchEffect会自动在逻辑中识别所要监视的属性,不用再像watch那样再标明所要监视的属性

ref

加在html标签上可以获取当前的DOM元素
但是加在组件身上,获取的是一个组件实例,并不会看到这个组件身上的东西,产生保护机制
若想看到,组件要暴露defineExpose,defineExpose({想给别人看的属性})
这样父组件调用的时候才能看到这些属性

hook钩子函数

hook 本质是一个函数,把setup函数中使用的Composition API进行了封装

其实是将vue中的数据与方法进行进一步模块化,将一个功能的数据与方法放到同一个文件中,类似于vue2中的minxin

命名使用use与功能名进行拼接,文件内使用函数包裹功能向外界暴露,函数内将其数据与函数return出

在主文件中引入,使用hook暴露出的函数,让代码的逻辑更加清楚易懂

toRef

作用:将响应式对象中的指定属性值包装成为一个ref响应式数据,该响应式数据的值指向先前对象中的值
语法:const 属性名 = toRef(对象名,‘属性名’)
应用:将对象中的值单独提供给外部使用时,可以实现原对象的 数据与新包装成的ref数据的联动响应

let person = reactive({name:'zhangsan',age:11
})
let age =toRef(person,'age')
let name =toRef(person,'name')const updateName = ()=>{name.value += '_'
}
const updateAge = ()=>{age.value += '_'
}

在这里插入图片描述

在这里插入图片描述

对象数据类型的响应式原理是依靠proxy来实现的,通过内部的get与set函数来实现对数据的读取和修改,实现数据与页面的一致,当使用toRef()将对象中的数据转化为ref实例对象时,实例对象的get与set会指向原对象的get与set,当原对象中该属性值发生变化时,该实例对象也会发生变化,同理实例对象发生变化时,原对象也会发生变化,从而会实现了两个数据的同步

toRefs

toRefs和toRef作用一样,不同点是前者将对象中的每一个都创建为了ref对象,后者是有选择的
适用于多个使用对象中的数据的场景

let person = reactive({name:'zhangsan',age:11
})
let { name,age} =toRefs(person) 
const updateName = ()=>{name.value += '_'
}
const updateAge = ()=>{age.value += '_'
}
console.log(name,age);

在这里插入图片描述

toRaw与markRow

toRaw: 作用:将一个由reactive生成的响应式对象转为普通对象。
使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。

markRaw:
作用:标记一个对象,使其永远不会再成为响应式对象。
应用场景:
1.有些值不应被设置为响应式的,例如复杂的第三方类库等。
2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。

vue2&vue3(difference)

vue2中父组件通过props向子组件传递数据,但当子组件不接收时,就将数据暂时储存在$attrs上,当子组件使用props接收时,就将数据挂载在组件实例身上

setup函数的执行时机比beforeCreated还要早,this为undefined,所有vue3中不存在this

setup函数接收两个参数,props和context props:外部传递过来的数据且组件声明接收过的放在props上
context:attrs:外部组件传递过来数据,但组件没有声明接收的会放在这里,和vue2$attrs一样

emit:给子组件绑定自定义事件,必须在子组件中使用emits声明下绑定的是什么事件,相当于vue2$emits

slots:插槽,具名插槽需要用v-slot:名字,$slots


http://www.ppmy.cn/devtools/132201.html

相关文章

甘肃高校大数据实验室建设案例分享

随着信息技术的快速发展,大数据技术已成为推动经济社会发展的重要引擎。甘肃省高度重视教育信息化建设,并积极支持省内高校建立大数据相关实验室,以促进学科交叉融合及创新人才培养。在此背景下,泰迪携手多所甘肃高校共同打造了一…

恒创科技:如何知道一台服务器能承载多少用户?

如何知道一台服务器能承载多少用户?其实服务器承载能力并非一个单一固定的数值,而是由多种因素共同决定的动态指标,所以想知道能承载的访客量,我们要先搞清楚究竟有哪些因素会影响服务器承载访客的数量。 影响服务器承载访客的因素&#xff…

python项目实战---使用图形化界面下载音乐

音乐下载 设计思路: 设计界面编写爬虫代码绑定爬虫打包exe文件 这个是最终的设计成果,所有的下载歌曲都在“下载mp3”文件夹里面 完整代码 逻辑代码 import os.path import reimport requests from PyQt5.QtWidgets import QApplication,QWidget,QM…

Java版工程行业管理系统源码-专业的工程管理软件- 工程项目各模块及其功能点清单

工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&am…

[vulnhub]DC: 1

https://www.vulnhub.com/entry/dc-1,292/ 主机发现端口扫描 使用nmap扫描网段类存活主机 因为靶机是我最后添加的,所以靶机IP是156 nmap -sP 192.168.75.0/24 // Starting Nmap 7.93 ( https://nmap.org ) at 2024-09-28 12:48 CST Nmap scan rep…

网络安全从入门到精通(第一章-1)Web服务器通信原理

本文内容 IP地址域名 端口 HTTP协议从访客角度看网页浏览器流程 常见服务器系统路径Web容器常见的Web容器 !!!多动手,多动手,只看只听是不行的!!! 1,IP地址:就是计算机…

NLP segment-04-自动摘要 auto-summary java 开源实现

拓展阅读 分词系列专题 jieba-fenci 01 结巴分词原理讲解 segment jieba-fenci 02 结巴分词原理讲解之数据归一化 segment jieba-fenci 03 结巴分词与繁简体转换 segment jieba-fenci 04 结巴分词之词性标注实现思路 speechTagging segment 关键词系列专题 NLP segment-…

java项目之微服务在线教育系统设计与实现(springcloud)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的闲一品交易平台。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: 微服务在线教育系统设计与…