精通Vue.js系列实例教程 │ Vue组件的数据监听

2022-11-24 0 660

原副标题:通晓Vue.js系列产品实例教程 │ Vue模块的统计数据窃听

精通Vue.js系列实例教程 │ Vue组件的数据监听

假如Vue模块的两个表达式num会被频密预览,因此当表达式num每天被预览时,须要展开一连串产品费时的操作方式,如出访远距伺服器的天然资源,或是透过繁杂耗时的演算预览这些倚赖表达式num的其它表达式(如result表达式)。在此种情况下,能透过Vue架构的统计数据窃听器Watcher同时实现对表达式num的窃听。

Vue的watch快捷键会透过Watcher窃听统计数据。例程1的mywatch.html模拟了watch快捷键的基本上用语。

解释器1 mywatch.html

< divid= “app”> < p> < inputv-model= “num”/> </ p> < p> {{ result }}</ p> </ div>

< > constvm=Vue.createApp({ data{return{ num: 0, result: 0} },methods:{ //睡眠方法,参数numberMillis是睡眠的毫秒数sleep(numberMillis) { varnow = newDate; varexitTime = now.getTime + numberMillis while( true) { now =newDateif(now.getTime > exitTime) return; } }},watch: { //当num表达式被预览,就会调用此函数//newNum参数表示预览后的num表达式//oldNum参数表示预览前的num表达式num(newNum, oldNum) { //num表达式的窃听函数this.sleep( 2000) //睡眠2秒this.result= Math.sqrt(newNum) //计算平方根}}}).mount( #app) </ > </ body> </ html>

在mywatch.html中,Vue应用实例的watch快捷键中有两个num函数,负责窃听num表达式。当num表达式被预览,Vue的统计数据窃听器就会调用这个num函数。

透过浏览器出访mywatch.html,会得到如图1所示的网页。在网页的num表达式的输入框输入新的数字,Vue的统计数据窃听器就会调用num函数,预览result变量的值。

图1 mywatch.html的网页

1

用Web Worker执行统计数据窃听中的异步操作方式

对于解释器1的mywatch.html,当用户在网页的num表达式的输入框输入新的数字时,num函数就会被Vue的统计数据窃听器调用。num函数会先调用sleep(2000)方法睡眠2秒,透过此种睡眠的方式来模拟费时的操作方式。

num函数是由浏览器的负责执行Java脚本的主线程来执行的。当主线程执行sleep(2000)方法睡眠时,网页处于卡死状态,不能响应用户的任何操作方式。只有当主线程执行完num函数,重新预览了网页,网页才能继续响应用户的操作方式。

假如希望用户始终能和网页展开顺畅地交互,不会出现网页卡死的情况,可以透过两个额外的线程异步执行费时的操作方式。这里会利用HTML5中的Web Worker线程来执行费时操作方式。

首先创建两个longtask.js文件(文件名能任意取),参见解释器2,它的onmessage函数包含了Worker线程接收到主线程发送的统计数据时所执行的操作方式。

解释器2 longtask.js

//睡眠函数,参数numberMillis是睡眠的毫秒数functionsleep( numberMillis) {…}

//当Worker线程接收到主线程发送的统计数据时,调用此函数onmessage= function( event) { varnum=event.data //读取主线程发送过来的统计数据sleep( 2000) //睡眠2秒,模拟费时的操作方式varresult= Math.sqrt(num) //求平方根postMessage(result) //向主线程发送演算结果 }

在onmessage函数中,event.data表示主线程发送过来的num表达式。postMessage(result)用于向主线程发送result表达式。

解释器3的mywatch-async.html会透过Worker线程执行费时操作方式。

解释器3 mywatch-async.html

< divid= “app”> < p> < inputv-model= “num”/> </ p> < p> {{ result }} </ p> </ div>

< > constvm=Vue.createApp({data{return{ num: 0, result: 0} } ,

watch: { // 当num表达式被预览,就会调用此方法num(newNum, oldNum) { // num表达式的窃听函数this.result= 正在演算,请稍后…//创建Worker线程 varworker= newWorker( longtask.js)

//注册窃听接收Worker线程发送统计数据的函数worker.onmessage=( event)=> this.result=event.data

//向Worker线程发送统计数据worker.postMessage(newNum) }}}).mount( #app) </ >

在num函数中,浏览器的主线程先透过以下语句为result表达式赋予两个临时取值:

this.result= 正在演算,请稍后…

接着主线程透过“new Worker(longtask.js)”语句创建了Worker线程。接下来执行以下语句注册用于窃听接收统计数据的onmessage函数:

worker.onmessage= ( event)=> this.result=event.data

当主线程接收到Worker线程发送的统计数据时,就会执行worker.onmessage函数中的this.result=event.data语句,event.data表示Worker线程发送的统计数据。

主线程接着向Worker线程发送newNum表达式:

worker.postMessage( newNum)

各个浏览器对Web Worker的支持程度不一样。假如在Chrome浏览器中出访本地的mywatch-async.html,然后在网页的输入框修改num表达式的值,浏览器会产生以下错误:

Uncaught ( inpromise) DOMException: Failed to construct Worker: at file:///C:/vue/sourcecode/chapter03/longtask.jscannot be accessed fromorigin null.

这是因为Chrome出于安全的原因,不允许使用本地的Web Worker线程。笔者把该范例发布到了JavaThinker.net网站上,网址如下:

www.javathinker.net/vue/mywatch- async.html

透过浏览器出访上述网址,就能正常出访mywatch-async.html。在网页的输入框修改num表达式的值,网页不会卡死,主线程会先显示result表达式的临时取值,参见图2。过2秒后,主线程再显示由Worker线程演算得到的result表达式。

图2 网页显示result表达式的临时取值

图3展示了主线程和Worker线程的通信及交换统计数据的过程。

精通Vue.js系列实例教程 │ Vue组件的数据监听

图3 主线程和Worker线程的通信以及交换统计数据的过程

从图3能看出,当主线程通过worker.postmessage(newNum)方法向Worker线程发送newNum表达式,就会触发Worker线程执行longtask.js中的onmessage函数。当Worker线程透过postmessage(result)方法向主线程发送result表达式,就会触发主线程执行worker.onmessage函数。无论是主线程还是Worker线程,都能透过event.data读取对方发送的统计数据。

2

在watch快捷键中调用方法

在watch快捷键中还能调用方法。例如在解释器4的score.html中,假如score表达式被预览,Vue的统计数据窃听器就会调用judge方法。

解释器4 score.html

< divid= “app”> < p> < inputv-model= “score”/> </ p> < p> {{ result }} </ p> </ div>

< > constvm=Vue.createApp({ data{return{ score: , result: } } ,

methods:{ judge { if( this.score>= 60) this.result= 及格elsethis.result= 不及格}},

watch: { score: judge//调用judge方法}}).mount( #app) </ >

下面对judge方法做一些修改,使它透过Java语言的setTimeout函数执行异步操作方式。

judge {this.result= “正在演算,请稍后…”setTimeout( =>{if( this.score>= 60) this.result= 及格elsethis.result= 不及格}, 2000)//延迟2秒后再执行演算}

以上judge方法先给result表达式赋予了两个临时值“正在演算,请稍后…”,然后利用setTimeout函数设置了异步操作方式:过2秒后计算result表达式的取值。judge方法产生的运行效果是,网页上首先显示“正在演算,请稍后…”,过2秒后再显示reuslt表达式的实际取值。

3

深度窃听

默认情况下,当Vue的watch快捷键窃听两个对象时,不会窃听对象的属性的变化。假如希望窃听对象的属性变化,能在watch快捷键中把deep属性设为true,这样就会支持深度窃听。

在解释器5的student.html中,Vue的watch快捷键会窃听student对象,由于deep属性设为true,当student.score属性被预览,watch快捷键中的handler函数也会被执行。

解释器5 student.html

< divid= “app”> < p> < inputv-model= “student.score”/> </ p> < p> {{ result }} </ p> </ div>

< > constvm=Vue.createApp({ data{return{ student: { name: Tom,score: 98} , result: }} ,

watch: { student: { //窃听student对象handler(newStudent,oldStudent){if( this.student.score>=60) this.result= 及格elsethis.result= 不及格},deep: true//启用深度窃听}}}).mount( #app) </ >

透过浏览器出访student.html网页,在输入框修改student.score属性的值,Vue的统计数据窃听器会调用handler函数,预览result表达式。

当Vue的统计数据窃听器深度窃听两个对象时,不管对象的属性嵌套了多少层,只要属性发生变化,就会被窃听。

4

立即窃听

透过浏览器出访解释器5的student.html时,会看到网页上一开始显示{{student.score}}的值为98,而{{result}}的值为空。因为这时候Vue的数据窃听器还没有窃听到student.score属性的变化,因此不会调用watch快捷键中的handler函数。

在Vue模块的生命周期中,假如希望在它的初始化阶段,Vue架构就会调用一次watch快捷键中的handler函数,为result表达式赋值,那么能把watch快捷键的immediate属性设为true。

下面对student.html做如下修改,增加immediate: true语句。

watch: {student: { handler(newStudent,oldStudent){…}, immediate: true, deep: true}}

再次透过浏览器出访student.html,会看到网页上{{student.score}}的初始值为98,{{result}}的初始值为“及格”。

5

参考书籍

点击上图看详细图书介绍

《通晓Vue.js:Web前端开发技术详解(微课视频版)》

详细阐述用Vue架构的各种技术;深刻揭示前端开发的响应式编程核心思想;介绍与其它流行技术的整合;典型范例帮助读者迅速获得实战经验。

作者:孙卫琴,杜聚宾

价格:119元

扫码优惠购书

实例讲解

通晓Vue.js:

Web前端开发技术详解

精彩回顾

1. Vue模块的命名规则

2 . 注册全局模块和局部模块

3 . 路由导航中抓取统计数据

4. 路由管理器的基本上用语

5. 命名路由

6. CSS中DOM元素的过渡模式

7. 插槽slot的基本上用语

8. 模块的递归

9. 在Vue项目中使用Axios

10. 自定义指令v-drag范例

11. Vuex中的异步操作方式

12. 分割setup函数

13. Vue模块的单向统计数据流

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务