众所周知,在2019.10.5日发布了Vue3.0
预览版源码,但是预计最早需要等到 2020 年第一季度才有可能发布 3.0 正式版。
但是我们可以先使用@vue/composition-api这个插件提前体验vue3.0的新特性,写起来还是挺方便的
主要解决了下面这些问题
ts
实现了类型推断,新版api全部采用普通函数,在编写代码时可以享受完整的类型推断(避免使用装饰器)首先,要先安装@vue/compoisition-api这个插件,并注册插件
import Vue from 'vue'
import Composition from '@vue/composition-api'
Vue.use(Composition)
然后,在使用到的组件中再按需引入相关新API
import { ref, reactive, computed, onMounted } from "@vue/composition-api";
接下来,我们看看新的API
setup
setup
是新的组件选项,它充当在组件内部使用入口点。即新特性的API入口是这个setup选项函数
调用时间
setup
创建组件实例时,在初始组件解析后立即调用。在生命周期方面,它在beforeCreate
之后,created
之前被调用(2.x)。
模板使用
如果setup
返回一个对象,则该对象的属式将合并到组件模板的渲染上下文中:
{{ count }} {{ object.foo }}
请注意,setup
在模板中访问时,从ref返回的引用将自动解包,因此模板中使用不需要.value
。在setup
中访问必须需要.value
reactive
取得一个对象并返回原始对象的响应式代理。这等效于2.x的Vue.observable()
。
const obj = reactive({ count: 0 })
响应式转换是“深度”的:它影响所有嵌套的属式。在基于ES2015代理的实现中,返回的代理不等于原始对象。建议仅与响应式代理一起使用,并避免依赖原始对象。
ref
接受一个值并返回一个响应式且可变的ref对象。ref对象具有.value
指向内部值的单个属式。
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
如果将一个对象分配为ref的值,则该reactive
方法会使该对象具有高度的响应式。
模板访问
当ref作为渲染上下文(从中返回的对象setup()
)的属式返回并在模板中进行访问时,它会自动展开为内部值。无需.value
在模板中附加:
{{ count }}
响应式对象中的访问
当ref被访问或作为响应对象的属式进行更改时,它会自动展开为内部值,因此其行为类似于普通属式:
const count = ref(0)
const state = reactive({
count
})
console.log(state.count) // 0
state.count = 1
console.log(count.value) // 1
请注意,ref
内部值可以被覆盖/替换:
const otherCount = ref(2)
state.count = otherCount
console.log(state.count) // 2
console.log(count.value) // 1
isRef
检查值是否是ref
的引用对象。
const unwrapped = isRef(foo) ? foo.value : foo
toRefs
将响应对象转换为普通对象,其中结果对象上的每个属式都是指向原始对象中相应属式的ref;常用于reactive
解构/扩展时使用。
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
/*
Type of stateAsRefs:
{
foo: Ref,
bar: Ref
}
*/
// The ref and the original property is "linked"
state.foo++
console.log(stateAsRefs.foo) // 2
stateAsRefs.foo.value++
console.log(state.foo) // 3
toRefs
从组合函数返回反应对象时,此函数很有用,以便使用组件可以对返回的对象进行解构/扩展而不会失去响应式:
function useFeatureX() {
const state = reactive({
foo: 1,
bar: 2
})
// logic operating on state
// convert to refs when returning
return toRefs(state)
}
export default {
setup() {
// can destructure without losing reactivity
const { foo, bar } = useFeatureX()
return {
foo,
bar
}
}
}
computed
使用getter函数,并为getter返回的值返回一个不变的响应式ref对象。
const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // error
或者,它可以使用具有get
和set
功能的对象来创建可读写的ref对象。
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => { count.value = val - 1 }
})
plusOne.value = 1
console.log(count.value) // 0
import { onMounted, onUpdated, onUnmounted } from 'vue'
const MyComponent = {
setup() {
onMounted(() => {
console.log('mounted!')
})
onUpdated(() => {
console.log('updated!')
})
onUnmounted(() => {
console.log('unmounted!')
})
}
}
这些生命周期钩子注册功能只能在期间同步使用setup()
(只能在setup()
中调用),因为它们依赖于内部全局状态来定位当前活动实例(当前setup()
正在被调用的组件实例)。在没有当前活动实例的情况下调用它们将导致错误。
2.x生命周期选项和3.0Composition API之间的映射
beforeCreate
setup()
created
setup()
beforeMount
-> onBeforeMount
mounted
-> onMounted
beforeUpdate
-> onBeforeUpdate
updated
-> onUpdated
beforeDestroy
-> onBeforeUnmount
destroyed
-> onUnmounted
errorCaptured
-> onErrorCaptured
介绍完了compoisitionAPI的基本用法,接下来我们就可以开始愉快的体验Vue3.0的用法啦
详细代码在https://github.com/wangchaochuan/composition-todolist.git