返回顶部
首页 > 资讯 > 前端开发 > JavaScript >详细解读VUE父子组件的使用
  • 168
分享到

详细解读VUE父子组件的使用

VUE组件VUE父子组件 2023-05-19 20:05:13 168人浏览 薄情痞子
摘要

目录1.递归组件2.组件之间的循环使用二,深层次的问题**1.父传子****2.子传父***3.兄弟关系** 4.子组件复用5.父组件通过ref调用子组件的方法我们对父子组

我们对父子组件的学习,接触的一般是子组件通过事件传参给父组件,父组件拿到参数再进行处理,用来处理表单提交,弹框信息等等,再者就是父组件通过自定义属性传值给子组件,子组件通过props接收,watch监听新值,达到组件的复用的效果;

后我在Vue官网接触到一种子父组件深度耦合的方式,使我们不用额外的创建新的组件,也可以达到一些效果,下面与你们分享一下:

1.递归组件

看名字我们就知道,这是对组件进行递归,vue给我们提供的不只是递归子组件,而且可以在自己的模板中调用自己;

//parent.vue
<template>
<div>
//对子组件传值
<HomeView :list="list"></HomeView>
</div>
</template>
import HomeView from "./HomeView.vue";
<script>
export default{
        component:{
            HomeView
        }
        data(){
            return{
                 list: [{
          name: "经济",
          children: [{
              name: "如家",
              children: [{
                  name: "上江路-如家"
                },
                {
                  name: "望江路-如家"
                }]
            },{
              name: "7天",
              children: [{
                  name: "长江路-7天"
                },
                {
                  name: "望江路-7天"
                }]
            }]
        }],
            }
        }
}
</script>

这里面的数据是嵌套的,嵌套两层children,一般我们可能会拿到数据用两个标签嵌套渲染,这里vue给我们提供了调用自己组件的方法:

//child.vue
<template>
<div>
 <div class="list-item" v-for="(item, index) in list" :key="index">
            <div class="item-name">
                <span>{{item.name}}</span>
            </div>
            <div v-if="item.children" class="children-item">
                    //调用自身  节省一个for循环
                <HomeView :list="item.children"></HomeView>
            </div>
        </div>
</div>
</template>
<script>
export default{
        //通过name选项做调用自身的事情
    name:'HomeView',
      props:{
        list: Array
      },
}
</script>

让原本两次for循环的模板变得简洁易懂,虽然节省了一次for循环,但是这样做也是有缺点的,就是容易陷入无限循环中,这是我们需要注意的,最后得到的效果是:

 这是vue给我们提供的多一种的使用组件方式

2.组件之间的循环使用

你可以理解为子父组件的深度耦合,相互调用从而更方便达到节点数的效果,形成相互循环渲染的效果

效果图:

数据源:

 folders: [
          {
            name: 'folder1',
            children: [{
              name: 'folder1 - folder1',
              children: [{
                name: 'folder1 - folder1 - folder1'
              }]
            }, {
              name: 'folder1 - folder2',
              children: [{
                name: 'folder1 - folder2 - folder1'
              }, {
                name: 'folder1 - folder2 - folder2'
              }]
            }]
          },
          {
            name: 'folder 2',
            children: [{
              name: 'folder2 - folder1',
              children: [{
                name: 'folder2 - folder1 - folder1'
              }]
            }, {
              name: 'folder2 - folder2',
              children: [{
                name: 'folder2-content1'
              }]
            }]
          },
          {
            name: 'folder 3',
            children: [{
              name: 'folder3 - folder1',
              children: [{
                name: 'folder3 - folder1 - folder1'
              }]
            }, {
              name: 'folder3 - folder2',
              children: [{
                name: 'folder3-content1'
              }]
            }]
          }
        ],

 这个案例有爷爷组件这块我有在全局进行注册,HomeView.vue是爷爷组件,包含数据源,引进父级组件等操作;

main.js全局注册:

HomeView.vue(爷爷组件):

<template>
  <div class="home">
    <li v-for="folder in folders">
    <about-view :folder="folder"></about-view>
    </li>
  </div>
</template>
<script>
//引进父组件
import AboutView from './AboutView.vue';
export default {
  components:{
    AboutView,
  },
  data(){
    return{
       folders: [
          {
            name: 'folder1',
            children: [{
              name: 'folder1 - folder1',
              children: [{
                name: 'folder1 - folder1 - folder1'
              }]
            }, {
              name: 'folder1 - folder2',
              children: [{
                name: 'folder1 - folder2 - folder1'
              }, {
                name: 'folder1 - folder2 - folder2'
              }]
            }]
          },
          {
            name: 'folder 2',
            children: [{
              name: 'folder2 - folder1',
              children: [{
                name: 'folder2 - folder1 - folder1'
              }]
            }, {
              name: 'folder2 - folder2',
              children: [{
                name: 'folder2-content1'
              }]
            }]
          },
          {
            name: 'folder 3',
            children: [{
              name: 'folder3 - folder1',
              children: [{
                name: 'folder3 - folder1 - folder1'
              }]
            }, {
              name: 'folder3 - folder2',
              children: [{
                name: 'folder3-content1'
              }]
            }]
          }
        ],
    }
  },
}
</script>

AboutView.vue(父级组件):

<template>
 <div class="about">
<p>
<span>{{folder.name}}</span>
<second-view :children="folder.children"></second-view>
</p>
  </div>
</template>
<script>
export default{
  props:['folder'],
  components:{
    // HomeView
    SecondView:()=>import('./SecondView.vue')
  },
  data(){return{}},
}
</script>

 SecondView.vue(孙子组件):

<template>
<div>
        <ul>
            <li v-for="child in children">
            <about-view v-if="child.children" :folder="child"></about-view>
            <span v-else>{{child.name}}</span>
            </li>
        </ul>
</div>
</template>
<script>
// import AboutView from './AboutView.vue'
export default{
    props:['children'],
    components:{
        AboutView:()=>import ('./AboutView.vue')
    },
    data(){return{}},
}
</script>

写这个案例的时候出现了一个报错,是一个引入的逻辑错误,你需要找到一个循环支撑点,而又不能让他陷入无限循环,所以我让爷爷组件在全局注册,让子父组件异步引入,这样就可以解决报错问题,当然解决方法还有其他方式,例如在beaforecreate中引入,利用webpack等,欢迎相互讨论!

二,深层次的问题

 该文章是介绍对于多次使用的表单抽离成公共组件,围绕抽离的公共组件的一些技巧和方法;

包含公共组件在父组件的多次使用方法,父组件通过ref调用子组件的方法等;

这是最基础的组件通讯方案:

1,2,3是回顾子组件,父子间,非父子组件的传参;

4,5介绍的是子组件复用,父组件调用子组件的方法使用;

**1.父传子**

/父传子是自定义属性传值给子组件,子组件通过props接受传值,并渲染
//父页面
//<!-- 通过自定义属性传值给子组件 -->
<Child :msg='msg'></Child>
 return {
      msg:'父组件的值'
    }
//子页面
<p>父组件的值为:{{msg}}</p>
// 接受父组件传过来的值
      props:['msg'],

**2.子传父*

//子传父是自定义事件,通过$emit发送,父组件绑定自定义事件 //子组件  

<button @click="sentInfo">通过自定义事件将值发送给父组件</button>
 return {
      childInfo:'子组件的值'
    }
   methods: {
   sentInfo(){
      // 发送自定义事件
      // console.log(this)
      // this.$emit('自定义事件名',发送的值)
      this.$emit('sendV',this.childInfo)
    }
  },
  //父组件
   <!-- 监听子组件的自定义事件 -->
 Child @sendV='showInfo'></Child>
  return {
      msg:'',//等待子组件的值
    }
   methods:{
    // 监听的事件的函数的第一个参数就是传过来的值
    showInfo(v){
      console.log(v)// v只在{}内有效,父组件模板想要使用这个值,必须将值保存到自己的data中
      this.msg = v
    }
  }

**3.兄弟关系**

main.js中

//bus事件中心

Vue.prototype.$event = new Vue()

  //兄弟组件是先在main.js初始化页面自定义事件通过​emit发送,b页面$on监听,

one.vue:
<button @click="senMsg">发起自定义事件并携带参数</button>
 return {
      msg:"one组件的值"
    },
 methods:{
    senMsg(){
      this.$event.$emit('sendmsgInfo',this.msg)
    }
  }
  //two.vue 监听自定义事件,并接受
  mounted() {
    // 进入页面就开始监听one的自定义事件
    // this.$event.$on('监听的自定义事件名'函数(函数的第一个参数就是传过来的值))
   this.$event.$on('sendmsgInfo',(v)=>{
    console.log(v)//one组件的值
  })
  },

 4.子组件复用

//这是需要复用的结构,需要抽离成公共组件
<template>
    <div class=".main_input">
        <el-select 
        v-model="name" 
        filterable 
        :filter-method="typeFiltersixone" 
        placeholder="请选择"
        @change="chooseCustom" 
        ref="multiSelectsixone" 
        clearable>
        <el-option 
        :value="treeDataValue" 
        style="height: auto">
            <el-tree 
            :data="uDeptOptions" 
            :props="defaultProps" 
            :expand-on-click-node="false"
            :filter-node-method="filterNode" 
            ref="treesixone" 
            default-expand-all
            @node-click="handleNodeClick" 
            node-key="deptId" />
            </el-option>
        </el-select>
    </div>
</template>

需求是需要复用表单查询,写一个组件复用人员查询模块;

这是正常的子父组件信息通讯,子组件通过事件$emit传递name和id,父组件传值watch监听变化;

//父组件传值监听  
 props:{
    wzryName:{
       required: false
    },
    wzryId:{
       required: false
    },
  },
  watch:{
    wzryName:{
       handler(newValue, oldValue){
         this.name = newValue
       }
    },
     wzryId:{
       handler(newValue, oldValue){
         this.ids = newValue
       }
    }
  },

复用的方案是使用同一个子组件,父组件使用时,用单独的方法!

//这就是复用的结构,
//staff-queryitem是复用组件,复用两次,不同的是@returninput的方法不一样
        <el-col :span="5">
			<el-fORM-item label="派发人姓名" prop="pfryxm">
				<staff-queryitem @returninput="inputData"></staff-queryitem>
                        //第一个组件时inpuData方法
			</el-form-item>
		</el-col>
			<el-col :span="5">
				<el-form-item label="监督人姓名" prop="jdryxm">
					<staff-queryitem @returninputtwo="inputDatatwo"></staff-queryitem>
                     //第二个组件时inputDatatwo方法
				</el-form-item>
			</el-col>

单独传参

//子传父
    //两次复用对应两各不同的方法,分别传参
			inputData(name,id){
					this.queryParams.pfryxm=name
					this.queryParams.pfryId=id
			},
			inputDatatwo(name,id){
					this.queryParams.jdryxm=name
					this.queryParams.jdryId=id
			},

5.父组件通过ref调用子组件的方法

案例一:父组件调用子组件的方法,对父组件的数据进行处理

//以转换字符串方法为例:
//子组件的方法
methods:{
        //在子组件中写好一个反转字符串的方法,
        changetext(value){
            return value.split('').reverse().join("");
        }
    },
//父组件
<template>
  <div class="home">
    <p>{{list}}</p>
    <One ref="once"></One>
    <button @click="reverse">转换子组件</button>
  </div>
</template>
//引入子组件
import One from '../components/One.vue';
export default {
 components:{
    One,
  },
    data(){
        return{
            list:'hellow'
        }
    },
    methods:{
            通过ref调用子组件写好的changetext方法
        reverse(){
            console.log(this.$refs.once)//返回的是一个vue对象,所以可以直接调用其方法
            this.list= this.$refs.once.changetext(this.list)
    },
    },
}
</script>

此方法可以用来解决子组件复用时,需要对表单进行联动时使用;避免子父组件的反复传参;

案例二:父组件调用组件一的方法,调用组件二的数据进行处理

//还是以反转字符串为例
//组件一:
  methods:{
     //组件一提供方法
        changetext(value){
            return value.split('').reverse().join("");
        }
    },
//组件二:
<template>
  <div class="home">
      <p>{{list}}</p>
      <button @click="twos">发送数据</button>
  </div>
</template>
<script>
export default {
  data(){
      return{
          list:'总是在梦里 我看到你无助的双眼'
      }
  },
  methods:{
//组件二点击发送this.list数据给父组件
      twos(){
          this.$emit('sendV',this.list)
      },
  },
}
</script>
//父组件
<template>
  <div class="home">
    <p>{{info}}</p>
    <One ref="once"></One>
    <Two @sendV="Towsinfo"></Two>
    <button @click="reverse">转换子组件</button>
  </div>
</template>
<script>
import One from '../components/One.vue'
import Two from '../components/Two.vue'
export default {
  components:{
    One,
    Two
  },
  data(){
    return{
      info:''
    }
  },
  methods:{
    reverse(){
     this.info= this.$refs.once.changetext(this.info)
    },
    Towsinfo(v){
          console.log(v); //组件二发送的数据
          this.info=v    //需要有一个变量接收
    }
  },
}
</script>
 

通过这两个案例发现vue通过ref操作dom带来的好处是很明显的,便捷灵活的实现方案需求

到此这篇关于详细解读VUE父子组件的使用的文章就介绍到这了,更多相关VUE父子组件内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详细解读VUE父子组件的使用

本文链接: https://lsjlt.com/news/213708.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详细解读VUE父子组件的使用
    目录1.递归组件2.组件之间的循环使用二,深层次的问题**1.父传子****2.子传父***3.兄弟关系** 4.子组件复用5.父组件通过ref调用子组件的方法我们对父子组...
    99+
    2023-05-19
    VUE 组件 VUE父子组件
  • Vue子组件与父组件详细解析
    目录一、父组件和子组件二、模板分离写法1、template标签2、text/x-template三、父子组件通信-父传子1、Prop 类型四、父子组件通信子传父1、vm.$emit(...
    99+
    2024-04-02
  • Vue组件通信之父传子与子传父详细讲解
    目录父组件传递给子组件浅谈Props子组件传递给父组件父组件传递给子组件 父组件传递给子组件:通过props属性;子组件传递给父组件:通过$emit触发事件; 这里我们知道,父组件...
    99+
    2022-11-13
    Vue组件通信 Vue组件通信父传子 Vue组件通信子传父
  • Vue组件中的父子组件使用
    目录Vue组件中的父子组件父组件向子组件传值子组件向父组件传值Vue父子组件的生命周期总结Vue组件中的父子组件 父组件向子组件传值 父组件通过属性绑定(v-bind:)的形式, 把...
    99+
    2023-01-28
    Vue组件 Vue父子组件 Vue父子组件使用
  • Vue父子组件通信全面详细介绍
    目录1.Vue父子组件通信方式2.不同文件间的通信方式1 .父组件vue文件和子组件vue文件2 .父组件jsx文件和子组件vue文件3 .父组件vue文件和子组件jsx文件4 .父...
    99+
    2022-11-13
    vue的父子组件通信 vue父子组件通信例子
  • Vue子组件调用父组件方法案例详解
    一、直接在子组件中通过this.$parent.event来调用父组件的方法 <!-- 父组件 --> <template> <div> ...
    99+
    2024-04-02
  • vue父子组件slot插槽的使用
    目录vue父子组件slot插槽1.创建一个子组件并在vue实例中注册2.在HTML代码中使用子组件3.在vue实例中写入想要插入到子组件的内容4.在子组件的模板中通过一个slot标签...
    99+
    2022-11-13
    vue父子组件 vue slot插槽 插槽slot
  • Vue中的父子组件通讯以及使用sync同步父子组件数据
    目录前言子组件向父组件中传递数据一. 通过props从父向子组件传递函数,调用函数改变父组件数据二. 通过自定义事件从子组件向父组件中传递数据三. 通过ref属性在父组件中直接取得子...
    99+
    2024-04-02
  • vue弹窗父子组件调用问题示例详解
    目录一、vue弹窗 父子组件 emit 传图片二、vue父组件调用子组件里的不同方法一、vue弹窗 父子组件 emit 传图片 1、:modal-append-to-body=&qu...
    99+
    2024-04-02
  • vue子组件如何使用父组件传过来的值
    目录子组件使用父组件传过来的值父组件子组件vue子组件调用父组件数据子组件使用父组件传过来的值 父组件 <alarmstatistics :roless.sync="role"...
    99+
    2024-04-02
  • vue子组件怎么使用父组件传过来的值
    本篇内容主要讲解“vue子组件怎么使用父组件传过来的值”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue子组件怎么使用父组件传过来的值”吧!子组件使用父组件传过来的值父组件<alarms...
    99+
    2023-06-29
  • Vue中一个组件调用其他组件的方法详解(非父子组件)
    目录前言方式一:引用式方式二:vuex1、src/store/index.js2、被使用组件- A 页面(组件)3、使用触发页面-B 页面(组件)方式三:使用事件总线eventBus...
    99+
    2022-11-13
    vue调用其他组件方法 vue组件调用 vue组件之间调用
  • Vue中子组件向父组件传值$emit、.sync的案例详解
    目录父组件子组件案例父组件子组件v-model首先我们可先了解一个父组件向子组件传值的一个案例:将父组件请求的后端数据传值给子组件props 因为通过属性传值是单向的,有时候我们需要...
    99+
    2024-04-02
  • 详解Angular父子组件通讯
    目录概述一、输入输出属性概述二、输入属性三、属性绑定是单向的,从父组件到子组件四、输出属性1、先模拟一个实时变动的IBM的股票价格2、把信息输出出去,告诉组件外部,谁感兴趣谁来订阅3...
    99+
    2024-04-02
  • angular父子组件通信详解
    目录用到的api简单的例子person.ts父组件子组件效果总结用到的api Input - 子组件中定义可接受的属性,可以用来父组件给子组件传递数据 Output - 子组件中定义...
    99+
    2024-04-02
  • vue3 父子组件传值详解
    现在距离vue3的诞生已经过了很长时间了,笔者也是近期才开始学习vue3。对比vue2来看,vue3在写法发生了不小的变化,最典型的例子就是vue3通过ref,或者reactive实...
    99+
    2024-04-02
  • Vue非父子组件之间的通信方式详解
    目录非父子组件的通信1.Provide和Inject1.1基本使用1.2处理响应式数据(了解)2.全局事件总线总结非父子组件的通信 此篇讲解的是, 在学习状态管理之前, 非父子间通信...
    99+
    2024-04-02
  • 关于vue父组件调用子组件的方法
    组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功...
    99+
    2024-04-02
  • Vue父组件调用子组件函数实现
    Vue父组件调用子组件的函数 父组件通过事件调用子组件的函数。例如父组件通过 点击事件 让子组件发请求。 文章中的项目已经通过脚手架去创建。 DEMO: Father.js ...
    99+
    2024-04-02
  • Vue怎么用父组件向子组件通信
    本文小编为大家详细介绍“Vue怎么用父组件向子组件通信”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue怎么用父组件向子组件通信”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。props组件实例的作用域是孤立的...
    99+
    2023-07-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作