vue中props数据变化的问题

本文介绍了在Vue项目中遇到的一个父子组件数据传递问题,即父组件传递的数据无法使子组件的显示状态及时更新。通过分析,发现问题在于子组件内部对props的响应性处理不当。提供了两种解决方案:1) 在子组件中通过watch监听props并手动同步数据;2) 使用计算属性的setter来实现数据的双向绑定。这两种方法都能有效解决子组件无法响应父组件数据变化的问题。
摘要由CSDN通过智能技术生成

发现问题

在vue项目中,父子组件数据传递是最常见的场景,但是今天在开发过程中父级数据传递到子组件,控制子组件的显隐,发现存在问题,一直监听不到数据的变化,详细排查后发现是因为props在传递数据的时候子组件接收到数据后没有及时发生变化导致的。

这里使用的是 iview 框架

// 子组件
<template>
    <Modal
        v-model="isShowModel"
        title="测试弹窗">
        <p>Content of dialog</p>
        <p>Content of dialog</p>
        <p>Content of dialog</p>
    </Modal>
</template>

<script>
export default {
    name: 'TestModel',
    props: {
        showModel: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            isShowModel: this.showModel
        }
    }
}
</script>
// 父组件
<template>
  <div id="app">
    <TestModel :showModel="showModel"></TestModel>
    <Button type="primary" @click="changeShowModel">显示弹窗</Button>
  </div>
</template>

<script>
import TestModel from './components/TestModel.vue'

export default {
  components: {
    TestModel
  },
  data() {
    return {
      showModel: false,
    }
  },
  methods: {
    changeShowModel() {
      this.showModel = true;
    }
  }
}
</script>

问题分析

预期效果是点击按钮直接弹出弹窗,结果怎么也弹不出来。子组件中增加 watch 监听 props 发现数据已经变化了,但是 data 中接收 props 数据的变量并未改变,发现问题所在。

问题原因就是接收 props 数据的变量无法及时响应 props 的变化,下一步解决问题就是重点解决响应变化问题。

问题解决

解决方案1

子组件中增加 watch 监听 props 中传进来的数据变化,同时当子组件数据变化时,数据上传父组件。

// 子组件
<template>
    <Modal
        v-model="isShowModel"
        width="1000"
        title="测试弹窗"
        @on-cancel="cancel"    
    >
        <p>Content of dialog</p>
        <p>Content of dialog</p>
        <p>Content of dialog</p>
    </Modal>
</template>

<script>
export default {
    name: 'TestModel',
    props: {
        showModel: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            isShowModel: this.showModel
        }
    },
    watch: {
        showModel(v) {
            this.isShowModel = this.showModel
        }
    },
    methods: {
        cancel() {
            this.$emit('cancel', this.isShowModel);
        }
    }
}
</script>
// 父组件
methods: {
    modelCancel(v) {
        this.showModel = v;
    }
}

解决方案2

使用 vue 中的计算属性( computed )中的 set 方法。

// 子组件
<template>
    <Modal
        v-model="isShowModel"
        width="1000"
        title="测试弹窗"
    >
        <p>Content of dialog</p>
        <p>Content of dialog</p>
        <p>Content of dialog</p>
    </Modal>
</template>

<script>
export default {
    name: 'TestModel',
    props: {
        showModel: {
            type: Boolean,
            default: false
        }
    },
    computed: {
        isShowModel: {
            set(v) {
                this.$emit('cancel', v);
            },
            get() {
                return this.showModel;
            }
        }
    },
}
</script>

有兴趣的兄弟可以关注我的博客 www.maple.ink
个人博客

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值