vue3 父组件和子组件如何传值 详解

目录

1.父组件打开子组件的的dialog组件

                 model-value 单向数据绑定

 2.父组件关闭子组件的的dialog组件

defineEmits

3.开始运用: 用户的增加修改操作

1.父组件的修改 

2.子组件的修改

3.父组件给子组件赋值

4.子组件调用父组件方法


 

 

1.父组件打开子组件的的dialog组件

        🕒新建一个vue文件命名为test

        🕒然后咱们直接从官网CV一个带有表单的dialog组件如下

 //子组件
<template>
  <el-dialog v-model="dialogFormVisible" title="Shipping address">
    <el-form :model="form">
      <el-form-item label="Promotion name" :label-width="formLabelWidth">
        <el-input v-model="form.name" autocomplete="off" />
      </el-form-item>
      <el-form-item label="Zones" :label-width="formLabelWidth">
        <el-select v-model="form.region" placeholder="Please select a zone">
          <el-option label="Zone No.1" value="shanghai" />
          <el-option label="Zone No.2" value="beijing" />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogFormVisible = false">Cancel</el-button>
        <el-button type="primary" @click="dialogFormVisible = false"
        >Confirm</el-button
        >
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
  import { reactive, ref } from "vue";
 
  const formLabelWidth = '140px'

  const form = reactive({
    name: '',
    region: '',
    date1: '',
    date2: '',
    delivery: false,
    type: [],
    resource: '',
    desc: '',
  })

</script>

<style scoped>
  .el-button--text {
    margin-right: 15px;
  }
  .el-select {
    width: 300px;
  }
  .el-input {
    width: 300px;
  }
  .dialog-footer button:first-child {
    margin-right: 10px;
  }
</style>

        👫父组件就只需要一个按钮  然后加上咱们的点击事件

<template>
  <el-button type="primary" @click="handlerDialog"
  >添加用户
  </el-button>
  <test />
</template>

<script setup>
  import { reactive, ref } from "vue";
  import test from './test'

  const dialogFormVisible = ref(false)

  const handlerDialog = () => {
    dialogFormVisible.value = true
  }
</script>

<style scoped>

</style>

然后这个时候发现 弹窗怎么点就是出不来

 注意原因就是咱们的 dialogFormVisible.value值还没传给子组件 所以是打不开的

这个时候就要用到v-model进行数据绑定

所以父组件要进行修改 在test这里加上如下内容

<test v-model="dialogFormVisible"
        v-if="dialogFormVisible"/>

 同样子组件也要修改 这里注意 是不能用v-model的  虽然官网的默认自带v-model     

但我们要作为子组件的话 vue3子组件是不能用v-model和父组件进行双向绑定的

那该怎么实现父子组件进行数据传递呢 咱们慢慢道来 咱们先实现父组件如何把dialogFormVisible的值传给子组件

其实很简单 在官网给的文档里面有这一行

017acdcf82af423da863e2c5be538e96.png

 model-value 单向数据绑定

 直接拿来CV到咱们的子组件上去

 <el-dialog :model-value="dialogFormVisible" title="Shipping address">

然后再去测试一下 可以了!!!

d67fa7a2e4e34215a1863e1186045c42.png


 2.父组件关闭子组件的的dialog组件

b0778dd930864520baab9d7ae80d7250.png  

 点击那个叉叉按钮可以关闭dialog组件  但是点击Cancel和Confirm按钮毫无反应

没错就是子组件没有传值到父组件上面去 所以!!! 重点来了


📦defineEmits

子组件向父组件事件传递

通俗点就是子组件可以调用父组件的方法并且可以传参

所以在我们的子组件里面修改以下代码

<template>
  <el-dialog :model-value="dialogFormVisible" title="Shipping address">
    <el-form :model="form">
      <el-form-item label="Promotion name" :label-width="formLabelWidth">
        <el-input v-model="form.name" autocomplete="off" />
      </el-form-item>
      <el-form-item label="Zones" :label-width="formLabelWidth">
        <el-select v-model="form.region" placeholder="Please select a zone">
          <el-option label="Zone No.1" value="shanghai" />
          <el-option label="Zone No.2" value="beijing" />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">



        //加上关闭的点击事件
        <el-button @click="handleClose">Cancel</el-button>
        <el-button type="primary" @click="handleClose"



        >Confirm</el-button
        >
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
//记得引入defineEmits
  import { reactive, defineEmits,ref } from "vue";

//实例化defineEmits
 const emits = defineEmits(['update:modelValue'])

//关闭的点击事件
  const handleClose = () => {
    emits('update:modelValue', false)
  }

  const dialogFormVisible = ref(false)



  const formLabelWidth = '140px'

  const form = reactive({
    name: '',
    region: '',
    date1: '',
    date2: '',
    delivery: false,
    type: [],
    resource: '',
    desc: '',
  })

</script>

<style scoped>
  .el-button--text {
    margin-right: 15px;
  }
  .el-select {
    width: 300px;
  }
  .el-input {
    width: 300px;
  }
  .dialog-footer button:first-child {
    margin-right: 10px;
  }
</style>

然后再去试试 完美解决!!!


3.开始运用: 用户的增加修改操作

这个想必并不陌生 一般情况下便于维护 增加和修改操作都是在一个dialog上的

所以我们需要通过传入一个参数来区分我们进行的是添加用户还是修改用户 

修改用户还得向子组件传入咱们表格那一行的数据

所以咱们简化一下

如果是添加用户 就传一个字符串

如果是修改用户 就传一个对象过去

思路清晰 开始操作!!!


1.父组件的修改 

在添加用户按钮上修改如下

  <el-button type="primary" @click="handlerDialog('添加用户')"
      >添加用户
      </el-button>

修改按钮这里就要用到自己的表格数据了 


 <template #default="{ row }" v-else-if="item.prop==='action'">
          
     <el-button type="primary" @click="handlerDialog(row)" :icon="Edit"/>
                
 </template>

解释一下 这里是elementplus的表格的自定义列 有疑惑的可以参考官网文档


 然后在修改点击事件handlerDialog

 const handlerDialog = (row) => {

    if(row==='添加用户'){
      dialogTitile.value = "添加用户"
      dialogTableValue.value = {}
    }else{
      dialogTitile.value = "修改用户"
      console.log(row)
      dialogTableValue.value = JSON.parse(JSON.stringify(row))

    }
    dialogFormVisible.value = true
  }

说明一下 JSON.stringify() 系列化对象
系列化对象说白了就是把对象的类型转换为字符串类型

最后 发现这里给子组件是传入了俩个参数

所以 我们要去给父组件绑定上

  <test v-model="dialogFormVisible"
        v-if="dialogFormVisible"
        :dialogTitile="dialogTitile"
        :dialogTableValue="dialogTableValue"
  />

2.子组件的修改

父组件给子组件需要一个插件

📦defineProps:父组件给子组件传值

加入以下方法 别忘了导入defineProps

 import {  defineProps } from 'vue' 
//接受父组件的值
  const props = defineProps({
    dialogTitile: {
      type: String,
      default: '',
      required: true
    },
    dialogTableValue:{
      type:Object,
      default: ()=>{},
    }

  })

这个时候添加用户的操作已经完成了

修改用户这块父组件已经传过来值了 接下来开始赋值操作


3.父组件给子组件赋值

📦这时候需要一个监听

所以我们要导入一个watch

import { watch } from 'vue'

watch(()=>props.dialogTableValue,()=>{

   form.value = props.dialogTableValue.value

},{deep:true,immediate:true})

 props是我们创建出来的实例 在defineProps那一块

form.value = props.dialogTableValue.value 是将我们父组件的dialogTableValue传给form对象

这时候再去测试以下 已经没问题了!!!


父组件传过来的值里面还有一个 dialogTitile 

我们知道修改用户的密码话在实际中是不能修改的

所以咱们一不做二不休

只需要修改一下form表单 加上一个v-if

<el-form-item label="密码" :label-width="formLabelWidth" prop="password" v-if="dialogTitile==='添加用户'">
        <el-input v-model="form.password" name="password" type="password" show-password/>
 </el-form-item>

4.子组件调用父组件方法

论异步 咱们就要异步到底 在添加用户和修改用户之后 我们可以调用父组件的更新表格内容的方法

在这里我是  initUserList  小伙伴就调用自己的就好了

所以最后 修改dialog的提交按钮如下

 const emits = defineEmits(['update:modelValue','initUserList']) 

const handleConfirm = () => {
    formref.value.validate(async (valid) => {
      if (valid) {
        props.dialogTitile==='添加用户' ? await adduser(form.value) : await editUser(form.value)
        props.dialogTitile==='添加用户' ? ElMessage.success("添加成功"):ElMessage.success("修改成功")
        emits('initUserList')
        handleClose()
      } else {
        props.dialogTitile==='添加用户' ? ElMessage.error('"添加失败'):ElMessage.success("修改失败")
        return false
      }
    })

  }

完结撒花🔥🔥🔥

欢迎评论点赞关注💪💪💪

 

  • 21
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
Vue3中,组件向子组件传值有多种方法。其中一种方法是使用`defineProps`,在组件中定义props属性,然后将需要传递给子组件的值作为props的属性值。在子组件中,可以使用`props`接收组件传递的值。 具体实现步骤如下: 1. 在组件中使用`defineProps`定义props属性,并将需要传递给子组件的值作为props的属性值。 2. 在子组件中使用`props`接收组件传递的值。 下面是一个示例代码,展示了如何在Vue3中实现向子组件传值: ```javascript // 组件 Father.vue <template> <div class="fa"> <div style="margin: 10px;">我是组件</div> 组件接收子组件传的值:{{ sonMessage }} <Son :message="sonMessage"></Son> </div> </template> <script setup lang="ts"> import Son from './Son.vue' import { ref } from "vue"; const sonMessage = ref<string>(""); </script> <style scoped> .fa { border: 3px solid cornflowerblue; width: 400px; text-align: center; } </style> ``` ```javascript // 子组件 Son.vue <template> <div class="son"> <div style="margin: 10px;">我是子组件</div> 子组件接收组件传的值:{{ message }} </div> </template> <script setup lang="ts"> import { defineProps } from "vue"; const props = defineProps({ message: String, // 定义props属性,接收组件传递的值 }); </script> <style scoped> .son { border: 3px solid lightgreen; width: 200px; text-align: center; } </style> ``` 在组件中,使用`:message="sonMessage"`将`sonMessage`的值传递给子组件的`message` props属性。在子组件中,使用`props`接收组件传递的值,并在模板中展示。 这样,就实现了在Vue3中组件向子组件传递值的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Vue3父子组件间传参通信](https://blog.csdn.net/qq_45397526/article/details/126281133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [vue3 组件和子组件如何传值 详解](https://blog.csdn.net/qq_56263094/article/details/124576055)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

owensweat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值