Vue3 响应式侦听与计算的实现


Posted in Javascript onNovember 11, 2020

响应式侦听和计算

有时我们需要依赖于其他状态的状态——在 Vue 中,这是用组件 计算属性 处理的,以直接创建计算值,我们可以使用 computed 方法:它接受 getter 函数并为 getter 返回的值返回一个不可变的响应式 ref 对象。

我们先来看看一个简单的例子,关于计算值的方式,同样我们在 src/TemplateM.vue 写下如下代码:

<template>
 <div class="template-m-wrap">
  count ---> {{count}}
  plusOne ---> {{plusOne}}
 </div>
</template>
<script>
import { ref, defineComponent, reactive, computed } from "vue";
export default defineComponent({
 name: 'TemplateM',
 setup() {
  let count = ref(2)
  let plusOne = computed(() => {
   return count.value++
  })
  console.log(plusOne.value)
  return {
   count,
   plusOne
  }
 }
})
</script>

访问链接效果如下:

Vue3 响应式侦听与计算的实现

我们可以看到 plusOne 没有值。或者,它可以使用一个带有 getset 函数的对象来创建一个可写的 ref 对象。

<template>
 <div class="template-m-wrap">
  count ---> {{ count }} plusOne ---> {{ plusOne }}
 </div>
</template>
<script>
import { ref, defineComponent, reactive, computed } from "vue";
export default defineComponent({
 name: "TemplateM",
 setup() {
  let count = ref(2);
  let plusOne = computed({
   get() {
    return count.value++;
   },
   set(val) {
    count.value = val;
   },
  });
  plusOne.value = 1;
  console.log(count.value); // 0
  return {
   count,
   plusOne,
  };
 },
});
</script>

同样访问效果如下:

Vue3 响应式侦听与计算的实现

watchEffect

为了根据响应式状态 自动应用重新应用 副作用,我们可以使用 watchEffect 方法。它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。

<template>
 <div class="template-m-wrap">
  count ---> {{ count }}
 </div>
</template>
<script>
import { ref, defineComponent, reactive, computed, watchEffect } from "vue";
export default defineComponent({
 name: "TemplateM",
 setup() {
  let count = ref(2);
  watchEffect(() => {
   console.log(count.value)
  })
  setTimeout(() => {
   count.value++
  }, 1000)
  return {
   count,
  };
 },
});
</script>

查看效果如下:

Vue3 响应式侦听与计算的实现

停止侦听

watchEffect 在组件的 setup() 函数或 生命周期钩子 被调用时,侦听器会被链接到该组件的生命周期,并在组件卸载时自动停止。

在一些情况下,也可以显式调用返回值以停止侦听:

<template>
 <div class="template-m-wrap">
  count ---> {{ count }}
 </div>
</template>
<script>
import { ref, defineComponent, reactive, computed, watchEffect } from "vue";
export default defineComponent({
 name: "TemplateM",
 setup() {
  let count = ref(2);
  const stopWatch = watchEffect(() => {
   console.log(count.value)
  })
  stopWatch()
  setTimeout(() => {
   count.value++
  }, 1000)
  return {
   count,
  };
 },
});
</script>

查看效果如下:

Vue3 响应式侦听与计算的实现

副作用刷新时机

Vue 的响应性系统会缓存副作用函数,并异步地刷新它们,这样可以避免同一个“tick” 中多个状态改变导致的不必要的重复调用。在核心的具体实现中,组件的 update 函数也是一个被侦听的副作用。当一个用户定义的副作用函数进入队列时,默认情况下,会在所有的组件 update 执行:

<template>
 <div>{{ count }}</div>
</template>

<script>
 export default {
  setup() {
   const count = ref(0)

   watchEffect(() => {
    console.log(count.value)
   })

   return {
    count
   }
  }
 }
</script>

在这个例子中:

  • count 会在初始运行时同步打印出来
  • 更改 count 时,将在组件 更新前 执行副作用。

如果需要在组件更新 重新运行侦听器副作用,我们可以传递带有 flush 选项的附加 options 对象 (默认为 'pre' ):

// fire before component updates
watchEffect(
 () => {
  /* ... */
 },
 {
  flush: 'post'
 }
)

flush 选项还接受 sync ,这将强制效果始终同步触发。然而,这是低效的,应该很少需要。

侦听器调试

onTrackonTrigger 选项可用于调试侦听器的行为。

  • onTrack 将在响应式 property 或 ref 作为依赖项被追踪时被调用。
  • onTrigger 将在依赖项变更导致副作用被触发时被调用。

这两个回调都将接收到一个包含有关所依赖项信息的调试器事件。建议在以下回调中编写 debugger 语句来检查依赖关系:

watchEffect(
 () => {
  /* 副作用 */
 },
 {
  onTrigger(e) {
   debugger
  }
 }
)

onTrackonTrigger 只能在开发模式下工作。

watch

watch API 完全等同于组件侦听器 property。 watch 需要侦听特定的数据源,并在回调函数中执行副作用。默认情况下,它也是惰性的,即只有当被侦听的源发生变化时才执行回调。

与watchEffect 比较, watch 允许我们:

  • 懒执行副作用;
  • 更具体地说明什么状态应该触发侦听器重新运行;
  • 访问侦听状态变化前后的值。

 侦听单个数据源

侦听器数据源可以是返回值的 getter 函数,也可以直接是 ref

// 侦听一个 getter
const state = reactive({ count: 0 })
watch(
 () => state.count,
 (count, prevCount) => {
  /* ... */
 }
)

// 直接侦听ref
const count = ref(0)
watch(count, (count, prevCount) => {
 /* ... */
})

到此这篇关于Vue3 响应式侦听与计算的实现的文章就介绍到这了,更多相关Vue3 响应式侦听与计算内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Jquery 选中表格一列并对表格排序实现原理
Dec 15 Javascript
关于jquery的多个选择器的使用示例
Oct 18 Javascript
JavaScript1.6数组新特性介绍以及JQuery的几个工具方法
Dec 06 Javascript
jquery获取checkbox的值并post提交
Jan 14 Javascript
javascript封装简单实现方法
Aug 11 Javascript
基于jQuery实现复选框是否选中进行答题提示
Dec 10 Javascript
jQuery树形控件zTree使用小结
Aug 02 Javascript
详解node+express+ejs+bootstrap构建项目
Sep 27 Javascript
element el-input directive数字进行控制
Oct 11 Javascript
vue+koa2实现session、token登陆状态验证的示例
Aug 30 Javascript
es6 super关键字的理解与应用实例分析
Feb 15 Javascript
浅谈 JavaScript 沙箱Sandbox
Nov 02 Javascript
详解Vue.js3.0 组件是如何渲染为DOM的
Nov 10 #Javascript
在vs code 中如何创建一个自己的 Vue 模板代码
Nov 10 #Javascript
JavaScript中常用的3种弹出提示框(alert、confirm、prompt)
Nov 10 #Javascript
原生JS实现弹幕效果的简单操作指南
Nov 10 #Javascript
vue解决跨域问题(推荐)
Nov 10 #Javascript
关于vue 项目中浏览器跨域的配置问题
Nov 10 #Javascript
如何在vue 中引入使用jquery
Nov 10 #jQuery
You might like
以文本方式上传二进制文件的PHP程序
2006/10/09 PHP
PHP获取163、gmail、126等邮箱联系人地址【已测试2009.10.10】
2009/10/11 PHP
PHP MySQL应用中使用XOR运算加密算法分享
2011/08/28 PHP
php获取从html表单传递数组的方法
2015/03/20 PHP
PHP入门教程之PHP操作MySQL的方法分析
2016/09/11 PHP
动态表格Table类的实现
2009/08/26 Javascript
javascript代码加载优化方法
2011/01/30 Javascript
基于jquery的图片幻灯展示源码
2012/07/15 Javascript
js模拟滚动条(横向竖向)
2013/02/22 Javascript
js中for in语句的用法讲解
2015/04/24 Javascript
基于javascript实现全国省市二级联动下拉选择菜单
2016/01/28 Javascript
Javascript的表单与验证-非空验证
2016/03/18 Javascript
JavaScript必知必会(九)function 说起 闭包问题
2016/06/08 Javascript
漫谈JS引擎的运行机制 你应该知道什么
2016/06/15 Javascript
js获取html的span标签的值方法(超简单)
2016/07/26 Javascript
AngularJS基础 ng-readonly 指令简单示例
2016/08/02 Javascript
原生JS实现图片轮播与淡入效果的简单实例
2016/08/21 Javascript
浅谈js中startsWith 函数不能在任何浏览器兼容的问题
2017/03/01 Javascript
AngularJS的Filter的示例详解
2017/03/07 Javascript
使用react实现手机号的数据同步显示功能的示例代码
2018/04/03 Javascript
使用vue的transition完成滑动过渡的示例代码
2018/06/25 Javascript
详解Vue 单文件组件的三种写法
2020/02/19 Javascript
[02:39]DOTA2英雄基础教程 天怒法师
2013/11/29 DOTA
用Python输出一个杨辉三角的例子
2014/06/13 Python
Python的__builtin__模块中的一些要点知识
2015/05/02 Python
python os模块简单应用示例
2019/05/23 Python
使用pygame编写Flappy bird小游戏
2020/03/14 Python
PyCharm Anaconda配置PyQt5开发环境及创建项目的教程详解
2020/03/24 Python
Django ForeignKey与数据库的FOREIGN KEY约束详解
2020/05/20 Python
python GUI计算器的实现
2020/10/09 Python
跑步爱好者一站式服务网站:Jack Rabbit
2016/09/01 全球购物
SmartBuyGlasses德国:购买太阳镜和眼镜
2019/08/20 全球购物
工程造价专业大专生求职信
2013/10/06 职场文书
竞选班干部演讲稿300字
2014/08/20 职场文书
小学生感恩父母演讲稿
2014/08/28 职场文书
在Windows Server 2012上安装 .NET Framework 3.5 所遇到的问题
2022/04/29 Servers