vue3_setup响应式
拉开序幕的setup
setup
- 理解:vue3.0的新的配置项,值为一个函数
- setup是所有composition API(组合API)的“表演舞台”;
- 组件中所用到的:数据,方法等等,均要配置在setup中;
- setup函数的两种返回值:
1、若返回一个对象,则对象中的属性,方法,在模板中均可以直接使用。
2、若返回一个渲染函数:则可以自定义渲染内容 - 注意点:
1、尽量不要与vue2.x配置混用
· vue2.x配置(data,methods,computed...)中可以访问到setup中的属性,方法。
· 但在setup中不能访问到vue2.x配置(data,methods,computed...)。
· 如有重名,setup优先。
2、setup不能是一个async函数,因为返回值不再是return对象,而是promise,模板中看不到return对象中的属性
ref函数
对数据进行响应式处理
作用: 定义一个响应式数据;
语法: const xxx = ref(initvalue);
- 创建一个包含响应式数据的引用对象(reference对象,简称ref对象)
- js中操作数据:xxx.value;
- 模板中读取数据,不需要value,直接<div>{{xxx}}</div>
备注:
·接收数据类型可以是基本数据类型,也可以是对象类型;
·基本数据类型:响应式依然是靠Object.defineProperty()的get和set完成的。
·对象数据类型:内部使用了vue3.0中的reactive函数
<template>
<h1>我是: {{ name }}</h1>
<h1>年龄: {{ age }}</h1>
<h1>工作: {{ job.type }}</h1>
<button @click="change">chanage</button>
</tempalte>
<script>
import { ref } from "vue";
export default {
setup(){
let name = ref("tom"); //ref函数把 "tom" 值封装为 RefImpl{}引用对象
let age = ref(18);
let job = ref({ //ref函数把对象封装为 Proxy 对象
type: "前端工程师",
salary: "20k"
})
function change(){
name.vlaue = "李四";
age.value = 20;
job.value.type = "UI设计师";
}
return {
name,
age,
change,
}
}
}
</script>
<style>
</style>
reactive函数
- 作用:定义一个对象类型的响应式数据(基本别用它,用ref函数);
- 语法:
const 代理对象 = reactive(被代理对象);
接收一个对象(或数组),返回一个代理器对象(Proxy对象); - reactive定义的响应式数据是“深层次的”;
- 内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据都是响应式的
<template>
<h1>我是: {{ person.name }}</h1>
<h1>年龄: {{ person.age }}</h1>
<h1>工作: {{ person.job.type }}</h1>
<button @click="change">chanage</button>
</tempalte>
<script>
import { reactive } from "vue";
export default {
setup(){
let person = reactive({
name: "tom",
age: 18,
job: {
type: "前端工程师",
salary: "20k"
}
})
function change(){
person.name = "李四";
person.age = 20;
person.job.type = "UI设计师";
}
return {
person,
change,
}
}
}
</script>
<style>
</style>
vue3中的响应式原理
vue2.x的响应式
原理:
对象类型: 通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持);
数组类型: 通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)
Object.defineProperty(data,"count",{
get(){
},
set(){
}
})
存在问题
- 新增属性,删除属性,界面不会更新
- 直接通过下标修改数组,界面不会更新
vue3.0的响应式
实现原理:
· 通过Proxy(代理):拦截对象中任意属性的变化;包括:属性的值的读写,属性的添加,属性的删除等。
· 通过Reflect(反射):对被代理对象的属性进行操作。
reactive对比ref
从定义数据角度对比:
· ref用来定义:基本数据类型。
· reactive用来定义:对象(数组)类型数据
备注
ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive
转为Proxy
对象。
从原理角度对比:
· 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
。