<template> 姓:<input v-model="person.firstName"><br/><br/> 名:<input v-model="person.lastName"><br/><br/> <span>全名:{{person.fullname}}</span><br/><br/> <span>全名:<input v-model="person.fullname"></span> </template> <script> import {reactive,computed} from 'vue' export default { name: 'HelloWorld', setup(){ let person = reactive({ firstName:"张", lastName:"三" }) //computed简写形式,没考虑修改 /*person.fullname = computed(()=>{ return person.firstName+"-"+person.lastName; })*/ person.fullname = computed({ get(){ return person.firstName+"-"+person.lastName; }, set(value){ const nameArr = value.split('-'); person.firstName = nameArr[0]; person.lastName = nameArr[1]; } }) return{ person, } } } </script>
#1、與Vue2.x 中watch 設定功能一致
2、兩個小"坑":
監視reactive 定義的響應式資料時: oldValue 無法正確取得、強制開啟了深度監視(deep配置失效)
監視reactive 定義的回應式資料中某個屬性時:deep 配置有效
<template> <h3>当前求和为:{{ sum }}</h3> <button @click="sum++">点我sum++</button> </template> <script> import {ref} from 'vue' export default { name: 'Demo', watch: { /*sum(oldValue,newValue){ console.log("sum发生了变化",oldValue,newValue); }*/ sum: { immediate: true, deep:true, handler(newValue,oldValue) { console.log("sum发生了变化", newValue, oldValue); } } }, setup() { let sum = ref(0); return { sum, } } } </script>
1、情況一:監視ref所定義的一個響應式資料
<template> <h3>当前求和为:{{ sum }}</h3> <button @click="sum++">点我sum++</button>> </template> <script> import {ref, watch} from 'vue' export default { name: 'Demo', setup() { let sum = ref(0); let msg = ref("你好啊"); //情况一:监视ref所定义的一个响应式数据 watch(sum, (newValue, oldValue) => { console.log("sum发生了变化", newValue, oldValue); }) return { sum } } } </script>
watch 還可以傳一個設定項,把immediate 等設定傳進去:
watch(sum, (newValue, oldValue) => { console.log("sum发生了变化", newValue, oldValue); },{immediate:true})
2、情況二:當有多個資訊需要同時監視時
<template> <h3>当前求和为:{{ sum }}</h3> <button @click="sum++">点我sum++</button> <hr/> <h3>信息为:{{ msg }}</h3> <button @click="msg+='!'">点我sum++</button> </template> <script> import {ref, watch} from 'vue' export default { name: 'Demo', setup() { let sum = ref(0); let msg = ref("你好啊"); //情况二:监视ref所定义的多个响应式数据 watch([sum,msg],(newValue, oldValue) => { console.log("sum发生了变化", newValue, oldValue); }) return { sum, msg } } } </script>
3、情況三:監視reactive所定義的一個響應式資料
<template> <h3>姓名:{{ person.name }}</h3> <h3>年龄:{{ person.age }}</h3> <h3>薪资:{{ person.job.j1.salary }}K</h3> <button @click="person.name+='~'">修改姓名</button> <button @click="person.age++">修改年龄</button> <button @click="person.job.j1.salary++">涨薪</button> </template> <script> import {reactive, watch} from 'vue' export default { name: 'Demo', setup() { let person = reactive({ name: "张三", age: 18, job:{ j1:{ salary:20 } } }) //情况三:监视reactive所定义的一个响应式数据全部属性 // 1\注意:无法正确获取oldvalue // 2\注意:强制开启了深度监视(deep配置无效) watch(person, (newValue, oldValue) => { console.log("person发生了变化", newValue, oldValue); }) return { person } } } </script>
4、情況四:監視reactive定義的一個響應式資料某個屬性
//情况四:监视reactive所定义的一个响应式数据某个属性 watch(()=>person.name, (newValue, oldValue) => { console.log("person的name发生了变化", newValue, oldValue); })
5、情況五:監視reactive 所定義的一個響應式資料某些屬性
//情况五:监视reactive所定义的一个响应式数据某个属性 watch([()=>person.name,()=>person.age], (newValue, oldValue) => { console.log("person的name或age发生了变化", newValue, oldValue); })
6、特殊情況,監視物件中的某個物件屬性,要開始deep:true
watch(()=>person.job, (newValue, oldValue) => { console.log("person的job发生了变化", newValue, oldValue); },{deep:true})//由于监视的是reactive对象中的某个属性,deep奏效
7、監視ref 定義的對象回應數據,需要.value或deep:true
let person = ref({ name: "张三", age: 18, job:{ j1:{ salary:20 } } }) watch(person.value, (newValue, oldValue) => { console.log("person的value发生了变化", newValue, oldValue); }) 或 watch(person, (newValue, oldValue) => { console.log("person的value发生了变化", newValue, oldValue); },{deep:true})
watch
的套路是:既要指明監視的屬性,也要指明監視的回呼
watchEffect
的套路是:不用指明監視哪個屬性,監視的回呼中用到哪個屬性,那就監視哪個屬性
watchEffect
有點像computed
:
。但computed
注重的計算出來的值(回呼函數的回傳值),所以必須寫回傳值
。而watchEffect
更注重的是過程(回呼函數的函數體),所以不用寫回傳值
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调 watchEffect(()=>{ const xl = sum.value const x2 = person.age console.log( "watchEffect配置的回调执行了") })
例如也用上邊的例子:
#import {reactive,watchEffect} from 'vue' export default { name: 'Demo', setup() { let person = reactive({ name: "张三", age: 18, job:{ j1:{ salary:20 } } }) watchEffect(()=>{ const x1 = person.name; console.log("watchEffect所指定的回调执行了"+x1); }) return { person } } } </script>
最後,我們使用watch 和watchEffect 實作姓名的例子
<template> 姓:<input v-model="person.firstName"> 名:<input v-model="person.lastName"> <span>全名:{{fullName}}</span> <span>全名:<input v-model="fullName"></span> </template> <script lang="ts"> import {defineComponent, reactive, ref,watch,watchEffect} from 'vue'; export default defineComponent({ setup(){ let person = reactive({ firstName:"张", lastName:"三" }); const fullName = ref(''); watch(person,({firstName,lastName})=>{ fullName.value = firstName+"-"+lastName },{immediate:true}) //不用使用immediate,默认执行一次 /*watchEffect(()=>{ fullName.value = person.firstName+"-"+person.lastName })*/ watchEffect(()=>{ const name = fullName.value.split('-'); person.firstName = name[0]; person.lastName = name[1]; }) return{ person, fullName } } }); </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
以上是Vue3中的computed,watch,watchEffect如何使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!