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>

耐心和恒心, 总会获得回报的.