vue3.0 在 7 月公布了 rc 版本,vue-cli4.5 后也反对抉择 vue3 作为备选版本能够体验了,vue3 的正式版本相必也不远了。学不动了呀!!!!
相比 vue2.0 版本 (Option API),Composition API(组合 API)算是 3.0 的重大变更之一了。
概述
Composition API 次要灵感来源于 React Hooks,目标是通过一组低侵入式的、函数式的 API,使得咱们可能更灵便地「 组合 」组件的逻辑。
示例
<template>
<div>{{count}}</div>
<button @click="addCount"> 增加 </button>
</template>
<script lang="ts">
import {defineComponent, ref, onMounted} from 'vue';
export default defineComponent({
name: 'App',
setup () {const count = ref(0)
const getCount = () => {count.value = Math.floor(Math.random() * 10)
}
const addCount = () => {count.value++}
onMounted(() => {getCount()
})
return {
count,
addCount
}
}
});
</script>
“
Composition API 顾名思义就是不再传入 data、mounted 等参数,通过引入的 ref、onMounted 等办法实现数据的双向绑定、生命周期函数的执行。
为什么须要
1. 在组件比较复杂的状况下,能够将逻辑代码合到一起去,而不会被 option 强行分隔。这进步了代码品质的下限,同时也拉低了代码品质的上限。来自官网的一张比照图:
2. 更好的进行复用。
在 vue2 中,想要复用局部逻辑的代码,都是通过 mixin 进去。但 mixin 进去的内容实际上很不直观,而且雷同命名会被笼罩。而通过 composition API,因为所有的办法都是引入的,能够将独自某个逻辑进行封装。例如对发送验证码倒计时性能进行封装。
<template>
<input type="number" placeholder="请输出验证码">
<button v-if="count">{{count}} 秒后可从新发送 </button>
<button v-else @click="startCount"> 发送验证码 </button>
</template>
<script lang="ts">
import {defineComponent, ref, reactive} from 'vue';
const userCountDown = () => {const count = ref(0)
const countDown = (num: number) => {
count.value = num
num--
if (num > 0) {setTimeout(() => {countDown(num)
}, 1000)
}
}
const startCount = () => {
// get verifyCode
countDown(60)
}
return {count, startCount}
}
export default defineComponent({
name: 'Home',
setup () {const { count, startCount} = userCountDown()
return {count, startCount}
}
});
</script>
3. 更好的 typescript 反对。不会再往 vue 原型上增加很多内容,而是通过引入的形式,类型定义会更清晰。
setup
setup 是 vue 新增的一个选项,它是组件内应用 Composition API 的入口。setup 是在创立 vue 组件实例并实现 props 的初始化之后执行。因为 setup 会在 option api 解析之前被调用,所以 setup 中的 this 会与 options 中得齐全不一样。为了防止凌乱,在 setup 中不应用 this。同时 setup 返回的值,能够在模板和其余 option 中应用。从设计上来说,vue 官网是将所有的事件在 setup 里实现。setup 返回值连贯的是 template 模板与办法。
ref、reactive
既然不在传入 data,那么将数据创立和监听响应式就须要通过 vue 裸露进去的性能 ref 或 reactive。两者有所区别,ref 用于根底赋值类型的数据,而 reactive 用于援用类型的数据。
其中根底赋值类型的值,在 setup 办法中,须要用 .value 的形式进行获取和批改。因为赋值类型的值如果 return 进来返回值,就失去了数据的双绑定。然而在 template 中,能够进行间接拜访。
<template>
<div>{{count}}
<button @click="changeCount"> 增加 </button>
</div>
<div> 学生的姓名是:{{student.name}}</div>
<div> 学生的年龄是:{{student.age}}
<button @click="changeStudentAge(20)"> 增加 </button>
</div>
</template>
<script lang="ts">
import {defineComponent, ref, reactive} from 'vue';
export default defineComponent({
name: 'Home',
setup () {const count = ref(0)
const changeCount = () => {count.value = count.value + 1}
const student = reactive({
name: 'Bob',
age: 12
})
const changeStudentAge = (age: number) => {student.age = age}
return {
count,
changeCount,
student,
changeStudentAge
}
}
});
</script>
computed 与 watch
<template>
<div>{{count}}</div>
<div>{{doubleCount}}</div>
<button @click="addCount"> 增加 </button>
</template>
<script lang="ts">
import {defineComponent, ref, computed, watchEffect, watch} from 'vue';
export default defineComponent({
name: 'App',
setup () {const count = ref(0)
watch(count, () => {// 如多个则用数组的形式传入 [count, count1]
console.log('watch', count.value)
})
watchEffect(() => {console.log('watchEffect', count.value)
})
const addCount = () => {count.value++}
const doubleCount = computed(() => {return count.value * 2})
return {
count,
doubleCount,
addCount
}
}
});
</script>
watch 与 watchEffect 的差异是,watchEffect 会立马执行,执行中被读取的响应式 数据会被观测。而 watch 只有在 watch 对象有变动时才会执行。
生命周期
beforeCreate
-> 应用setup()
created
-> 应用setup()
beforeMount
->onBeforeMount
mounted
->onMounted
beforeUpdate
->onBeforeUpdate
updated
->onUpdated
beforeDestroy
->onBeforeUnmount
destroyed
->onUnmounted
errorCaptured
->onErrorCaptured