Vue3 Composition-API

Wen前端严选 2020-11-09 08:17:30
vue API vue3 composition-api composition


Vue3 Composition-API

本文将简要介绍一下当前Vue3组合式API的使用方式及意义。

当然,该调侃的时候还是要调侃一下的,嘿嘿

image

1.组件状态

以2.x的使用习惯为例,我们最关心的就是双向数据绑定的使用形式:

<template>
<button @click="increment">
当前是: {{ state.count }}, 双倍是: {{ state.double }}
</button>
</template>
<script>
import {
computed,
reactive
} from 'vue'
export default {
setup() {
const state = reactive({
count: 1,
double: computed(() => state.count * 2)
})
function increment() {
state.count++;
}
return {
state,
increment
}
}
}
</script>

reactive,接收一个普通对象然后返回该对象的响应式代理,等同于2.x中的Vue.observable()

响应式转换是“深层的”:会影响对象内部所有嵌套属性。基于Proxy的实现,返回的代理对象 不等于原始对象。在使用时应尽量使用代理对象而避免依赖原始对象。

Vue响应式系统的精髓:当在组件中从data()返回一个对象,,内部实质上是通过调用reactive()使其变为响应式的。

computed, 传入一个getter函数,返回一个不可手动修改的ref对象;

computed的另一种使用方式是,传入一个带有get和set的函数对象,创建一个可以手动修改的计算状态;
const double = computed({
get: () => count.value,
set: (val) => {
count.value = val * 2
}
})

watchEffect对执行过程中用到的响应式状态作为依赖进行跟踪(与2.x中的watch选项类似,但是它不需要把被依赖的数据源和副作用回调分开),并在依赖变更时重新运行该函数。当组件的setup()或者生命周期钩子被调用时,watchEffect会被链接到该组件的生命周期,并在组件卸载自动停止

新的ref,接受一个参数值并返回一个响应式且可改变的ref对象。ref对象拥有一个指向内部值的单一属性,即.value

<template>
<button @click="increment">
数字增加
</button>
<p>{{num}}</p>
</template>
<script>
import {
ref
} from 'vue'
export default {
setup() {
const num = ref(0);
function increment() {
num.value ++;
}
return {
increment,
num
}
}
}
</script>
如果传入 ref 的是一个对象,将调用 reactive 方法进行深层响应转换。

readonly,传入一个对象或者ref,返回一个原始对象的只读代理。即使是深层对象,内部的任何属性也都是只读的。

const original = reactive({count: 0});
const only = readonly(original);
watchEffect(() => { //依赖追踪
console.log(only.count);
})
original.count ++; //这里的修改会触发only的监测
only.count ++; //无法修改并发出警告

至此简介已经覆盖了组件的纯状态层面:响应式状态、计算状态和用户输入时的状态变更。接下来将介绍生命周期及组合式API。

2.生命周期钩子

import {
onMounted, onUpdated, onUnmounted
} from 'vue'
setup() {
//...
onMounted(() => {
console.log('组件已经被挂载了!')
})
onUpdated(() => {
console.log('组件已经更新了!')
})
onUnmounted(() => {
console.log('组件已经被卸载了!')
})
//...
}

如上例所示,生命周期钩子函数只能注册在setup函数中,因为它们依赖于内部的全局状态来定位当前组件实例(即正在调用setup()的组件实例),不在当前组件下调用会抛出错误。

组件实例上下文都是在生命周期钩子同步执行期间设置的,所以在卸载组件时同步创建的侦听器和计算状态也会被删除。

除上例所示外,还有钩子:onBeforeMount、onBeforeUpdate、onBeforeUnmount、onErrorCaptured以及新增的钩子onRenderTracked、onRenderTriggered。

3.组合式API VS 选项式API

有组织的代码最终让代码更可读,更易于理解。在组件中看到的是“如何处理这个X、Y和Z”,而不再是“这个组件有这些data、这些property、这些methods”,即更加关心“这个组件是要干什么的”。基于选项的API写出来的代码自然不能很好地表述出组件的功能。

以下图为例,当以选项式API进行开发时,通过阅读选项中的代码梳理出各个逻辑是非常困难的,因为与逻辑相关的代码都分散在各处。这种碎片化开发使得后期阅读和维护变得相当困难,选项的强行分离为逻辑的理解抬高了门槛,我们不得不在各个代码块之间来回跳转,以找到相关代码。

image

相反,如果能把相同的逻辑点代码放在一起的话,那将是再好不过的事情了。这正是组合式API要做的事情。这种模式让该组件的逻辑点最终成为了良好的解耦函数:每个逻辑点代码块都被组合进一个函数中,大大减少了来回跳转的情况。你还可以把这些组合函数折叠起来,更加易于浏览:

image

除了提取逻辑外,另一个变化就是this的引用。

setup()中的this与2.x中的this完全不同,同时在setup()和2.x中使用this将会造成混乱。这里就需要再介绍一下setup函数了:

  • 创建组件实例时,先初始化props,紧跟着就要调用setup函数,并且将在beforeCreate之前被调用;
  • setup返回一个对象,对象的属性将会被合并到组件模板的上下文中;
  • setup的第一个参数,就是props;
  • setup的第二个参数,提供了上下文对象,并且从2.x中选择性暴露了一些属性。
export default {
props: {
name: string,
age: number
},
setup(prop,context) {
watchEffect(() => {
console.log(`My name is ${props.name},I'm ${props.age} years old.`)
});
context.attrs
context.slots
context.emit
}
}

当提取逻辑点时,逻辑方法也可接收参数props和context:

const checkUsername = (props, context) => {
onMounted(() => {
console.log(props)
context.emit('event', 'payload')
})
}
export default {
setup (props, context) {
checkUsername(props, context)
}
}

4.最后

希望本文能帮助更好地了解Composition API将如何改变我们的编码方式,在后续的开发活动中,提高代码的阅读性,提高内聚耦合度,毕竟这才是成熟的程序员要做的。

image

版权声明
本文为[Wen前端严选]所创,转载请带上原文链接,感谢
https://segmentfault.com/a/1190000037765646

  1. [front end -- JavaScript] knowledge point (IV) -- memory leakage in the project (I)
  2. This mechanism in JS
  3. Vue 3.0 source code learning 1 --- rendering process of components
  4. Learning the realization of canvas and simple drawing
  5. gin里获取http请求过来的参数
  6. vue3的新特性
  7. Get the parameters from HTTP request in gin
  8. New features of vue3
  9. vue-cli 引入腾讯地图(最新 api,rocketmq原理面试
  10. Vue 学习笔记(3,免费Java高级工程师学习资源
  11. Vue 学习笔记(2,Java编程视频教程
  12. Vue cli introduces Tencent maps (the latest API, rocketmq)
  13. Vue learning notes (3, free Java senior engineer learning resources)
  14. Vue learning notes (2, Java programming video tutorial)
  15. 【Vue】—props属性
  16. 【Vue】—创建组件
  17. [Vue] - props attribute
  18. [Vue] - create component
  19. 浅谈vue响应式原理及发布订阅模式和观察者模式
  20. On Vue responsive principle, publish subscribe mode and observer mode
  21. 浅谈vue响应式原理及发布订阅模式和观察者模式
  22. On Vue responsive principle, publish subscribe mode and observer mode
  23. Xiaobai can understand it. It only takes 4 steps to solve the problem of Vue keep alive cache component
  24. Publish, subscribe and observer of design patterns
  25. Summary of common content added in ES6 + (II)
  26. No.8 Vue element admin learning (III) vuex learning and login method analysis
  27. Write a mini webpack project construction tool
  28. Shopping cart (front-end static page preparation)
  29. Introduction to the fluent platform
  30. Webpack5 cache
  31. The difference between drop-down box select option and datalist
  32. CSS review (III)
  33. Node.js学习笔记【七】
  34. Node.js learning notes [VII]
  35. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  36. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  37. 【JQuery框架,Java编程教程视频下载
  38. [jQuery framework, Java programming tutorial video download
  39. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  40. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  41. 【Vue,阿里P8大佬亲自教你
  42. 【Vue基础知识总结 5,字节跳动算法工程师面试经验
  43. [Vue, Ali P8 teaches you personally
  44. [Vue basic knowledge summary 5. Interview experience of byte beating Algorithm Engineer
  45. 【问题记录】- 谷歌浏览器 Html生成PDF
  46. [problem record] - PDF generated by Google browser HTML
  47. 【问题记录】- 谷歌浏览器 Html生成PDF
  48. [problem record] - PDF generated by Google browser HTML
  49. 【JavaScript】查漏补缺 —数组中reduce()方法
  50. [JavaScript] leak checking and defect filling - reduce() method in array
  51. 【重识 HTML (3),350道Java面试真题分享
  52. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  53. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  54. [re recognize HTML (3) and share 350 real Java interview questions
  55. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  56. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  57. 【重识 HTML ,nginx面试题阿里
  58. 【重识 HTML (4),ELK原来这么简单
  59. [re recognize HTML, nginx interview questions]
  60. [re recognize HTML (4). Elk is so simple