Vue3的组合式API

组合式API和选项式API的区别

组合式API能够对逻辑关注点进行聚合,把逻辑相关的代码写到一起。选项式API把数据(data),计算属性(cpmputed),监听(watch),方法(methods)分离,当对其中的逻辑进行新增和修改时,需要跳转去定位代码修改的地方,开发的时候项目代码会来回跳转。

组合式API有一个入口方法setup,这样会引入一个问题,页面的代码都集中在一个setup方法中,会导致该方法中存在大量的代码,可以考虑到采用MVC的模式,将业务代码抽离出来单独的js文件,setup中只保留交互代码,实现业务和视图的代码分离,以便于项目更好的维护。

入口

上面提到setup选项式组合式API的主入口文件,他的执行顺序是在props解析之后,组件创建之前。

export default {  
    beforeCreate() {    
        console.log("beforeCreate 执行");  
    },  
    setup() {    
        console.log("setup 执行");  
    }
};
// 执行结果 ===> setup 先于beforeCreate执行
// setup 执行 
// beforeCreate 执行
复制代码

因为setup执行的时候,vue组件还没有被执行,所以在setup中不能使用this

创建响应式变量

ref

vue中提供了一个ref函数,可以将基本数据类型转换为ref响应式对象,ref对象会带有一个value属性,返回绑定的值。在js中,基本数据类型是通过值传递的而不是通过引用传递的,所以需要把基本数据类型封装成ref响应式对象来传递。

<template>
    <h3>{{ counter }}</h3>
</template>
<script>
import { ref } from "vue";
export default {  
    setup() {    
        let counter = ref(100);    
        return {      
            counter,    
        };  
    },
};
</script>
复制代码

如上面代码所示,绑定counter值以及返回的ref对象。ref也可以传入引用类型对象,vue会把对象的值转换成一个proxy对象

reactive

返回一个响应式副本(Proxy代理对象)

export default {  
    setup() {
        // 定义一个普通对象obj,obj中有两个属性a,b
        let obj = { a: 1, b: 2,};    
        let refObj = reactive(obj);    
        console.log(refObj);       
        return { refObj };  
    }
};
复制代码

reactive中使用解构赋值的注意事项

es6中的解构赋值是非响应式的

// 声明一个obj对象有 a,b两个属性值
let obj = {  a: 1,  b: 2}
// 对obj对象进行解构赋值
let { a, b } = obj
// 打印a,b
console.log('a======>' + a) // 1
console.log('b======>' + b) // 2
// 对obj对象a,b属性重新赋值
obj.a = 'a'
obj.b = 'b'
// 打印a,b 并没有因为obj对象的属性值发生变化而变化
console.log('a======>' + a) // ===> 1,目标是这里应该输出a
console.log('b======>' + b) // ===> 2 目标是这里应该输出b
// 解:a,b值进行解构赋值之后,不再随着目标对象obj中属性的变化而变化了,
// 因为a,b为基本数据类型,解构赋值是通过赋值操作而不是内存地址的变化的


// template
<h3>{{ a }}</h3> // 1 a值实际已经变更为"a"了,但页面没有发生变化
<h3>{{ b }}</h3> // 2
// js
export default {  
    setup() {    
        let obj = { a: 1, b: 2 };    
        let refObj = reactive(obj);    
        console.log(refObj);    
        let { a, b } = refObj;    
        console.log(a);    
        console.log(b);    
        refObj["a"] = "a";    
        return { a, b };  
    }
};
复制代码

toRefs

vue中引入了toRefs方法,顾名思义,就是把obj对象中的每个值进行遍历,使每个值都变成ref响应式对象。

// template
<h3>{{ a }}</h3> // a 正确  
<h3>{{ b }}</h3> // 2
// js
export default {  
    setup() {    
        let obj = {      a: 1,      b: 2,    };    
        let refObj = reactive(obj);    
        console.log(refObj); // Proxy {a: 1, b: 2} 
        let { a, b } = toRefs(refObj); // toRefs是新增的    
        console.log(a); // ObjectRefImpl {_object: Proxy, _key: "a", __v_isRef: true} 
        console.log(b); // ObjectRefImpl {_object: Proxy, _key: "b", __v_isRef: true}
        refObj["a"] = "a";    
        return { refObj, a, b };  
    }
};
复制代码

ref和reactive的异同点

相同点:

是vue3中定义响应式对象的两个函数

不同点:

定义数据类型

  ref可以定义基本数据类型,也可以定义引用数据类型(object),当因为引用数据类型时,会把传入的目标对象转换成一个proxy代理对象

  reactive只能定义引用数据类型,定义基本数据类型会报出警告

建议ref定义基本数据类型,reactive定义引用数据类型

export default {  
    setup() {    
        let num1 = ref(1);    
        let num2 = reactive(2);    
        let obj1 = ref({ a: 1 });    
        let obj2 = reactive({ a: 2 }); // warning ===> value cannot be made reactive: 2    
        console.log(num1);    // RefImpl {_rawValue: 1, _shallow: false, __v_isRef: true, _value: 1}    
        console.log(num2); // 2 会告警waring   
        console.log(obj1); // RefImpl {_rawValue: {…}, _shallow: false, __v_isRef: true, _value: Proxy} 
        // 注意:这里的value是Proxy了,而ref传入基本数据类型,value为基本数据类型的值    
        console.log(obj2); // Proxy {a: 2}    
        return { num1, num2, obj1, obj2 };  
    }
};
复制代码

生命周期钩子

选项式API中的生命周期钩子函数在setup中都可以使用,只是命名有所区别,当钩子被组件调用时,生命周期中的钩子函数会执行。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享