Vue中父子组件传参

父组件向子组件传参

父组件代码:

<template>
  <div>
    <h1>这是父页面</h1>
    // 父组件在调用子组件的时候,传入参数
    <Son msg="这是父组件传到子页面的参数"></Son>
  </div>
</template>

<script>
// 导入需要的子组件  import后面的Son可自定义
import Son from "./Son";
export default {
  components:{
    // 组件与标签的映射
    Son,
  },
}
</script>

子组件代码:

<template>
  <div>
    <h2>这是子页面</h2>
    {{msg}}
  </div>
</template>

<script>
export default {
  // 在子组件中声明props属性,定义一些属性变量 
  props:['msg']
}
</script>

效果:
在这里插入图片描述

子组件向父组件传数据,并修改父组件传递的参数

子组件向父组件传数据和子组件修改父组件传递的参数类似,所以就写一起了。
这里为了展示更加复杂的项目逻辑,因而使用了Element 组件。

需要注意的是:

在Vue中,不推荐子组件直接修改父组件的参数。例如:把一个布尔值传递给子组件,然后在子组件中修改该值,会报错:

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders

原因:

父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。

Prop 是单向绑定的:

当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解。
所以为了实现子组件修改父组件的效果,需要将修改过后的值传到父组件中,由父组件重新赋值即可。

父组件代码:

<template>
  <div>
    <h1>这是父页面</h1>
<!--    点击事件将dialogVisible的值改为true,使得:dialogVisible=true,展示子组件的弹窗-->
    <el-button type="primary" @click="dialogVisible=true">新建</el-button>
<!--    在父组件调用子组件时,定义一个接收事件,putDialogVisible就是定义好的一个事件-->
    <Son :dialogVisible="dialogVisible" @putDialogVisible="putDialogVisible"></Son>
  </div>
</template>

<script>
import Son from "./Son";
export default {
  components:{
    // 映射组件
    Son,
  },
  data(){return{
    dialogVisible:false,
  }},
  methods:{
    // 父组件接收经过子组件传递的参数,这个参数是由父组件传到子组件的并经过子组件修改的
    // 重新对dialogVisible进行赋值,以达到子组件修改父组件传递的参数的目的
    putDialogVisible(data){
      this.dialogVisible = data
    }
  },
}
</script>

子组件代码:

<template>
  <div>
    <h2>这是子页面</h2>
    <el-dialog title="创建用户" :visible.sync="dialogVisible" width="50%">
      <el-form ref="form" :model="form" label-width="80px">
        <el-form-item label="用户名">
          <el-input v-model="form.username"></el-input>
        </el-form-item>
        <el-form-item label="密码">
          <el-input v-model="form.password"></el-input>
        </el-form-item>
        <el-form-item label="手机号">
          <el-input v-model="form.phone"></el-input>
        </el-form-item>
        <div>
          <el-button type="primary" @click="onSubmit">创建</el-button>
          <el-button @click="cancel">取消</el-button>
        </div>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
export default {
  // 在子组件中声明props属性,定义一些属性变量,接收父组件传递的参数dialogVisible
  // 此时dialogVisible = true
  props:['dialogVisible'],
  data(){
    return {
      form:{
        username:"",
        password:"",
        phone:"",
      },
      role_list:[{"id":"1","name":"管理员"},{"id":2,"name":"普通用户"}]
    }
  },
  methods:{
    onSubmit(){
      alert('添加')
    },
    cancel(){
      // 点击取消按钮,定义一个新变量,值为false
      let data = false
      // 子组件触发事件并传递数据将新变量传递给父组件,达到修改参数的目的
      this.$emit('putDialogVisible',data)
    }
  },
}
</script>

效果:
在这里插入图片描述
点击新建按钮(点击‘取消’后弹窗消失):
在这里插入图片描述

上面的解决办法是指传递的参数只应用于一个子组件,并不满足应用多个子组件时的情况,当应用于多个子组件时,使用以下方法:

子组件不能修改父组件传递过来的值的原因,就是因为vue的单向数据流限制,当然,这个限制是很有必要的,我们假设一个场景,父组件有多个子组件,都用到了某个传递的参数,其中一个子组件修改了父组件传递过来的值,那么其他的子组件接收到的也会是改变后的值,这样显然是不合理的。
既然不能直接修改,那么,我们不妨在子组件定义一个副本,用来接收父组件传递过来的值,子组件定义的每个参数,其作用域都只局限于当前组件,所以,直接修改副本,并不会影响其他子组件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值