Vue3当中prop父子通信,prop在代码当中不具有响应式解决方案

166 阅读3分钟

问题分析

Vue3:当我们建立父子通信时,父组件传递给子组件的值,只有在模板上使用,才会具有响应式,我们在代码上使用的时候,就只能拿到刚开始传入的prop的“死值”,即使父组件值发生改变,它依旧保持不变,但是模板上,它还是具有响应式的,问题就是我们业务需求就是想拿到这个prop值,进行代码逻辑计算之后,在进行渲染到模板上

情景导入+解决方法

方法一:比较官方
解决父子组件页码同步的问题:

有一组数据,从父组件传入,但是我们是把数据渲染到表格上,肯定会涉及到分页,那么我们点击分页按钮时,数据应该进行筛选,重新渲染。首先要解决的就是点击某个页码,切换这个页码对应的数据。我们一般会把组件的交互权限交给父组件,那么我们子组件被点击的时候,就需要通过event up发生自定义事件给父组件,由父组件自行解决数据,子组件只负责交互和展示;这里也是组件封装的思想之一;子组件就干 展示+交互,至于交互做什么处理,以及数据怎么处理,我子组件一概不管,交给你父组件

//分页器,用的是Element组件,里面的页码通过v-model双向数据绑定
//这里可以通过Watch数据侦听,侦听currentPage数据的变化
<template>
    <div class="my-pagination">
           <el-pagination background layout="prev, pager, next" :page-size="pageSize" :total="tableData.length" v-model:current-page="currentPage" />
    </div>
</template>

//侦听currentPage数据逻辑,当数据一变化,就把当前页码emit()发送自定义事件并携带当前页码数,给父组件
<script setup>
    const currentPage = ref(1);
    watch(
           /* 监听页码项 */
        () => currentPage,
        /* 发生变化时,传递给父组件更新 */
        (nv, ov) => {
            console.log("currentPage changed", nv, ov);
            emit("pageChange", nv)
        }
    )
</script>

解决分页数据问题:
    //父组件
    <EpTable @pageChange="onPageChange" :tableData="computedData"></EpTable>
    
    const currentPage = ref(1);
    const onPageChange = (page)=>{
            currentPage.value = page
        }
     
     //计算分页数据具体逻辑(一页十条)
     const computedData = computed(() => tableData.value.slice((currentPage.value - 1) * 10, currentPage.value * 10));
     //最终把这个计算出来的分页数据注入给子组件
方法二:来点简单粗暴的

父组件传入全部数据,由子组件自己进行数据的选择,当用户选择页码,(分页器当中的页码一变化)就导致重新刷新这个模板,再重新调用这个模板上的方法,获得最新数据

父组件就当甩手掌柜,一开始就把数据丢给你子组件,你爱怎么处理就怎么处理,可能和上头组件封装思想有点出入,但是实际问题实际分析,你就看看这方法二好还是方法一好

     //父组件
    <EpTable  :tableData="tableData"></EpTable>
    
    
    <script setup>
        const tableData = ref([])
           
         //这是具体业务逻辑,联网获取所有数据
        onMounted(async () => {
            const films = await getComings()
            console.log("films", films);
            tableData.value = films;

})
    </script>
//子组件
<el-table :data="getNewData(tableData)"></el-table>

//由于prop传入的值,在代码中不具有响应式,在模板上才有,将计就计,把数据放入一个函数,传递到代码当中,进行计算之后,我再把返回值丢给模板自行渲染

//当我们选择页码,(分页器当中的页码一变化)就导致重新刷新这个模板,就会重新调用这个模板上的方法,获得最新数据,重绘页面
<script setup>
    const getNewData = (arr) => {
    return arr.slice((currentPage.value - 1) * pageSize, (currentPage.value) * pageSize)
}
</script>

最后,你们觉得哪种更好呢?

下课!