详解Vue中$props、$attrs和$listeners的使用方法

目录
  • 背景
  • 一、文档描述
  • 二、具体使用
  • 三、总结

背景

现在我们来讨论一种情况,父组件与孙子组件怎么通信,我们有多少种解决方案?

  • 我们使用VueX来进行数据管理,但是如果项目中多个组件共享状态比较少,项目比较小,并且全局状态比较少,那使用VueX来实现该功能,并没有发挥出VueX的威力。
  • 使用B来做中转站,当A组件需要把信息传给C组件时,B接受A组件的信息,然后利用属性传给C组件, 这是一种解决方案,但是如果嵌套的组件过多,会导致代码繁琐,代码维护比较困难;如果C中状态的改变需要传递给A, 使用事件系统一级级往上传递 。
  • 自定义一个Vue 中央数据总线,这个情况适合碰到组件跨级传递消息,但是缺点是 碰到多人合作时,代码的维护性较低,代码可读性低

一、文档描述

(1)$props:当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问。

(2)$attrs:包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。

(3)$listeners:包含了父作用域中(不含 .native 修饰器的)v-on事件监听器。他可以通过 v-on="listeners"传入内部组件

二、具体使用

1、父组件

<template>
  <div>
    <div>父亲组件</div>
    <Child
      :foo="foo"
      :zoo="zoo"
      @handle="handleFun"
    >
    </Child>
  </div>
</template>

<script>
import Child from './Child.vue'
export default {
  components: { Child },
  data() {
    return {
      foo: 'foo',
      zoo: 'zoo'
    }
  },
  methods: {
    // 传递事件
    handleFun(value) {
      this.zoo = value
      console.log('孙子组件发生了点击事件,我收到了')
    }
  }
}
</script>

2. 儿子组件(Child.vue)

中间层,作为父组件和孙子组件的传递中介,在儿子组件中给孙子组件添加v-bind="$attrs",这样孙子组件才能接收到数据。

$attrs是从父组件传过来的,且儿子组件未通过props接收的数据,例如zoo

<template>
  <div class='child-view'>
    <p>儿子组件--{{$props.foo}}与{{foo}}内容一样</p>
    <GrandChild v-bind="$attrs" v-on="$listeners"></GrandChild>
  </div>
</template>

<script>
import GrandChild from './GrandChild.vue'
export default {
  // 继承所有父组件的内容
  inheritAttrs: true,
  components: { GrandChild },
  props: ['foo'],
  data() {
    return {
    }
  }
}
</script>

3. 孙子组件(GrandChild.vue)

在孙子组件中一定要使用props接收从父组件传递过来的数据

<template>
  <div class='grand-child-view'>
    <p>孙子组件</p>
    <p>传给孙子组件的数据:{{zoo}}</p>
    <button @click="testFun">点我触发事件</button>
  </div>
</template>

<script>
export default {
  // 不想继承所有父组件的内容,同时也不在组件根元素dom上显示属性
  inheritAttrs: false,
  // 在本组件中需要接收从父组件传递过来的数据,注意props里的参数名称不能改变,必须和父组件传递过来的是一样的
  props: ['zoo'],
  methods: {
    testFun() {
      this.$emit('handle', '123')
    }
  }
}
</script>

三、总结

从上面的代码,可以看出使用attrsinheritAttrs属性 能够使用简洁的代码,将A组件的数据传递给C组件,该场景的使用范围还是挺广的。

通过listeners,我们在b组件上 绑定 v-on=”$listeners”, 在a组件中,监听c组件触发的事件。就能把c组件发出的数据,传递给a组件。

到此这篇关于详解Vue中$props、$attrs和$listeners的使用方法的文章就介绍到这了,更多相关Vue $props、$attrs和$listeners内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue 父子组件数据传递的四种方式( inheritAttrs + $attrs + $listeners)

    当我们在书写 vue 组件的时候,也许可能会用到数据传递:将父组件的数据传递给子组件,有时候也需要通过子组件去事件去触发父组件的事件: 每当我们遇到这样的需求的时候,我们总是会想到有三种解决办法: 通过 props 的方式向子组件传递(父子组件) vuex 进行状态管理(父子组件和非父子组件) vuex 非父子组件的通信传递 Vue Event Bus ,使用Vue的实例,实现事件的监听和发布,实现组件之间的传递. 后来再逛社区的时候我又发现了还有第四种传递方式, inheritAttrs +

  • Vue2.4+新增属性.sync、$attrs、$listeners的具体使用

    sync 在vue2.4以前,父组件向子组件传值用props:子组件不能直接更改父组件传入的值,需要通过$emit触发自定义事件,通知父组件改变后的值.比较繁琐,写法如下: //父组件 <template> <div class="parent"> <p>父组件传入子组件的值:{{name}}</p> <fieldset> <legend>子组件</legend> <child :val=&quo

  • Vue v2.4中新增的$attrs及$listeners属性使用教程

    前言 多级组件嵌套需要传递数据时,通常使用的方法是通过vuex.如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点杀鸡用牛刀.Vue 2.4 版本提供了另一种方法,使用 v-bind="$attrs", 将父组件中不被认为 props特性绑定的属性传入子组件中,通常配合 interitAttrs 选项一起使用.之所以要提到这两个属性,是因为两者的出现使得组件之间跨组件的通信在不依赖 vuex 和事件总线的情况下变得简洁,业务清晰. 首先分析以下应用场景: A 组件与 B

  • Vue封装组件利器之$attrs、$listeners的使用

    目录 前言 $attrs 例子: $listeners (官网解释) 使用场景 总结 前言 多级组件嵌套需要传递数据时,通常使用的方法是通过vuex.但仅仅是传递数据,不做中间处理,使用 vuex 处理,未免有些大材小用了.所以就有了 $attrs . $listeners两个属性 ,通常配合 inheritAttrs 一起使用. $attrs 从父组件传给自定义子组件的属性,如果没有 prop 接收会自动设置到子组件内部的最外层标签上,如果是 class 和 style 的话,会合并最外层标签

  • Vue为什么要谨慎使用$attrs与$listeners

    前言 在 Vue 开发过程中,如遇到祖先组件需要传值到孙子组件时,需要在儿子组件接收 props ,然后再传递给孙子组件,通过使用 v-bind="$attrs" 则会带来极大的便利,但同时也会有一些隐患在其中. 隐患 先来看一个例子: 父组件: { template: ` <div> <input type="text" v-model="input" placeholder="please input"&

  • Vue组件通信$attrs、$listeners实现原理解析

    前言 vue通信手段有很多种,props/emit.vuex.event bus.provide/inject 等.还有一种通信方式,那就是$attrs和$listeners,之前早就听说这两个api,趁着有空来补补.这种方式挺优雅,使用起来也不赖.下面例子都会通过父.子.孙子,三者的关系来说明使用方式. $attrs 官方解释: 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class和style除外).当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定

  • Vue中$attrs与$listeners的使用教程

    目录 介绍 举例 总结  介绍 $attrs 继承所有的父组件属性(没有通过 props 接收的属性还有 class 类名 和 style 样式 ). inheritAttrs: 是否非 props 属性显示在标签最外层,默认值 true ,就是继承所有的父组件属性(除了 props 特定绑定外)作为普通的HTML特性应用在子组件的根元素上,如果你不希望组件的根元素继承特性就设置 inheritAttrs: false  ,但是 class 还是会继承. $listeners 它是一个对象,能接

  • vue $attrs和$listeners的使用与区别

    首先让我们看一下这张图,表示了一个多级关联的组件嵌套 为什么要用$attrs 和 $listeners 先让我们来想一种情况,就是组件A跟组件C怎么通信,我们可以有多少中解决方案? 看到这种情况,大多数人应该会想到用vuex来进行数据通信吧,但是如果项目中多个组件中的共享状态很少,且项目比较小,全局数据通信也很少,那我们用vuex来实现这个功能,就感觉有点杀鸡用牛刀了 我们可以使用组件B来做通信的中转站,当组件A需要把数据传到组件C时,组件A通过props将数据传给组件B,然后组件B再用prop

  • 详解vue项目中调用百度地图API使用方法

    步骤一:申请百度地图密钥: JavaScript API v1.4以及以前的版本无序申请秘钥(ak),自v1.5版本开始需要先申请秘钥(ak),才可以使用,如需获取更高的配额,需要申请  认证企业用户.百度地图API 链接地址:http://lbsyun.baidu.com/apiconsole/key 步骤二:在index.html中添加百度地图JavaScript API接口: <script src="http://api.map.baidu.com/api?v=1.4"

  • 详解vue中引入stylus及报错解决方法

    前提条件是已经有了vue项目,如果没有,请先建立,具体方法看这里https://cn.vuejs.org/v2/guide/installation.html 安装stylus 好了,建立好项目后我们来安装stylus npm install stylus stylus-loader --save-dev 这样就安装上了stylus. 接下来就可以使用了,使用方式分两种.一种是在.vue文件的style块中使用,一种是引用.styl文件的形式 在.vue文件的style块中使用 这个很简单,只要

  • 详解Vue.js v-for不支持IE9的解决方法

    最近一个小项目,在最后的测试阶段出现了问题,使用了Vue,在Chrome.Firefox.Safari.IE11下都可以访问,唯独IE9下无法正常显示,排除程序问题后,最终判断是Vue的锅,替换版本后解决.经过测试,2.16.2.17 在IE9下无法使用 v-for 导致的. 写了一个简单的demo,在IE9下无法显示列表,运行结果如下: 测试代码如下: <!DOCTYPE html> <html lang=zh-CN> <head> <meta charset=

  • 详解vue+nodejs获取多个表数据的方法

    目录 效果 前端实现 后端实现 总结 读取两个表的数据 将用户及图像联系在一起 效果 前端实现 修改关联的时候,前端向后端传入array[number],后端存为字符串 这时在前端获取数据时,需要循环处理为数字数组 <template> <div> <el-table :data="state.tableData" border style="width: 100%"> <el-table-column prop="

  • 详解Vue中$props、$attrs和$listeners的使用方法

    目录 背景 一.文档描述 二.具体使用 三.总结 背景 现在我们来讨论一种情况,父组件与孙子组件怎么通信,我们有多少种解决方案? 我们使用VueX来进行数据管理,但是如果项目中多个组件共享状态比较少,项目比较小,并且全局状态比较少,那使用VueX来实现该功能,并没有发挥出VueX的威力. 使用B来做中转站,当A组件需要把信息传给C组件时,B接受A组件的信息,然后利用属性传给C组件, 这是一种解决方案,但是如果嵌套的组件过多,会导致代码繁琐,代码维护比较困难;如果C中状态的改变需要传递给A, 使用

  • 详解vue组件之间相互传值的方式

    概述 我们都知道 Vue 作为一个轻量级的前端框架,其核心就是组件化开发.Vue 就是由一个一个的组件构成的,组件化是它的精髓,也是最强大的功能之一.而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用. 但在实际项目开发过程中,我们需要访问其他组件的数据,这样就就有了组件通信的问题.在 vue 中组件之间的关系有:父子,兄弟,隔代.针对不同的关系,怎么实现数据传递,就是接下来要讲的. 一.父组件向子组件传值 即父组件通过属性的方式向子组件传值,子组件通过 props 来接收

  • 详解vue高级特性

    Vue为我们提供了很多高级特性,学习和掌握它们有助于提高你的代码水平. 一.watch进阶 从我们刚开始学习Vue的时候,对于侦听属性,都是简单地如下面一般使用: watch:{ a(){ //doSomething } } 实际上,Vue对watch提供了很多进阶用法. handler函数 以对象和handler函数的方式来定义一个监听属性,handler就是处理监听变动时的函数: watch:{ a:{ handler:'doSomething' } }, methods:{ doSomet

  • 详解vue 组件的实现原理

    组件机制的设计,可以让开发者把一个复杂的应用分割成一个个功能独立组件,降低开发的难度的同时,也提供了极好的复用性和可维护性.本文我们一起从源码的角度,了解一下组件的底层实现原理. 组件注册时做了什么? 在Vue中使用组件,要做的第一步就是注册.Vue提供了全局注册和局部注册两种方式. 全局注册方式如下: Vue.component('my-component-name', { /* ... */ }) 局部注册方式如下: var ComponentA = { /* ... */ } new Vu

  • 详解vue 组件注册

    一.了解组件注册的两种方式 1.1 全局组件的注册方法 //main.js import Vue from 'vue' import App from './App' import router from './router' Vue.config.productionTip = false let Hello = { name: 'hello', template: '这是全局组件hello' } Vue.component('hello', Hello) new Vue({ el: '#ap

  • 详解vue 模版组件的三种用法

    本文介绍了详解vue 模版组件的三种用法,分享给大家,具体如下: 第一种 //首先,别忘了引入vue.js <div id="user_name_01"></div> <script src="../node_modules/vue/dist/vue.js"></script> <script> var User_01 = Vue.extend({// 创建可复用的构造器 template: '<p&

随机推荐