https://segmentfault.com/a/1190000038236423
setup函数
- 使用Composition API 的入口
- 在beforeCreate之前调用
- 在setup中没有this,为undefined
- 属性或者方法需要return出去,外部才能访问
- setup函数只能是同步,不能异步
其实 setup 函数还有两个参数,分别是 props 、context,前者存储着定义当前组件允许外界传递过来的参数名称以及对应的值;后者是一个上下文对象,能从中访问到 attr 、emit 、slots
其中 emit 就是我们熟悉的Vue2中与父组件通信的方法,可以直接拿来调用
reactive ref
reactive 接收一个对象,返回该对象的响应式代理
ref 也是接收一个参数并返回一个响应式且可改变的 ref 对象,一般参数是基础类型,比如数值或字符串等。如果传入的参数是一个对象,将会调用 reactive 方法进行深层响应转换。ref 对象拥有一个指向内部值的单一属性 .value,即当你要访问它的值时,需要 .value 拿到它的值。但是如果是在 setup 中返回且用到模板中时,在 {{}} 里不需要加 .value 访问,在返回时已经自动解套。
//reactiveconst state = reactive({count: 0,str: 'test'})//ref 需要加上value才能获取const num = ref(1);const numadd =()=>{num.value++}
toRef
toRef 是将某个对象中的某个值转化为响应式数据,其接收两个参数,第一个参数为 obj 对象;第二个参数为对象中的属性名。
<script>// 1. 导入 toRefimport {toRef} from 'vue'export default {setup() {const obj = {count: 3}// 2. 将 obj 对象中属性count的值转化为响应式数据const state = toRef(obj, 'count')// 3. 将toRef包装过的数据对象返回供template使用return {state}}}</script>
ref是对传入数据的拷贝;toRef是对传入数据的引用ref的值改变会更新视图;toRef的值改变不会更新视图
toRefs
了解完 toRef 后,就很好理解 toRefs 了,其作用就是将传入的对象里所有的属性的值都转化为响应式数据对象,该函数支持一个参数,即 obj 对象。
<script>// 1. 导入 toRefsimport {toRefs} from 'vue'export default {setup() {const obj = {name: '前端印象',age: 22,gender: 0}// 2. 将 obj 对象中属性count的值转化为响应式数据const state = toRefs(obj)// 3. 打印查看一下console.log(state)}}</script>
toRaw
toRaw 方法是用于获取 ref 或 reactive 对象的原始数据的
getCurrentInstance
我们都知道在Vue2的任何一个组件中想要获取当前组件的实例可以通过 this 来得到,而在Vue3中我们大量的代码都在 setup 函数中运行,并且在该函数中 this 指向的是 undefined,那么该如何获取到当前组件的实例呢?getCurrentInstance 方法获取当前组件实例,然后通过 ctx 属性获取当前上下文,ctx. 
因为 instance 包含的内容太多,所以没截完整,但是主要的内容都在图上了,我们重点来看一下 ctx 和 proxy,因为这两个才是我们想要的 this 的内容

可以看到 ctx 和 proxy 的内容十分类似,只是后者相对于前者外部包装了一层 proxy,由此可说明 proxy 是响应式的
useStore
在Vue2中使用 Vuex,我们都是通过 this.$store 来与获取到Vuex实例,但上一部分说了原本Vue2中的 this 的获取方式不一样了,并且我们在Vue3的 getCurrentInstance().ctx 中也没有发现 $store 这个属性,那么如何获取到Vuex实例呢?这就要通过 vuex 中的一个方法了,即 useStore
// store 文件夹下的 index.jsimport Vuex from 'vuex'const store = Vuex.createStore({state: {name: '前端印象',age: 22},mutations: {……},……})// example.vue<script>// 从 vuex 中导入 useStore 方法import {useStore} from 'vuex'export default {setup() {// 获取 vuex 实例const store = useStore()console.log(store)}}</script>
生命周期
| Vue2 | Vue3 |
|---|---|
| beforeCreate | setup |
| created | setup |
| beforeMount | onBeforeMount |
| mounted | onMounted |
| beforeUpdate | onBeforeUpdate |
| updated | onUpdated |
| beforeDestory | onBeforeUnmount |
| destoryed | unMounted |
<template><div id="app"></div></template><script>// 1. 从 vue 中引入 多个生命周期函数import {onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, unMounted} from 'vue'export default {name: 'App',setup() {onBeforeMount(() => {// 在挂载前执行某些代码})onMounted(() => {// 在挂载后执行某些代码})onBeforeUpdate(() => {// 在更新前前执行某些代码})onUpdated(() => {// 在更新后执行某些代码})onBeforeUnmount(() => {// 在组件销毁前执行某些代码})unMounted(() => {// 在组件销毁后执行某些代码})return {}}}</script>
provide && inject
与 Vue2中的 provide 和 inject 作用相同,只不过在Vue3中需要手动从 vue 中导入
这里简单说明一下这两个方法的作用:
- provide :向子组件以及子孙组件传递数据。接收两个参数,第一个参数是
key,即数据的名称;第二个参数为value,即数据的值 - inject :接收父组件或祖先组件传递过来的数据。接收一个参数
key,即父组件或祖先组件传递的数据名称
watch && watchEffect
watch 和 watchEffect 都是用来监视某项数据变化从而执行指定的操作的,但用法上还是有所区别
watch:watch( source, cb, [options] )
参数说明:
- source:可以是表达式或函数,用于指定监听的依赖对象
- cb:依赖对象变化后执行的回掉函数
- options:可参数,可以配置的属性有 immediate(立即触发回调函数)、deep(深度监听)
接下来再来聊聊 watchEffect,它与 watch 的区别主要有以下几点:
- 不需要手动传入依赖
- 每次初始化时会执行一次回调函数来自动获取依赖
- 无法获取到原值,只能得到变化后的值
