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 相关文章推荐
用roll.js实现的图片自动滚动+鼠标触动的特效
Mar 18 Javascript
用javascript实现分割提取页面所需内容
May 09 Javascript
javascript抽象工厂模式详细说明
Dec 16 Javascript
jQuery实现可以控制图片旋转角度效果(附demo源码下载)
Jan 27 Javascript
仅9张思维导图帮你轻松学习Javascript 就这么简单
Jun 01 Javascript
AngularJS指令与指令之间的交互功能示例
Dec 14 Javascript
EditPlus中的正则表达式 实战(4)
Dec 15 Javascript
详解node-ccap模块生成captcha验证码
Jul 01 Javascript
详解使用angularjs的ng-options时如何设置默认值(初始值)
Jul 18 Javascript
React Native模块之Permissions权限申请的实例相机
Sep 28 Javascript
vue中created和mounted的区别浅析
Aug 13 Javascript
JS实现audio音频剪裁剪切复制播放与上传(步骤详解)
Jul 28 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数组实例总结与说明
2011/08/23 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(四)
2014/06/23 PHP
jQuery ajax在GBK编码下表单提交终极解决方案(非二次编码方法)
2010/10/20 Javascript
js实现点击链接后延迟3秒再跳转的方法
2015/06/05 Javascript
JavaScript实现将文本框的值插入指定位置的方法
2015/08/13 Javascript
js is_valid_filename验证文件名的函数
2017/07/19 Javascript
详解http访问解析流程原理
2017/10/18 Javascript
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法
2018/01/25 Javascript
vue移动UI框架滑动加载数据的方法
2018/03/12 Javascript
微信小程序修改swiper默认指示器样式的实例代码
2018/07/18 Javascript
axios全局注册,设置token,以及全局设置url请求网段的方法
2018/09/25 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
2019/01/30 Javascript
Jquery滑动门/tab切换实现方法完整示例
2020/06/05 jQuery
Angular短信模板校验代码
2020/09/23 Javascript
Vue实现圆环进度条的示例
2021/02/06 Vue.js
[02:38]2018DOTA2亚洲邀请赛赛前采访-VGJ.T
2018/04/03 DOTA
python批量下载图片的三种方法
2013/04/22 Python
详解Python 模拟实现生产者消费者模式的实例
2017/08/10 Python
django模型层(model)进行建表、查询与删除的基础教程
2017/11/21 Python
python使用pip安装模块出现ReadTimeoutError: HTTPSConnectionPool的解决方法
2019/10/04 Python
前端实现打印图像功能
2019/08/27 HTML / CSS
wordpress添加Html5的表单验证required方法小结
2020/08/18 HTML / CSS
FitFlop美国官网:英国符合人体工学的鞋类品牌
2018/10/05 全球购物
Abbacino官网:包、钱包和女士配饰
2019/04/15 全球购物
LightInTheBox法国站:中国跨境电商
2020/03/05 全球购物
施华洛世奇中国官网:SWAROVSKI中国
2020/06/16 全球购物
入党综合考察材料
2014/06/02 职场文书
校本教研活动总结
2014/07/01 职场文书
2014年人民警察入党思想汇报
2014/10/12 职场文书
团员年度个人总结
2015/02/26 职场文书
周末问候语大全
2015/11/10 职场文书
哪类餐饮行业,最适合在高校创业?
2019/08/19 职场文书
left join、inner join、right join的区别
2021/04/05 MySQL
Win11 Build 21996.1 Dev版怎么样? win11系统截图欣赏
2021/11/21 数码科技
Java异常处理try catch的基本用法
2021/12/06 Java/Android
星际争霸 Light vs Action 一场把教主看到鬼畜的比赛
2022/04/01 星际争霸