前言
在今年 1 月 20 号,尤大在 The Vue Point 中发布文章 Vue 3 as the New Default,文中宣称 Vue 3 将在 2 月 7 号后成为正式的默认版本。本文将梳理 Vue 3 在使用上和 Vue 2 的部分差异点,助你短时间内快速上手。
Vue 3 用法
代码示例模板
本文代码示例统一使用 vue.esm-browser.js,其他构建版本可以通过 cdn.jsdelivr.net/npm/vue@3.0… 链接获取。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app"></div>
<script type="module">
import { xxx } from './js/vue.esm-browser.js'
// do something...
</script>
</body>
</html>
组合式 API (Composition API)
composition api 以 setup 函数作为入口。
createApp({
setup(props, context) {
const position = reactive({
x: 0,
y: 0,
});
return {
position,
};
},
mounted() {
setTimeout(() => {
this.position.x = 100;
}, 2000);
},
}).mount('#app');
setup函数是在data、computed、methods被解析前执行,此时组件实例并未创建,不能使用 this 指向(值为 undefined)。props是组件外部传递的参数,它是一个响应式对象。context包含attrs、emit、slots等成员。setup函数的返回值是一个对象,可以在模板、computed中使用。
生命周期钩子
在 setup 函数中使用:
| 选项式 API | Hook inside setup |
|---|---|
beforeCreate | Not needed* |
created | Not needed* |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
activated | onActivated |
deactivated | onDeactivated |
由于 setup 函数的调用时机是在 beforeCreate 和 created 之间,所以不再需要这两个个钩子,其余的生命周期钩子均可以在 setup 函数以 on + 钩子名称 名称使用。
function useMousePosition() {
const position = reactive({
x: 0,
y: 0,
});
const update = e => {
position.x = e.pageX;
position.y = e.pageY;
}
onMounted(() => {
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
window.removeEventListener('mousemove', update)
})
return position;
}
reactive
将一个对象转换成响应式对象,转换后可在模板中使用。
当尝试解构一个响应式对象时,解构出来的属性值不会触发视图更新。解构后等同于创建了局部变量,而局部变量未被设置成响应式对象,它是不会触发视图更新。解决方式就是使用
toRefs将该对象的所有属性值都设置成响应式对象。
toRefs
将目标对象中的所有属性值设置成响应式对象,设置后的属性对象包含一个 value 属性,value 属性包含有 getter/setter 函数。
ref
ref 函数会根据参数类型的不同,有以下 2 中处理情况:
- 参数为基础类型,将基础类型转换成响应式对象。
- 参数为对象,调用 reactive 函数将其转换成响应式对象。
const count = ref(0);
computed
computed 参数是一个函数,返回值是一个不可变对象,直接在模板中使用。
const unfinshedCount = computed(() => {
return todos.filter(item => !item.isFinished).length
})
watch
watch 有 3 个参数,参数一为监听数据,参数二为监听回调函数,参数三为 deep、immediate 选项设置。
watch(question, async (newVal, oldVal) => {
const response = await fetch('https://www.yesno.wtf/api')
const data = await response.json()
answer.value = data.answer
imgUrl = data.image
})
watchEffect
watch 函数的简化版本,监听 setup 函数内响应式数据的变化,它的返回值是一个函数,调用后可停止监听。
setup() {
const count = ref(0);
const stop = watchEffect(() => {
console.log(count.value)
})
return {
count,
stop,
increase: () => {
count.value++
}
}
}