目录
一、响应式编程的原理及在vue中的应用
1、手动追踪变量的变化
2、vue中的响应式对象
3、独立的响应式值Ref的应用
二、响应式的计算与监听
1、关于计算变量
2、监听响应式变量
三、组合式API的应用
1、关于setup方法
2、在setup方法中定义生命周期行为。
四、范例
1、常规风格的示例工程开发
2、使用组合式API重构用户列表
响应式的本质是对变量的监听,当监听到变量发生变化时,我们可以做一些预定义的逻辑。例如对于数据绑定技术来说,需要做的是在变量发生改变时及对页面的元素进行刷新。
结果:
两次输出的sum变量的值都是3,虽然从逻辑上理解,sum值得意义是变量a和变量b的值得和,但是当变量a和变量b发生改变时,变量sum的值并不会响应式地进行改变。
如何为sum这类变量增加响应式?在js中,可以使用Proxy对原对象进行包装,从而实现对对象属性设置和获取的监听。
结果:
在vue3.0中引入了组合式API的新特性,这种新特性允许我们在setup方法中定义组件需要的数据和函数,set方法可以在组件被创建前定义组件需要的数据和函数。
测试数据:{{myData.value}}
结果:
为什么页面没有被刷新?这是因为myData对象是我们自己定义的普通js对象,本身没有响应式,对其进行修改也不会同步刷新到页面上,这与我们常规使用组件的data方法返回的数据不同,data方法返回的数据会被默认保存到proxy对象,从而获得响应式。
为了解决上面的额问题,vue3提供了reactive方法,使用这个方法对自定义的js对象进行包装,即可以方便地为其添加响应式。
//定义数据
let myData = Vue.reactive({
value: 0
})
在实际开发中,很多时候我们需要的只是一个独立的原始值,对于独立的原始值,不需要手动将其包装为对象的属性,可以直接使用vue提供的ref方法来定义响应式独立值,ref方法会帮我们完成对象的包装。使用ref方法创建了响应式对象后,在setup方法内要修改数据,就需要对myObject中的value属性值进行修改,value属性值是vue内部生成的,但是对于setup方法导出的数据来说,我们在模板中使用myObject数据已经是最终的独立值,可以直接使用。
测试数据:{{myObj}}
结果:
vue还提供了一个名为toRefs的方法来支持响应式对象的解构赋值。
什么是解构赋值?
const myObj = {
name: 'zs',
age: 20,
sex: '男',
play() {
console.log('打游戏!');
}
}
const { name, age, sex, play } = myObj
console.log(name, age, sex);
play()
测试数据:{{value}}
结果:
改写后的代码可以正常运行,但是已经失去了响应式,对于这种场景,我们可以使用vue中提供的toRefs方法来进行对象的解构,其会自动解构出的变量转换为ref变量,从而获得响应式。
测试数据:{{value}}
结果:
注意,Vue.toRefs解构时,会将解构出的属性设置为key,vue内部会自动创建一个value属性,用于保存解构出的值。要想改变解构出的属性,必需调用 属性.value才能更改其值。
测试结果:{{sum}}
结果:
有时候,当响应式变量发生变化时,我们需要监听其变化行为。在vue3中,watchEffect方法可以自动对其内部用到的响应式变量进行变化监听,由于其原理是在组件初始化时对所有依赖进行收集,因此在使用时无须手动指定要监听的变量。
{{a.value}}
结果:
在调用watchEffect方法时,其会立即执行传入的函数参数,并会追踪其内部的响应式变量,在其变更时再次调用此函数参数。需要注意,watchEffect在setup方法中被调用后,其会和当前组件的生命周期绑定在一起,组件卸载时会自动停止监听,如果需要手动停止监听。
{{a.value}}
watch是一个与watchEffect类似的方法,与watchEffect方法相比,watch方法能够更加精准地监听指定的响应式数据的变化。
结果:
watch方法比watchEffect方法强大的地方在于,其可以分别获取到变化前的值和变化后的值,也可以监听多个数据源。
注意,通过Vue.reactive声明的变量需要使用箭头函数,watch才能监听到。
组合式API的使用能够帮助我们更好地梳理复杂组件的逻辑分布,能够从代码层面上将分离的相关逻辑点进行聚合,更适合进行复杂模块组件的开发。
setup方法是组合式API的核心方法。
setup方法是组合式API功能的入口方法,如果使用组合式API模式进行组件开发,则逻辑代码都要编写在setup方法中。需要注意的是,setup方法会在组件创建之前执行,即对应组件的生命周期方法beforeCrete方法调用之前被执行。由于setup方法特殊的执行时机,除了可以访问组件的传参外部属性props之外,在其内部我们不能使用this来引用组件的其他属性,在set方法的最后,我们可以将定义的组件所需要的数据、函数等内容暴露给组件的其他选项。
setup方法可以接受两个参数:props和context。props术组件使用时设置的外部参数,其实响应式;context则是一个js对象,其中可用的属性有attrs、slots和emit。
结果:
注意,在setup方法中不要使用this关键字,setup方法中的this与当前组件实例并不是同一个对象。
setup中的生命周期定义方法需要在周期函数前加上on,注意:setup方法执行时机与beforeCreate和created执行时机基本一致。
组合和setup方法中窦定义了同样的生命周期方法,他们之间并不会冲突。
结果:
实现支持搜索和筛选的用户列表
全部
男
女
搜索:
姓名
性别
{{item.name}}
{{item.sex==0?'男':'女'}}
结果:
全部
男
女
搜索:
姓名
性别
{{item.name}}
{{item.sex==0?'男':'女'}}