Vue中打开和关闭弹窗时父子组件传值

每次写父组件到子组件传值和双向数据绑定都会忘,记下……

单项数据流Vue.js介绍

父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。

在这里插入图片描述

  1. 常用的子组件使用computed$emit()
    父组件:
<template>
  <div class="">
    <a-button type="primary" @click="openChild">打开和关闭弹窗</a-button>
    <Son :isVisible="isShowSon" @close="closeDialog" :title="title" @changeTitle="change"></Son>
  </div>
</template>
<script>
// 引入子组件
import Son from "@/views/components/Son";
export default {
  name: "Parent",
  components: {Son},
  data() {
    return {
      isShowSon: false, //是否显示子组件
      title:''
    };
  },
  methods: {
    // 打开弹窗,并向子组件传递title值
    openChild() {
      this.isShowSon = true;
      this.title='你笑起来真好看'
    },
    // 打开或关闭弹窗
    closeDialog(val) {
      this.isShowSon = val;
    },
    // 改变title
    change(val){
      this.title=val
    }
  },
};
</script>

子组件:使用computed接收父组件的值,并使用$emit方法向父组件传值。

<template>
  <div class="main" >
    <a-modal v-model="visible" title="新增表单" @ok="handleOk"  @cancel="handleCancel">
      子组件接收的值为: <a-tag color="orange" @click="changeTitle">{{title}}</a-tag>
    </a-modal>
  </div>
</template>
<script>
export default {
  name: "Son",
  props:{
    //父组件传递的值,要改变的
      isVisible:{
          type:Boolean,
          default:false
      },
    //常规数据
      title:{
          type:String,
          default:''
      }
  },
  computed: {
      /* visible用来接收和改变父组件的值:isVisible */
      visible:{
          get(){
              if(this.isVisible){this.init()}//打开弹窗的时候直接去初始化,不知道写在哪里了啊
              return this.isVisible //接收父组件传递的值
          },
          set(val){
            // 使用$emit方法去改变父组件传递的isVisible值,父组件使用close方法接收,val是当前传递的值
            this.$emit('close',val)  
          }
      }
  },
  methods: {
    handleOk(e) {
     // 不能直接修改父组件中的值,父->子:单向数据流 this.isVisible = false;会有警告
        this.visible=false
    },
     handleCancel(e) {
         this.visible=false
    },
    init(){
      console.log('可以做初始化数据了----');
    },
    changeTitle(){
      this.$emit('changeTitle','哦,不想写了啊啊啊')
    }
  },
};
</script>
  1. 可以同步更新数据,父组件中使用sync修饰参数,子组件中使用this.$emit('update:isVisible',val)向父组件传值。
    父组件
<template>
  <div class="">
    <a-button type="primary" @click="openChild">打开和关闭弹窗</a-button>
     <Son :isVisible.sync="isShowSon" :title.sync="title"></Son>
  </div>
</template>
<script>
// 引入子组件
import Son from "@/views/components/Son";
export default {
  name: "Parent",
  components: {Son},
  data() {
    return {
      isShowSon: false, //是否显示子组件
      title:''
    };
  },
  methods: {
    openChild() {
      this.isShowSon = true;
      this.title='你笑起来真好看啊'
    },
  },
};
</script>

子组件:在computed中同步更新父组件中isVisible

<template>
  <div class="" >
    <a-modal v-model="visible" title="新增表单" @ok="handleOk"  @cancel="handleCancel">
      子组件接收的值为: <a-tag color="orange" @click="changeTitle">{{title}}</a-tag>
    </a-modal>
  </div>
</template>
<script>
export default {
  name: "Son",
  props:{
      isVisible:{
          type:Boolean,
          default:false
      },
      title:{
          type:String,
          default:''
      }
  },
  computed: {
      visible:{
          get(){
              if(this.isVisible){this.init()}
              return this.isVisible 
          },
          set(val){
            //更新父组件中的isVisible
            this.$emit('update:isVisible',val)
          }
      }
  },
  methods: {
    handleOk(e) {
         this.visible=false
    },
     handleCancel(e) {
         this.visible=false
    },
    init(){
      console.log('可以做初始化数据了----');
    },
    changeTitle(){
        this.$emit('update:title','哦,不想写了啊啊啊')
    }
  },
};
</script>
  1. 父传子,这种方法更简单些,父组件中使用refs,可以直接修改子组件中的属性方法。子组件就像正常组件那样写就行了。
    父组件
<template>
  <div class="">
    <a-button type="primary" @click="openChild">打开和关闭弹窗</a-button>
      <Son ref="son"></Son>
  </div>
</template>
<script>
// 引入子组件
import Son from "@/views/components/Son";
export default {
  name: "Parent",
  components: {Son},
  methods: {
    // 打开弹窗,$refs可以直接操作子组件中值和方法等
    openChild() {
     this.$refs.son.visible=true
     this.$refs.son.title='你笑起来真好看'
     this.$refs.son.init(1234) //调用子组件中的方法
    },
  },
};
</script>

子组件

<template>
  <div class="">
    <a-modal v-model="visible" title="新增表单" @ok="handleOk"  @cancel="handleCancel">
      子组件接收的title为: <a-tag color="orange">{{title}}</a-tag>
    </a-modal>
  </div>
</template>
<script>
export default {
  name: "Son",
  data(){
      return{
          title:'',
          visible:false
      }
  },
  methods: {
    handleOk(e) {
        this.visible=false
    },
     handleCancel(e) {
         this.visible=false
    },
    // 初始化数据一般情况
    init(id){
        console.log('拿到了ID可以请求其他数据了',id);
    }
  },
};
</script>
  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值