• VUE父组件向子组件传递值


    创作灵感

    最近在写一个项目时,遇到了这样的一个需求。我封装了一个组件,这个组件需要被以下两个地方使用,一个是搜索用户时用到,一个是修改用户信息时需要用到。其中,在搜索用户时,可以根据姓名或者账号进行搜索。根据账号一次只能搜索出一个用户,根据姓名可以一次性搜出许多名字包含该内容的用户,如下图:

    按名称搜索示意图

    然而,在更改用户信息界面使用该组件时,我们不希望用户能通过姓名来查询,因为我们是一个一个的修改用户信息的,如果通过姓名查询会查询出多个数据。因此,我们需要在更新用户信息界面使用该组件是禁止选择姓名选项,如下:

     禁止按名称搜索示意图

    效果实现

    要想实现上面的效果,大致思路就是父组件在使用子组件时,传递一个参数,根据这个参数选择是否禁用。这就需要用到父组件向子组件传递值的知识了。父组件向子组件传值最简单的就是props了,如果有多重传递,则需要用到别的方法,大家可以去了解一下,这里我使用的是props。

    下面为子组件与父组件的代码实现:

    1. <style scoped lang="scss">
    2. style>
    3. <script lang="ts">
    4. import { defineComponent,reactive, ref, toRaw } from 'vue'
    5. import API from '@/untils/axios'
    6. import { ElMessage } from 'element-plus'
    7. export default defineComponent({
    8. props:['noSelect'],
    9. emits:["returnResults"],
    10. name:"searchComponent",
    11. setup(){
    12. var select=ref("1")
    13. var content=ref("")
    14. var users=reactive({//返回的前十位用户信息
    15. data:[]
    16. })
    17. var total=ref(0)
    18. return{
    19. select,
    20. users,
    21. total,//总的记录数
    22. content
    23. }
    24. },
    25. methods:{
    26. search(){
    27. if(this.content==""){
    28. ElMessage({
    29. message:"搜索值为空",
    30. type:"warning"
    31. })
    32. return
    33. }
    34. API.get("admin/searchUsers",{
    35. params:{
    36. type:this.select,
    37. content:this.content
    38. }
    39. }).then((res:any|undefined)=>{
    40. if(res==undefined){
    41. return
    42. }
    43. if(res.data.users.length==0){
    44. ElMessage({
    45. message:"搜索为空",
    46. })
    47. } else {
    48. ElMessage({
    49. message:"搜索成功",
    50. type:"success"
    51. })
    52. }
    53. this.users.data=res.data.users
    54. this.total=res.data.total
    55. var result={
    56. users:toRaw(this.users.data),//搜索出来的前10位信息
    57. total:this.total,
    58. content:this.content
    59. }
    60. this.$emit("returnResults",result)
    61. })
    62. }
    63. }
    64. })
    65. script>

    大家主要看到的是props,里面就包含了父组件传来的'noSelect',子组件根据传来的值来禁止需要禁止的选项

    父组件传递值:

    1. <script lang="ts">
    2. import { defineComponent } from 'vue'
    3. import searchComponent from "@/components/searchComponent.vue"
    4. export default defineComponent({
    5. components:{
    6. searchComponent
    7. }
    8. })
    9. script>
    10. <style scoped lang="scss">
    11. .searchComponent{
    12. margin: 5vh;
    13. }
    14. style>

    在这里,我在使用子组件时,向其传递了'noSelect'值为2,意味着禁止了姓名选项。子组件拿到值后就可以根据拿到的值来禁止对应的选项卡了。

    子向父动态的取得值并且能够改变该值

    其实上面的这个标题并不完全正确,因为一般情况下,我们并不希望子组件可以直接修改父组件的值,如果真的有类似的需求,应当如何完成呢?答案是子组件复制父组件所传递的值,而后修改复制后的值就可以了。下面向大家展示一下具体的应用场景:

    在上面的这个场景内,我们需要用到两个子组件,搜索的子组件与展示个人信息的子组件。其中、展示个人信息的子组件用到了两次,一次为仅供展示的,一个是可供编辑的,这样在修改个人信息时,就可以知道自己修改了哪些部分。但是需要注意的是,一开始个人展示组件里面的信息是空的,我们如何使其在拿到父组件的值后能相应的更改呢?(由于我在子组件内可能需要改变父组件传递的值,所以我们不能直接使用父组件的响应式来完成这个功能)。

    这时我们就需要监听父组件传递的值,如果其发生了改变,我们就改变子组件本地备份的数据,就能做到——既可以编辑父组件传递的值(实际上为其对应的深拷贝对象)、又能在父组件重新给值时响应式的改变子组件的内容了。具体代码如下:

    子组件的js部分

    上述js中,我在setup()内定义了一个本地的localUser,并且将其定义为了一个响应式的对象。其内部的值取自父组件传来的user对象,子组件可以通过编辑localUser对象,令用户感觉他们在编辑user一样。同时,此时如果还想父组件的user发生改变,子组件同时改变时,必须使用watch进行监听了。有人或许会说,我们把父组件的user对象设置为一个响应式对象不就行了?然而,由于子组件展示的是localUser,不是父组件的user,在子组件内没有触发localUser对象的值发生改变是不会令其内容发生变动的。所以必须使用一个监听器来监听父组件的值发生变动时,及时的将变动的新值赋值给子组件的本地user

    其他问题

    在介绍完这些后,最后向大家再介绍一个易错点,那就是浅拷贝问题。因为我这里的展示面板使用了两次,一个是仅供参考的,一个是可供编辑的。但如果在向两个子组件传值时使用的是浅拷贝,会导致在编辑面板修改时,展示面板也会被修改。解决办法就是在编辑面板传值时使用深拷贝。具体的大家可以翻看我之前的文章,下面向大家展示一下我的解决方法:

    上面的就是我父组件的js内容,其中,在对writerUser对象赋初始值以及后面的任何一次赋值都使用了深拷贝(建议不要按照我这样来,深拷贝还有其他方法,这里我图方便就没用了

    感谢大家的观看!!!

  • 相关阅读:
    QT6.5.2编译PostgreSql驱动
    Hadoop
    学好MySQL增删查改,争取不做CURD程序员【上篇】
    JAVA毕业设计096—基于Java+Springboot+Vue的在线教育系统(源码+数据库+18000字论文)
    2022年下半年软件设计师知识集锦
    Sfdp 超级表单开发平台 V6.0.4 正式发布
    TCP三次握手和四次挥手基本知识
    2019 java面试题基础
    【工艺库】SMIC数字后端工艺库
    vscode中 vue3+ts 项目的提示失效,volar插件失效问题解决方案
  • 原文地址:https://blog.csdn.net/m0_60689237/article/details/138082244