setup学习
setup的基本使用
在Vue2中,我们去编写一个页面,假设就是一个比较简单的加减法的,如下图所示:
这是Vue2的写法
<template>
<button type="button" @click="add">count is {{ count }}</button>
<div>2倍的count:{{ countDouble }}</div>
</template>
<script>
export default {
name: 'HelloWorld',
data: () => {
return {
count: 1,
};
},
computed: {
countDouble() {
return this.count * 2;
},
},
methods: {
add() {
this.count++;
},
},
};
</script>
在Vue3中的写法
<template>
<div class="card">
<button type="button" @click="add">count is {{ count }}</button>
<div>2倍的count:{{ countDouble }}</div>
</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(1);
const add = () => {
count.value++;
};
const countDouble = computed(() => {
return count.value * 2;
});
return {
count,
add,
countDouble,
};
},
};
</script>
在Vue3使用了一个setUp的函数,在函数中去编写数据和方法,并通过return的方式进行导出给组件中其他部分进行使用。
可以看出在Vue3中去编写页面逻辑的时候,自由度是比较高的,可以直接将数据、所使用该数据的方法、computed等放在同一个地方,这样页面的逻辑相比于Vue2的散落各个部分的逻辑会清楚很多。
setup函数参数的学习
在setup函数中,接受两个参数,第一个是props,第二个是context。
props
setup接受的第一个参数是props,是从父组件中传递过来的参数, 具有响应式(父组件中该数据发生改变的时候,props会对应发生改变) 基本使用案例:
props参数是响应式的,但是通过解构的方式去获取props里面的数据,会消除数据的响应式,通过 toRefs对props进行包裹,可实现解构后的数据仍具有响应式的特点。
context
context是一个js普通对象,不具有响应式的特点,里面有组件的三个属性:
- attrs: 非响应式对象 如组件的id class 等
- slot: 插槽
- emit : 方法
由于暂时还没这么用过这些属性,所以现只是列举,等后期在项目中被使用,再进行进一步说明。
setup的注意点
- 在setup函数中,不可以调用this,在setup函数中不存在组件实例的概念。
- 在setup函数中去调用生命周期的钩子时,相对于Vue2而言,在生命周期钩子函数名字前面多了on。
- 在setup函数中,created、beforeCreated生命周期函数都可在此进行编写。
数据的响应式--ref、reactive
基本使用
在Vue2中,我们是直接通过在data中编写数据,实现数据的响应式,但是在Vue3中由于使用了Composition API,因此在Vue3中通过 reactive、ref来实现数据的响应式。 案例如下:
reactive的实现原理是使用了proxy代理,直接通过 data.属性的方式就可以获取,一般用于对对象类型的数据,ref是用于定义响应式的字符串、数值等简单的数据类型,需要通过 data。value的方式获取。
ref、reactive对比
- 对于原始类型,只可以使用ref,如果使用reactive Vue3会报警告,源码中,在使用reactive函数对数据进行包裹时,会对是不是对象进行判断 不是对象,报警告, 直接返回,数据也不会具有响应性。
- ref是在reactive基础上进行了一层包裹。
- ref定义的数据在script中通过 .value的方式来获取,reactive直接使用。
- ref对对象进行整体的赋值,且赋值后的对象依旧具有响应式,但是reactive包裹的对象重新赋值后不再具有响应式。
ref的实践:
重新赋值后的对象依旧具有响应式,当数据发生改变时,模板中的数据会跟着改变。
reactive实践:
toRef、toRefs使用以及对比
存在的意义
toRef、toRefs的目的:为了解决响应式对象被解构后,不再具有响应式的问题,通过toRef、toRefs将解构出来的property重新具有响应式。
toRef的使用
为源响应式对象上的某个 property 新创建一个 ref。ref 被传递,保持对其源 property 的响应式连接,无论是源的property的改变还是新的被创建的值的改变,都会被同步。
toRefs的使用
主要针对对象中的所有的property,对象的每个 property 都是指向原始对象相应 property的ref。
两者对比
实际上,toRefs的存在是因为toRef只能对于响应式数据中的某个属性进行响应式的添加,而当响应式的对象里面的键值对比较多的时候,如果对象中所有的属性都要变成响应式的,一个个通过toRef进行添加比较繁琐,所以作者给我们封装了toRefs函数,实现批量的完成转换。
因此两者的区别在于:toRef针对特定键值对,toRefs针对批量的数据。
Vue3源码中toRefs对对象进行了遍历,将里面的属性放入到toRef函数中进行处理。