常用的Composition API
composion API 是一组api的组合,因此也叫组合API。包括:setup、ref、reactive、watchEffect等等。参考这里
setup
Vue3.x 新增的一个选项, 组件内使用 Composition API的入口
setup 执行时机是在 beforeCreate 之前执行
此函数
返回的对象
会被合并到组件上下文中
setup参数
js
export default defineComponent ({
// props 父组件传递的props
// context 提供Vue实例上常用的属性:attrs、slot、emit
setup(props, context) {
// const { name } = props // 结构会使props丢失响应性
},
})
reactive、ref 与 toRefs
reactive
: 用于处理对象的双向绑定
ref
: 用于处理基本类型的双向绑定(但也可以处理对象的双向绑定)
js
setup() {
const obj1 = reactive({ count:1, name: 'chaos' })
const obj2 = ref({ count:1, name: 'chaos' })
setTimeout(() =>{
obj2.value.count += 1
obj2.value.name = 'chaos'
}, 2000)
return {
obj1,
obj2
}
}
toRefs
: 用于将一个 reactive 对象转化为属性全部为ref对象的普通对象
js
<template>
<div class='homePage'>
<p>第 {{ year }} 年</p>
<p>姓名: {{ nickname }}</p>
<p>年龄: {{ age }}</p>
</div>
</template>
<script>
import { defineComponent, reactive, ref, toRefs } from 'vue'
export default defineComponent({
setup() {
const year = ref(0)
const user = reactive({ nickname: 'chaos', age: 18, gender: '男' })
setInterval(() => {
year.value++
user.age++
}, 1000)
return {
year,
// ... user, // 直接解构可以取到值, 但是会丢失响应性
...toRefs(user), // 使用reRefs
}
},
})
</script>
watch & watchEffect
watch
watch(source, callback, [{options}])
source: 用于指定要侦听的响应式变量. 支持string,Object,Function,Array
callback: 执行的回调函数
options:支持 deep、immediate 和 flush 选项
watch监听ref & reactive定义的对象
js
import {
defineComponent, reactive, ref, toRefs, watch
} from 'vue'
export default defineComponent({
setup() {
const data1 = reactive({ age: 18 })
const data2 = ref(0)
setTimeout(() => {
data1.age += 1
data2.value += 2
}, 1000)
// 监听reactive
watch(() => data1.age, (curAge, preAge) => {
console.log('data1新值:', curAge, 'data1老值:', preAge)
})
// 监听ref
watch(data2, (curAge, preAge) => {
console.log('data2新值:', curAge, 'data2老值:', preAge)
})
// 同时监听【返回一个函数,可以停止监听】
const stopWatch = watch(
[() => data1.age, data2],
// 前者是新值构成的array,后者是旧值构成的array
([data1NewVal, data2NewVal], [data1OldVal, data2OldVal]) => {
console.log(data1NewVal, data1OldVal)
console.log(data2NewVal, data2OldVal)
},
{
deep: true, // 深度监听对象属性
immediate: true // 初次监听
// flush: // 暂未搞明白作用
}
)
stopWatch() // 调用后停止监听对应的侦听器(上面由于immediate属性会执行一次,然后立即停止监听,后面数据变更也不会执行了)
return {
...toRefs(data1)
}
}
})
watchEffect
- watchEffect会立即执行传入的函数,并响应式追踪其依赖,并在其依赖变更时重新运行该函数
js
import { defineComponent, ref, reactive, watchEffect } from 'vue'
export default defineComponent({
setup() {
const state = reactive({ nickname: 'xiaofan', age: 20 })
let year = ref(0)
setInterval(() => {
state.age++
year.value++
}, 1000)
// 自动收集里面的响应式对象然后监听
watchEffect(() => {
console.log(state.age)
console.log(year.value)
})
}
})
computed
与vue2中用法类似
js
import { defineComponent, ref, computed } from 'vue'
export default defineComponent({
setup() {
// 一般用法
const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
// get/set用法
const count2 = ref(10)
const plusOne2 = computed({
get: () => {
console.log('get:', count2.value)
return count2.value + 1
},
set: (val) => {
console.log('set:', val)
count2.value = val - 1
}
})
plusOne2.value = 1
console.log(plusOne2.value) // 1
}
})
生命周期
vue2 与 vue3生命周期对比
注意
由于更贴近语义化,beforeDestroy变更成beforeUnmount; destroyed变更为unmounted
同一阶段的钩子,在setup中的钩子优先与options里的调用.
新增钩子函数
onRenderTriggered
和onRenderTricked
用于调试代码
js
import {
defineComponent, onBeforeMount, onMounted, onRenderTriggered, reactive
} from 'vue'
export default defineComponent({
mounted() {
console.log('mounted') // 3
},
setup() {
onMounted(() => {
console.log('------onMounted-----') // 2
})
onBeforeMount(() => {
console.log('------onBeforeMount-----') // 1
})
onRenderTriggered((e) => {
console.log('------onRenderTriggered-----: ', e) // test.a每次变化event都会被打印(如果没有return test就不会打印任何东西...)
})
const test = reactive({ a: 1 })
setInterval(() => {
test.a += 2
}, 1000)
return {
test
}
}
})