Vue3学习笔记--computed、watch、watchEffect

118 阅读2分钟
  • computed 当我们想监听一个ref数据变化时,computed返回的Ref对象,所有不用.value
let $total = ref<number>(0)
$total = computed<number>(() => {
  return data.reduce((prev, next) => {
    return prev + (next.num * next.price)
  }, 0)
})
  • watch 需要侦听特定的数据源,并在单独的回调函数中执行副作用
// 监听Ref 案例
import { ref, watch } from 'vue'
 
let message = ref({
    nav:{
        bar:{
            name:""
        }
    }
}) 
watch(message, (newVal, oldVal) => {
    console.log('新的值----', newVal);
    console.log('旧的值----', oldVal);
},{
    immediate:true,
    deep:true
})
// 监听多个ref 注意变成数组
import { ref, watch ,reactive} from 'vue'
 
let message = ref('')
let message2 = ref('')
 
watch([message,message2], (newVal, oldVal) => {
    console.log('新的值----', newVal);
    console.log('旧的值----', oldVal);
})
// 监听引用类型中的值
import { ref, watch } from 'vue'
let message = ref({
    nav: {
        bar: {
            name: '小满'
        }
    }
})

watch(message, (newVal, oldVal) => {
    console.log('新的', newVal)
    console.log('旧的', oldVal)
})

存在问题:新的和旧的里面被监听的值,同时改变了 image.png

// 监听Reactive 使用reactive监听深层对象开启和不开启deep 效果一样
import { ref, watch ,reactive} from 'vue'
 
let message = reactive({
    nav:{
        bar:{
            name:""
        }
    }
})

watch(message, (newVal, oldVal) => {
    console.log('新的值----', newVal);
    console.log('旧的值----', oldVal);
})
// 监听reactive 单一值
import { ref, watch ,reactive} from 'vue'
 
let message = reactive({
    name:"",
    name2:""
})
 
 
watch(()=>message.name, (newVal, oldVal) => {
    console.log('新的值----', newVal);
    console.log('旧的值----', oldVal);
})

watchEffect

  • 立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数
  • 如果用到message 就只会监听message 就是用到几个监听几个 而且是非惰性 会默认调用一次
let message = ref<string>('')
let message2 = ref<string>('')
 watchEffect(() => {
    console.log('message', message.value);
    console.log('message2', message2.value);
})

清除副作用

  • 就是在触发监听之前会调用一个函数可以处理你的逻辑例如防抖
import { watchEffect, ref } from 'vue'
let message = ref<string>('')
let message2 = ref<string>('')
 watchEffect((oninvalidate) => {
    console.log('message', message.value);
    oninvalidate(()=>{
        // 会先执行回调函数
    })
    console.log('message2', message2.value);
})

watchEffect 返回一个函数 调用之后将停止更新

watchEffect 提供第二个参数可以做额外配置

<button @click="stopWatch"></button>
<input id="ipt" />
import { watchEffect, ref } from 'vue'
let message = ref<string>('')
let message2 = ref<string>('')
const stop =  watchEffect((oninvalidate) => {
    let ipt: HTMLInputElement = document.querySelector('#ipt') as HTMLInputElement // 断言
    console.log(ipt, 'iptttt') // 此时打印为null
    oninvalidate(()=>{
 
    })
    
    console.log('message', message.value);
    console.log('message2', message2.value);
})
const stopWatch = () => stop()

image.png

watchEffect提供一个配置选项,flush

prepresyncpost
更新时机组件更新前执行强制效果始终同步触发组件更新后执行
import { watchEffect, ref } from 'vue'
  let message = ref<string>('')
  let message2 = ref<string>('')
  const stop =  watchEffect((oninvalidate) => {
    let ipt: HTMLInputElement = document.querySelector('#ipt') as HTMLInputElement // 断言
    console.log(ipt, 'iptttt')
    oninvalidate(()=>{
 
    })
    
    console.log('message', message.value);
    console.log('message2', message2.value);
}, {
    flush:"post",
    onTrigger (e) {
        // 开发环境帮助我们调试
        debugger
    }
})
const stopWatch = () => stop()

image.png