1. v-for数据元素已发生变化,但页面数据不更新
const data = ref([])
const change = (res) => {
data.value = res
}
const data = ref([])
const change = (res) => {
data.value = []
data.value.push(...res)
//或 data.value = [].concat(res)
}
2. dom元素渲染及父子组件props传值延迟问题——nextTick
2.1 获取dom元素宽高等信息
<div ref="parentSize" stylr="width: 100%; height: 100%">
<div :style="{'width': size, 'height': size}">'30%'</div>
</div>
const parentSize = ref()
const size = ref()
onMounted(async () => {
await nextTick()
size.value = parentSize.value.offsetWidth / 3
})
2.2 props传值
//父组件
<Son :tag="tag"/> //调用子组件
<button @click="change">change tag</button>
//父组件
import Son from '......'
const tag = ref(0)
const change = () => {
tag.value = 1;
}
//子组件
const props = defineProps<{
flag: number
}>()
const deal = async() => {
await nextTick()
console.log(props.flag)
//......
}
2.3 nextTick
- Vue在更新DOM时是异步执行的。当数据发生变化,Vue将开启一个异步更新队列,视图需要等队列中所有数据变化完成之后,再统一进行更新。
- nextTick()方法可以实现dom数据更新后延迟执行后续代码、
3. watch监听响应式对象的属性值
3.1 监听父组件数据
watch(props.tag, (newVal) => {
//......
}
watch(() => props.tag, (newVal) => {
//......
}
3.2 监听子组件数据
//父组件
<Son ref="sonComp" /> //调用子组件
//子组件
const tag = ref(0)
const tagChange = () => {
//......
}
defineExpose({
tag
})
//父组件
import Son from '......'
const sonComp = ref()
watch(sonComp.value.tag, (newVal) => {
//......
}
onMounted(() => {
//......
)
- 正确做法:watch需写在mounted里, 因为这时ref指向的子组件才加载完成并能够获取到,
//子组件
const tag = ref(0)
const tagChange = () => {
//......
}
defineExpose({
tag
})
//父组件
import Son from '......'
const sonComp = ref()
onMounted(() => {
watch(sonComp.value.tag, (newVal) => {
//......
}
//......
)