首页 > 其他分享 >vue3 watch watchEffect computed 使用差别

vue3 watch watchEffect computed 使用差别

时间:2024-07-18 23:20:25浏览次数:16  
标签:深度 computed vue3 watch props config 监听

概论

watch 监听明确的数据
computed 监听数据并返回计算结果
watchEffect重视监听过程

测试代码

  • 子组件
<template>
  <div class='box'>
    <div>props 监听测试</div>
    computed返回的内容的深度属性:{{ configTwo.obj1 && configTwo.obj1.xxx }}
    <div></div>
    <!-- 成功响应, computed 说明也能监听到深度修改 -->
    computed本身:{{ configTwo }}
    <div></div>

    <data>props返回的是一个reactive对象,可以深度响应:{{ props.config.obj1?.xxx }}</data>
  </div>
</template>
<script lang='ts' setup>
import { PropType } from 'vue';

// import { ref, reactive, computed, onMounted, nextTick } from 'vue';


export interface Config {
  arr1: Array<IObject>,
  obj1?: IObject
}

const props = defineProps({
  title: {
    type: String,
    required: true,
    default: 'Default Title'
  },
  dicts: {
    type: Array,
    required: true,
    default: () => []
  },
  customClass: {
    type: String,
    default: ''
  },
  config: {
    type: Object as PropType<Config>,
    default: () => ({
      arr1: [], obj1: {
        arr1: [],
        obj1: {
          id: 1,
          name: "test"
        }
      }
    })
  }
})


console.log(props, "props_type_slvnsldjsklfjlks")
console.log(props.config, "snvlkwejrklwejrkwej")

const dicts = computed(() => props.dicts);

const title = computed(() => props.title);

const config = props.config;

console.log(config, "config_slvnsdlfkjskfj");

//可以监听到
watch(config, (val) => {
  console.log(val, "vsndskfdlsfksjfjslkjslkfjsdjflks");
})

//可以监听到,对于config的浅属性可以监听到,也就是config的第一层属性可以监听到,再深度就不行了,因为watch是浅监听
watch(props.config, (val) => {
  console.log(val, "config_sdkvnnsdks2342")
});
//能监听到,watch对props任何修改都能监听到?
watch(props, (val) => {
  console.log(val, "props_23423svdnlfskjfskldjnlerjlkfjsklfjskdf")
})

//返回ref对象
const configTwo = computed(() => props.config)

console.log(configTwo, "configTwo_vsndlsjdfknvskdlskfj")


//watch 对于ref对象 默认是浅监听,不能监听到ref对象的深度变化,需要开启deep
watch(configTwo, () => {
  console.log(configTwo.value, "config_two_sdkvnnsdks2342")
}, {
  deep: true,
})
//监听不到ref对象的深度属性,watch 默认是浅监听,不能监听对象的深度属性
watch(configTwo, () => {
  console.log(configTwo.value, "vnsldnnvsldfklwe2342sdskjfskdf")
})


watchEffect(() => {
  //watchEffect 是深度监听,能监听到ref对象的深层次数据的变化
  console.log(configTwo.value, "config_two_effect_sdkvnnsdks2342")
})

const obj1 = computed(() => props.config.obj1); //直接指明监听属性,不开启深度监听也能监听到

//这样可以监听到
watch(obj1, () => {
  console.log(obj1.value, "obj1_sdkvnnsdks2342")
})

//可以监听到,watchEffect是深度监听
watchEffect(() => {
  console.log(props.config, "config_effect_sdkvnnsdks2342")
})


/**
 * 总结:
 * watch 第一次加载不会执行,且是浅监听,一般只能监听到对象属性的第一层,对于深度属性不能监听到,需要指明deep配置才能深度监听
 * 
 * watchEffect 是深度监听,且第一次加载就会执行
 * 
 * computed 计算属性也是深度监听,对于深度有任何变化都会反应计算,computed和watchEffect差不多,只是computed会多返回计算结果值,且会缓存,如果内部计算对象没变化就直接读缓存值
 */

/**
 * 基本上除了watch默认不是深度监听之外,watchEffect和computed都有深度的响应特性
 */




</script>
<style lang='scss' scoped></style>
  • 父组件
<template>
  <div class="box">
    <div>

      <childP :title="'vnslfdjslkfj'" :customClass="'sdfsdf'" :dicts="mydicts" :config="myconfig" />
    </div>
  </div>
</template>
<script lang="ts" setup>

import childP from "./components/childP.vue";



const mydicts = ref([] as Array<any>);

setTimeout(() => {

  mydicts.value = [
    {
      title: "tom",
      age: 20,
    },
    {
      title: "jerry",
      age: 22,
    }
  ];

}, 2000);

import {Config} from "./components/childP.vue"

const myconfig=ref<Config>({
  arr1:[],
  obj1:{
    xxx:''
  }
})

setTimeout(() => {
  // myconfig.value.arr1=[{
  //   a:"slfjsklfjsdf"
  // }]
  myconfig.value.obj1!['xxx']="修改了"

  console.log(myconfig.value,"snvslkjlskfjsklfjsklfdj")
},5000)



</script>
<style lang="stylus" scoped></style>

总结

  • watch 第一次加载不会执行,且是浅监听,一般只能监听到对象属性的第一层,对于深度属性不能监听到,需要指明deep配置才能深度监听
  • watchEffect 是深度监听,且第一次加载就会执行
  • computed 计算属性也是深度监听,对于深度有任何变化都会反应计算,computed和watchEffect差不多,只是computed会多返回计算结果值,且会缓存,如果内部计算对象没变化就直接读缓存值
  • 基本上除了watch默认不是深度监听之外,watchEffect和computed都有深度的响应特性

标签:深度,computed,vue3,watch,props,config,监听
From: https://www.cnblogs.com/jocongmin/p/18310584

相关文章

  • Vue3动态生成组件
    在Vue3中,要遍历funConfig并动态生成组件,可以使用Vue的defineAsyncComponent来加载异步组件,并结合v-for指令在模板中进行渲染。以下是一个示例代码来实现这个需求:1.配置文件确保配置文件导出的是一个reactive对象:import{reactive}from'vue';exportconst......
  • Vue3学习---1
    Vue3学习1.初识Vue1.1HelloWorld程序<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><ti......
  • vue3中使用@作为引用根目录报错
    在Vue3中使用 @ 作为引用根目录(通常是 src 目录)报错,通常是因为配置未正确设置或者配置未被项目正确识别。1.1.排查和解决此类问题的步骤:确认配置文件:对于使用Vite的项目,需要在 vite.config.ts 文件中配置路径别名。确保你已经正确导入了 path 模块,并设置了......
  • 自研electron31+vue3+elementPlus桌面聊天Exe应用-源码版
    Vue3-ElectronWechat:基于最新前端跨平台技术electron31.x整合高性能构建工具vite.js5搭建的一款高颜值桌面端仿微信界面聊天程序。整个项目采用vue3setup语法糖编码开发,全新封装electron多窗口管理模式。基于vite5+electron31+vue3仿微信客户端聊天【源码版】功能特......
  • [VUE3] 使用D3实现日历热力图
    开始最近我在写自己的网站,需要日历热度图来丰富点内容;所以在网上找了许多参考,如下:https://www.zzxworld.com/posts/draw-calendar-of-heatmap-chart-with-d3jshttps://github.com/DominikAngerer/vue-heatmap/blob/master/README.md将两个结合就是我想要的。现在是这样:代......
  • vue3 封装svg图标
    安装插件npmivite-plugin-svg-icons1.修改 vite.config.jsimport{resolve}from'path'import{createSvgIconsPlugin}from'vite-plugin-svg-icons';exportdefaultdefineConfig({  plugins:[    vue(),    createSvgIconsPlugin({......
  • Vue3 - 微信公众号H5网站使用微信扫一扫(微信扫码),苹果报错 {“errMsg“:“scanQRCode
    前言关于此问题网上的教程都无法解决,如果您的报错信息与我相似,即可解决。在vue3|nuxt3微信公众号网页开发中,微信移动端h5网页使用JS-SDK中的“微信扫码(微信扫一扫)”wx.scanQRCode接口,苹果ios系统真机测试时出现报错:“errMsg”:“scanQRCode:thepermissi......
  • vue3,生产环境,禁止调试输出(重写console的方式)
    如果你想在生产环境中直接重写console的方法以禁止其输出,你可以在你的主入口文件(通常是main.js或main.ts)中添加一些代码来实现这一点。但是,请注意,直接修改全局对象(如console)可能不是最佳实践,因为它可能会与其他库或框架产生冲突。然而,如果你确实想这样做,下面是一个简单的例子,说明......
  • vue3 | 通信组件之provide 与 inject实现兄弟组件通信
    一、vue3|通信组件之provide与inject实现兄弟组件通信 通过共同祖先组件使用provide与inject来提供和注入状态,从而实现兄弟组件通信的示例。例子:祖先组件提供了一个名为 sharedState 的响应式状态,并通过 provide 函数将其提供给所有子组件。ChildA 和 ChildB ......
  • vue3+TS从0到1手撸后台管理系统
    1.路由配置1.1路由组件的雏形src\views\home\index.vue(以home组件为例)1.2路由配置1.2.1路由index文件src\router\index.ts//通过vue-router插件实现模板路由配置import{createRouter,createWebHashHistory}from'vue-router'import{constantRoute}from'./route......