优势

image.png
image.pngimage.png
传统的Vue写法是Options API,把data、methods、生命周期等等都分开,写个东西要上下滚动。

新的compostition API 可以把功能1相关的东西都写在一起

使用

image.png

1、直接使用

vue2.x中的xx.vue

  1. <template>
  2. <!--html -->
  3. </template>
  4. <script>
  5. export default {
  6. name:'test',
  7. components:{}, // 组件
  8. data(){ //数据
  9. return{
  10. o1Data:'功能1的数据',
  11. o2Data:'功能2的数据'
  12. }
  13. },
  14. methods:{ // 函数
  15. o1function(){
  16. //业务1的方法
  17. },
  18. o2function(){
  19. //业务2的方法
  20. },
  21. },
  22. mounted(){ // 生命周期
  23. },
  24. };
  25. </script>
  26. <style>
  27. </style>

vue3.x中的xx.vue

  1. <template>
  2. <!--html -->
  3. </template>
  4. <script>
  5. export default {
  6. import { onMounted } from "vue";
  7. name:'test',
  8. components:{},// 组件
  9. setup() { //组合api
  10. // 功能1
  11. let o1Data = '功能1的数据';
  12. function o1function(){
  13. //业务1的方法
  14. };
  15. // 功能2
  16. let o2Data = '功能2的数据';
  17. function o2function(){
  18. //业务2的方法
  19. };
  20. onMounted(() => { // 生命周期,需要引入
  21. })
  22. return { o1Data, o1function, o2Data, o2function}; //template要用到的变量和函数,要return出去
  23. },
  24. };
  25. </script>
  26. <style>
  27. </style>

也可以只保留数据和如何调用函数,把功能函数放到外面,甚至其他文件中
image.png

2、外部引入

也可以通过外部其他文件
查看 https://www.yuque.com/yejielin/mypn47/ff0z2s

语法糖(简写)

https://github.com/vuejs/rfcs/blob/script-setup-2/active-rfcs/0000-script-setup.md

Vue-组合API 语法糖

注意

image.png
image.png
image.png

setup里面不能使用this,因为找不到实例,没有绑定对象
image.png(by 王红元)

=================

setup 的参数(props , ctx)

用不到的话可以不写参数

image.png

props

image.png

ctx

image.png
image.png

emit:见下 父子组件传递参数
attrs:查看 https://www.yuque.com/yejielin/mypn47/agwuud#XPXZF

父子组件传递参数

查看 https://www.yuque.com/yejielin/mypn47/wsa45l#9elM4

setup 的返回值 return

image.png

如果也有data属性,也有setup的返回值,里面有同名的变量,优先是用setup里的
image.png

setup 执行原理

https://www.yuque.com/yejielin/mypn47/cp5cvf

==================

响应式API

响应式原理

image.png

reactive 响应式对象(重要)

image.png

响应式数据对象,和ref类似,区别就是在setup里面不需要通过.value读取和使用值,直接引用。
他们都是递归监听,如果结构比较大,会影响性能

  1. <template>
  2. <div>{{a}}</div>
  3. </template>
  4. <script>
  5. import { reactive } from "vue";
  6. export default {
  7. setup() {
  8. let a = reactive({
  9. a:0
  10. });
  11. a.a = 2;
  12. return { a };
  13. },
  14. };
  15. </script>

image.png
image.png
image.png
image.png

image.png
那么有没有办法让我们解构出来的属性是响应式的呢?见下toRef

ref 响应式变量(重要)

ref是reference的缩写
image.png
比较简单的变量,在setup里面使用时要通过 a.value 来获得和使用它表示的值。

  1. <template>
  2. <div>{{a}}</div>
  3. </template>
  4. <script>
  5. import { ref } from "vue";
  6. export default {
  7. setup() {
  8. let a = ref(0); // 定义
  9. a.value = 2;
  10. return { a };
  11. },
  12. };
  13. </script>

在template中使用时,正常来说也是要加.value才能获取这个引用的值 ,但是为了方便开发,template中做了一层解包,第一层的不用加.value,后续嵌套在其他对象中的要加
image.png

readonly 数据只读

image.png
image.png
image.png
image.png
无法修改,重新赋值也无效

image.png
image.png

image.png
原理是劫持了proxy的set方法,让他set不到其他任何值就可以了
image.png
image.png

用途

image.png

Reactive判断的API(少)

isProxy 判断是否代理

检查对象是否是由 reactive 或 readonly创建的 proxy,Vue3的响应式都是通过JS的Proxy代理功能实现的。

ref、reactive、readonly都是proxy,原生JS的new Proxy( ) 为false

isRef 判断是否ref

判断值是否是一个ref对象

isReactive 判断是否reactive

readonly 会返回false,但是readonly 包裹着reactive就是true
image.png

检查对象是否是由 reactive创建的响应式代理

如果该代理是 readonly 建的,但包裹了由 reactive 创建的另一个代理,它也会返回 true;

isReadonly 判断是否只读

检查对象是否是由 readonly 创建的只读代理。
image.png

shallowReactive 只监听第一层

创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (深层还是原生对象)。

  1. let x = shallowReactive({
  2. a:'a',
  3. b:{
  4. c:'c'
  5. }
  6. })

shallowReactive,非递归监听的情况下,只会响应式a和b,不会监听b.c

shallowReadonly 第一层只读

image.png
第一层只读,子层虽然可以变化,但是不会更新UI

其他API(少)

toRefs 和 toRef

image.png
相当于{ name : ref , age : ref }

image.png
参数要是reactive对象,才能用。
也可以用state.name,也是响应式的

通常用于解构reactive
image.png

unref 解除响应式

image.png

shallowRef 只监听第一层

  1. <script>
  2. import { shallowRef } from "vue";
  3. export default {
  4. setup(){
  5. let state = shallowRef({})
  6. //接下图,给state.value赋值
  7. return { state }
  8. }
  9. }
  10. </script>

image.png

非递归监听的情况下,只监听第一层a或gf,html模板