watch 和 watchEffect
前篇对 computed 属性如何在 api 中基本使用, 即从 vue 中引入, 然后通过直接传函数或者传对象的方式, 开箱即用, 非常清晰易懂. 本篇继续来对之前的 watch 进行扩展使用啦.
watch
<!DOCTYPE html>
<html lang="en">
<head>
<title>watch</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
// watch 监听器
const app = Vue.createApp({
setup () {
const { ref, watch } = Vue
const name = ref('youge')
// 具备一定的 lazy 惰性加载
// 参数可以拿到之前值和当前值
watch(name, (curValue, prevValue) => {
console.log(curValue, prevValue)
})
return { name }
},
template: `
<div>
<div>
name: <input v-model="name" />
</div>
<div>
name is: {{name}}
</div>
</div>
`,
})
const vm = app.mount('#root')
</script>
</body>
</html>
当然对于 reactive 的数据也是类似的写法啦, watch 这里要写成箭头函数就行.
setup () {
const { reactive, toRefs, watch } = Vue
const nameObj = reactive({ name: 'youge' })
watch( () => nameObj.name, (curValue, prevValue) => {
console.log(curValue, prevValue)
})
const { name } = toRefs(nameObj)
return { name }
}
当然还可以监听多个内容的, 即通过数组参数的形式哦.
<!DOCTYPE html>
<html lang="en">
<head>
<title>watch</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
// watch 监听器, 可监听多个对象
const app = Vue.createApp({
setup () {
const { reactive, toRefs, watch } = Vue
const nameObj = reactive({ name: 'youge', age: 18 })
watch( [() => nameObj.name,
() => nameObj.age
],
([curName, prevName], [curAge, prevAge]) => {
console.log('在监听', curName, prevName, '----', curAge, prevAge)
})
const { name, age } = toRefs(nameObj)
return { name, age }
},
template: `
<div>
<div>
name: <input v-model="name" />
</div>
<div>
name is: {{name}}
</div>
<div>
age: <input v-model="age" />
</div>
<div>
age is: {{name}}
</div>
</div>
`,
})
const vm = app.mount('#root')
</script>
</body>
</html>
梳理一下关于 watch 的特点无非就是:
- 具备一定的 lazy
- 参数可以拿到 prev 和 current
- 可监听多个数据变化, 用一个监听器, 数组传参的方式
watchEffect
它是一个新增的, 和 watch 的不同在于:
- 立即执行, 没有惰性
- 无需传递要监听的内容, 会自动感知代码依赖, 只需传递一个回调即可
- 不能获取之前数据的值
<!DOCTYPE html>
<html lang="en">
<head>
<title>watchEffect</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
// watch 监听器
const app = Vue.createApp({
setup () {
const { reactive, toRefs, watch } = Vue
const nameObj = reactive({ name: 'youge', age: 18 })
watch( [() => nameObj.name,
() => nameObj.age
],
([curName, prevName], [curAge, prevAge]) => {
console.log('在监听', curName, prevName, '----', curAge, prevAge)
})
// 立即执行, 没有惰性
// 无需传递要监听的内容, 会自动感知代码依赖, 只需传递一个回调即可
// 不能获取之前数据的值
watchEffect(() => {
console.log(nameObj.name)
})
const { name, age } = toRefs(nameObj)
return { name, age }
},
template: `
<div>
<div>
name: <input v-model="name" />
</div>
<div>
name is: {{name}}
</div>
<div>
age: <input v-model="age" />
</div>
<div>
age is: {{name}}
</div>
</div>
`,
})
const vm = app.mount('#root')
</script>
</body>
</html>
耐心和恒心, 总会获得回报的.