Vue父子组件元素获取方法互相调用示例详解

 更新时间:2023年09月22日 14:38:35   作者:SHQ5785  
这篇文章主要为大家介绍了Vue父子组件元素获取方法互相调用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

一、前言

Vue项目开发过程中,有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者子组件访问根组件。梳理出如下请求方法:

  • 父组件访问子组件:$children 或者 $refs;
  • 子组件访问父组件:$parent;
  • 子组件访问根组件(通过 new Vue 创建的根 Vue 实例):$root;

二、父组件访问子组件

2.1 使用 $children

在父组件中使用 this.$children 拿到的是一个数组类型,它包含所有子组件实例。

<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <button @click="btnClick">按钮</button>
</div>
<template id="cpn">
  <div>
    <h1>我是子组件</h1>
  </div>
</template>
<script>
  let vm = new Vue({
    el: "#app",
    data: {},
    methods: {
      btnClick() {
        //1.拿到所有子组件,是一个数组
        console.log(this.$children);
        //2.拿到一个组件实例,可以直接访问子组件中的方法和 data 中的数据
        this.$children[0].showMessage();
        console.log(this.$children[0].name);
      }
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            name: 'webchang'
          }
        },
        methods: {
          showMessage() {
            console.log('我是子组件');
          }
        }
      }
    }
  });
</script>

2.2 使用 $refs

使用$children 的缺陷如下:

通过 $children 访问子组件时,是一个数组类型,访问其中的子组件必须通过索引值。

但是当子组件过多,我们需要拿到其中一个时,往往不能确定它的索引值,甚至还可能会发生变化。

有时候,我们想明确获取其中一个特定的组件,这个时候就可以使用 $refs

2.3 $refs 的使用

通过设置子组件的ref,父组件通过this.$refs.xxx.method_name(data)调用子组件方法,data参数可选。

$refs 和 ref 指令通常是一起使用的。

首先,我们在子组件上添加一个 ref 属性,相当于给某一个子组件绑定一个特定的ID

其次,this.$refs 拿到的是所有标有 ref 属性的子组件(如果一个子组件实例没有 ref 属性,通过这种方式是拿不到的),最后拿到的是一个对象,属性名是子组件实例的 ref 属性,属性值是该组件实例。

通过 this.$refs.ID 就可以访问到该组件。

示例代码如下:

<div id="app">
  <cpn ref="child1"></cpn>
  <cpn ref="child2"></cpn>
  <!-- 这个子组件实例没有 ref 属性,通过 this.$refs 方式拿不到这个组件实例 -->
  <cpn></cpn>
  <button @click="btnClick">按钮</button>
</div>
<template id="cpn">
  <div>
    <h1>我是子组件</h1>
  </div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  let vm = new Vue({
    el: "#app",
    data: {
      message: "hello"
    },
    methods: {
      btnClick() {
        console.log(this.$refs)
        console.log(this.$refs.child1)
        console.log(this.$refs.child1.name)
        this.$refs.child1.showMessage('父组件')
      }
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            name: 'webchang'
          }
        },
        methods: {
          showMessage(value) {
            console.log("子组件方法被调用,调用者:" + value)
          }
        }
      }
    }
  });
</script>

三、子组件调用父组件方法

3.1 方法一:this.$parent.event

直接在子组件中通过this.$parent.event来调用父组件的方法。示例代码如下:

父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
  import child from './components/dam/child';
  export default {
    components: {
      child
    },
    methods: {
      fatherMethod(value) {
        console.log("父组件方法被调用,调用者:" + value)
      }
    }
  };
</script>

子组件

<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
    methods: {
      childMethod() {
        this.$parent.fatherMethod('子组件');
      }
    }
  };
</script>

注意事项

  • 尽管在Vue开发中,我们允许通过 $parent 来访问父组件,但是在真实开发中尽量不要这样做。
  • 子组件应该尽量避免直接访问父组件的数据,因为这样代码耦合度太高了。
  • 如果我们将子组件放在另外一个组件之内,很可能该父组件没有对应的属性,往往会引起问题。
  • 另外,通过 $parent 直接修改父组件的状态,那么父组件中的状态将变得飘忽不定,很不利于调试和维护。

3.2 方法二: $emit

在子组件里用$emit向父组件触发一个事件,父组件监听这个事件。

父组件

<template>
  <div>
    <child @fatherMethod="fatherMethod"></child>
  </div>
</template>
<script>
  import child from '~/components/dam/child';
  export default {
    components: {
      child
    },
    methods: {
      fatherMethod() {
        console.log('测试');
      }
    }
  };
</script>

子组件

<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
    methods: {
      childMethod() {
        this.$emit('fatherMethod');
      }
    }
  };
</script>

3.3 方法三:方法传参

父组件把方法传入子组件中,在子组件里直接调用这个方法。

父组件

<template>
  <div>
    <child :fatherMethod="fatherMethod"></child>
  </div>
</template>
<script>
  import child from '~/components/dam/child';
  export default {
    components: {
      child
    },
    methods: {
      fatherMethod() {
        console.log('测试');
      }
    }
  };
</script>

子组件

<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
    props: {
      fatherMethod: {
        type: Function,
        default: null
      }
    },
    methods: {
      childMethod() {
        if (this.fatherMethod) {
          this.fatherMethod();
        }
      }
    }
  };
</script>

子组件 更简便的写法

<template>
  <div>
    <button @click="fatherMethod()">点击</button>
  </div>
</template>
<script>
  export default {
    props: {
      fatherMethod: {
        type: Function,
        default: null
      }
    },
    methods: {
    }
  };
</script>

四、其他调用方法

由于最终所有组件都会渲染成真实的Dom元素,所以可以通过jsjquery,获取Dom元素对象,通过模拟点击的方式触发元素绑定的方法,通过本地CookielocalStoragesessionStorage做参数缓存,实现值传递。

此方法不限于父子组件,只要组件位于同一页面都可使用,但因为不符合vue规范,并非特殊情况不建议使用。

组件A:

<template>
  <div>    
    <h1>我是组件A</h1>
    <button id='btn' @click='methodA()'>点我</button>
  </div>
</template>
<script>
  export default {
    methods: {
      methodA() {     
      	var parameter= localStorage.getItem('parameter'); 
        console.log('我是组件A方法');
      }
    }
  };
</script>

组件B:

<template>
  <div>    
    <h1>我是组件B</h1>
    <button @click='methodB(data)'>点我</button>
  </div>
</template>
<script>
  export default {
    methods: {
      methodB(data) {
      localStorage.setItem('parameter',data); 
        $('#btn').click();//模拟按钮点击
        console.log('模拟点击按钮,触发A组件方法');
      }
    }
  };
</script>

拓展阅读

http://shouce.jb51.net/vue/

以上就是Vue 父子组件元素获取、方法互相调用的详细内容,更多关于Vue父子组件元素获取方法互调的资料请关注脚本之家其它相关文章!

相关文章

  • Vue无法读取HTMLCollection列表的length问题解决

    Vue无法读取HTMLCollection列表的length问题解决

    这篇文章主要介绍了Vue无法读取HTMLCollection列表的length问题解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • 解决报错ValidationError: Progress Plugin Invalid Options问题

    解决报错ValidationError: Progress Plugin Invalid&

    这篇文章主要介绍了解决报错ValidationError: Progress Plugin Invalid Options问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • vue cli安装使用less的教程详解

    vue cli安装使用less的教程详解

    这篇文章主要介绍了vue-cli安装使用less的教程,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • vue-json-editor json编辑器的使用

    vue-json-editor json编辑器的使用

    本文主要介绍了vue-json-editor json编辑器的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • vue和iview实现Scroll 数据无限滚动功能

    vue和iview实现Scroll 数据无限滚动功能

    今天小编就为大家分享一篇vue和iview实现Scroll 数据无限滚动功能,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-10-10
  • vue单页面改造多页面应用的全过程记录

    vue单页面改造多页面应用的全过程记录

    众所都知vue是一个单页面应用,下面这篇文章主要给大家介绍了关于vue单页面改造多页面应用的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • vue中通过使用$attrs实现组件之间的数据传递功能

    vue中通过使用$attrs实现组件之间的数据传递功能

    组件之间传递数据的方式有很多种,之所以有这么多种方式,是为了满足在不同场景不同条件下的使用。这篇文章主要介绍了vue中通过使用$attrs实现组件之间的数据传递,需要的朋友可以参考下
    2019-09-09
  • 浅谈Vue的加载顺序探讨

    浅谈Vue的加载顺序探讨

    本篇文章主要介绍了Vue的加载顺序探讨,详细的介绍了加载顺序以及如何判断所有的子组件加载完成。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • vue+elementUi 实现密码显示/隐藏+小图标变化功能

    vue+elementUi 实现密码显示/隐藏+小图标变化功能

    这篇文章主要介绍了vue+elementUi 实现密码显示/隐藏+小图标变化功能,需本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • vue router 动态路由清除方式

    vue router 动态路由清除方式

    这篇文章主要介绍了vue router 动态路由清除方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05

最新评论