问题阐述
问题描述
父组件传递给子组件 props,由于父组件的业务需求,希望子组件通过 watch 监听 props 修改数据。
父组件模板:
<PaginationPage
ref="pagination"
@fixed-change="fixedChange"
@float-change="floatChange"
:current-index="currentIndex"
:page-count="pageCount">
</PaginationPage>
子组件 setup:
const props = defineProps({
pageCount: {
type: Number,
default: 2
},
currentIndex: {
type: Number,
default: 1
}
});
let _pageCount = $ref<number>(props.pageCount);
let _currentIndex = $ref<number>(props.currentIndex);
// 监听 props,发生变化时更新
watch(() => props.pageCount, () => {
_pageCount = props.pageCount;
});
// 监听 props,发生变化时更新
watch(() => props.currentIndex, () => {
_currentIndex = props.currentIndex;
});
子组件模板:
<el-pagination
@current-change="fixedSorterChange"
v-model:current-page="_currentIndex"
v-model:page-count="_pageCount"
:background="true"
layout="prev, pager, next, jumper"
/>
发生前提
由于子组件使用了 element-plus 分页组件,而分页组件 page-count、current-page 都是双向响应式数据,而 vue3 不允许我们把 props 传递给组件的双向响应式数据(即通过 v-model 绑定的 model 值)。因此,我就再声明一个新的响应式数据,把 props 赋值过去,再把这个新的响应式数据传递给分页组件。
需求描述
父组件 watch 监听路由变化,修改传递给子组件的 props,希望子组件通过 watch 监听到在父组件中,传递给子组件的 props 变化,子组件的 watch 触发从而更新数据。
父组件 setup:
watch(route, () => {
pageCount = 2;
currentIndex = 1;
});
发生原因
- pageCount 与子组件的 props 初始值保持一致,watch 不会触发;
- 路由切换时,可能 pageCount 发生变化,子组件监听到了并触发,可能 currentIndex 没有变化,子组件对应的 watch 也没有变化。
总而言之,watch 显得有些不合适。defineExpose
,暴露一个函数,这个函数来修改子组件本身的数据,减少更多的代码。父组件通过 ref 获取子组件对象,调用暴露出来的函数。
子组件 setup:
const updateProps = () => {
_pageCount = 2;
_currentIndex = 1;
};
defineExpose({ updateProps });
父组件 setup:
const pagination = ref();
watch(route, () => {
pagination.value.updateProps();
});
问题总结
根本原因发生在,因为数据一样,或者某些原因没有导致被监听的响应式数据发生改变,就不可能触发 watch。希望,不管也没有变化都触发函数,并执行其他逻辑(子组件里的),推荐暴露一个函数,专门做这件事,父组件 ref 拿到之后,不管怎么样都触发子组件暴露出来的函数即可。
标签:pageCount,Vue3,watch,currentIndex,props,组件,监听 From: https://www.cnblogs.com/Enziandom/p/17020946.html