# 1. 在 setup 里拿到 ref 元素
App 为根组件 下面 Home 例子都被此组件引用
// App.vue | |
<template> | |
<div> | |
<home></home> | |
</div> | |
</template> | |
<script> | |
import Home from "./Home.vue"; | |
export default { | |
components: { | |
Home, | |
}, | |
}; | |
</script> | |
<style scoped></style> |
// Home.vue | |
<template> | |
<div> | |
<h2 ref="title">哈哈哈</h2> | |
</div> | |
</template> | |
<script> | |
import { ref } from "vue"; | |
export default { | |
setup() { | |
const title = ref(null); | |
// 这里打印会发现并不是绑定的元素,是因为元素还有没有挂载上去,现实的还是默认赋值的 null | |
console.log(title.value); | |
return { | |
title, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
</style> |
参考结果:
# 2. 使用 watchEffect
// Home.vue | |
<template> | |
<div> | |
<h2 ref="title">Nekoaimer</h2> | |
</div> | |
</template> | |
<script> | |
import { ref, watchEffect } from "vue"; | |
export default { | |
setup() { | |
const title = ref(null); | |
watchEffect(() => { | |
// 提问:为什么会先打印出 null 然后才是获取到的元素呢? | |
console.log(title.value); | |
}); | |
return { | |
title, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
</style> |
参考结果:
# 3.watchEffect 中 flush 的使用
// Home.vue | |
<template> | |
<div> | |
<h2 ref="title">Nekoaimer</h2> | |
</div> | |
</template> | |
<script> | |
import { ref, watchEffect } from "vue"; | |
export default { | |
setup() { | |
const title = ref(null); | |
//watchEffect 有两个参数,第一个是回调函数,第二个是一个对象:flush | |
watchEffect( | |
() => { | |
console.log(title.value); | |
}, | |
{ | |
flush: "post", | |
} | |
); | |
return { | |
title, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
</style> |
参考结果:
# 4. 总结
- 为什么会打印两次不同的结果?
- 首先应该了解 watchEffect 会默认执行一次,而第一次执行的时候元素还没有挂载上去,所以显示的默认赋的初始值 null
- 其次等元素挂载上了之后,title 的数据必然会发生改变,那么就会触发 watchEffect 监听 。所以会再一次执行内部函数,打印出已经挂载好的元素!
- watchEffect 有两个 参数,第一个是 回调函数,第二个是一个对象,里面有一个 flush 属性
- flush 有三个值 :
- 默认为 pre(它会提前执行,不管 DOM 有没有挂载完)
- post:(等 DOM 挂载完或者更新完再执行)
- sync:强制同步 (官方不建议使用)