购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.3 监听

计算属性可以根据已有的一个或多个数据,通过同步计算返回一个新的用于显示的数据。在计算数据的依赖数据发生变化时,计算属性函数会重新执行并返回一个新的值进行显示。但有的时候,在依赖数据发生变化时,我们需要让其产生一些“副作用”。例如,直接更新DOM,或者执行异步操作后,更新其他数据。此时我们可以使用Vue的监听语法来实现。

2.3.1 监听的基本使用

在选项式API中,我们可以通过watch选项配置一个函数来监听某个响应式属性的变化。监听回调函数默认在数据发生变化时回调,且接收新值和旧值两个参数。其语法格式如下。

下面我们利用监听来实现如图2-14所示的页面效果。

图2-14 页面效果

现有两个需求,具体如下。

①输入标题,实时同步显示到页面标题上。

②输入标题,实时AJAX请求获取一个最匹配的问题并显示到输入框下面。

下面我们对需求进行分析:输入的标题可以通过v-model收集到data对象中的title属性上,同时用watch选项来监听title属性的变化,在监听回调函数中将最新的值设置给文档的标题。同时发送AJAX请求,根据title属性获取一个最匹配的问题并设置给data对象中的question属性,显示到输入框下面。

实现代码如下所示。

Vue代码如下。

JavaScript代码如下。

运行代码后,我们在输入框中输入Vue,会发现1秒后显示问题。

其实watch选项不仅可以监听data对象中外部的属性,还可以监听其内部的属性。现有一个person对象,内部有name和age两个属性,我们使用watch选项对name属性进行监听。其语法格式如下。

2.3.2 即时回调与深度监听

watch回调默认是在数据发生变化时自动调用,如果我们需要在初始化时就执行一次监听的回调,那么要如何实现呢?

Vue的watch语法也支持这种场景需求,但是用法有些许差别,watch的属性不能再是一个函数了,需要是一个配置对象,并通过handler配置来指定监听回调函数。同时我们可以通过配置immediate为true来指定监听回调函数在初始化过程中执行第1次,当然在被监听数据发生改变时也会执行。

思考下面代码的运行效果。

Vue代码如下。

JavaScript代码如下。

运行代码后,页面上展示了person中的name属性和likes属性,如图2-15所示。

由于我们配置了immediate为true,因此watch的回调在初始化时就会执行1次。我们又通过定时器模拟异步向后台提交请求,即提交当前person的信息数据,如图2-16所示。

图2-15 页面效果(1)

图2-16 模拟异步向后台提交请求(1)

点击“更新人员信息”按钮,直接将当前person更新为一个新的人员对象,监听的回调也会执行,用来模拟异步向后台提交请求,发送最新的人员信息,如图2-17和图2-18所示。

图2-17 点击“更新人员信息”按钮后页面发生变化

图2-18 模拟异步向后台提交请求(2)

watch默认是浅层监听,只有在被监听属性本身发生变化时才会触发回调,它监听不到属性对象内部的数据变化。

对于上面的案例来说,如果只是更新person对象中的内部属性,比如name属性,那么watch的回调就不会执行。

点击“更新人员信息”按钮后,页面上的name属性值会发生改变,但是不会触发watch中的异步操作,因此页面上不会弹出警告提示,如图2-19所示。

图2-19 点击“更新人员信息”按钮后的页面效果

那么如何才能深度监听到对象或数组内任意数据的变化呢?其实可以通过将deep配置为true来实现。也就是说,deep的默认值为false,因此之前watch监听不到内部数据的修改。现在修改一下watch的配置,具体如下。

此时我们再次重复当前的操作,可以发现除了页面发生变化,1秒后还弹出了警告提示,证明此时已经监听到内部数据了,如图2-20所示。

图2-20 模拟异步向后台提交请求(3)

其实,无论是更新person对象的name属性,还是更新person对象中的likes属性,监听的回调都会调用,会将最新的人员信息提交给后台,如下代码所示。

重复点击“更新人员信息”按钮,这次likes属性的数组中新增了一项“atguigu”,这个修改同样被监听到了,也会异步向后台提交数据,如图2-21和图2-22所示。

图2-21 页面效果(2)

图2-22 模拟异步向后台提交请求(4) 7kRW6S2kcknQJ/PqISQ3YX6Ef0Z4gMbqhbWAJm9e6k6yoid488u1ME8vqre3Lszn

点击中间区域
呼出菜单
上一章
目录
下一章
×