• vue中$attrs和$listeners以及inheritAttrs的用法


    官方文档说明:

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

    意思就是父组件往子组件传没有在props里声明过的值时,子组件可以通过$attrs接受,且只包含父组件没有在props里声明的值。

    父组件

    <template>
      <div class="home">
        <child gender="male" age="18"/>
      </div>
    </template>
    
    <script>
    import Child from '../components/Child'
    
    export default {
      name: 'home',
      components: {
        Child,
      }
    </script>
    

    子组件

    <template>
      <div>
         -----------------Child------------------
         <br>
         <span>gender: {{$attrs['gender']}}</span>
         <br>
         <span>age: {{$attrs['age']}}</span>
         <br>
      </div>
    </template>
    
    <script>
    export default {
        name: 'Child'
    }
    </script>
    
    <style>
    
    </style>
    

    结果图:


    二、解释当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

    意思就是: $attrs 可以收集父组件中的所有传过来的属性除了那些在组件中没有通过 props 定义的。引申说明一下,如果组件的嵌套层级有点深但又不那么深,比如三层。我们如果使用props的话,最里面的组件想要获取最外层组件的数据,就要通过中间的组件的props来传递,但是这个props对于中间的这个组件没啥用处,它就是做了一个桥梁而已。我们平时写代码时候其实经常碰到。这种场景,写起来有时候觉得挺烦的。所以就有了这个$attrs来帮助我们,不必在中间组件中写props就可以让最里面的组件拿到最外面组件传进来的数据。

    爷组件

    <template>
      <div class="home">
        <img alt="Vue logo" src="../assets/logo.png">
        <father :child2Data="`${child2Data}`"/>
      </div>
    </template>
    
    <script>
    import Father from '../components/Father'
    
    export default {
      name: 'home',
      components: {
        Father
      },
      data() {
        return {
          child2Data: '我是爷爷组件数据'
        }
      }
    }
    </script>
    

    父组件

    <template>
      <div>
          *********************father********************
          <child2 v-bind="$attrs"/>
      </div>
    </template>
    
    <script>
    import Child2 from '../components/Child2';
    export default {
        name: 'Father',
        components: {
            Child2
        }
    }
    </script>
    
    <style>
    
    </style>
    

    子组件

    <template>
    <div>
        ====================Child2==================
        <br>
        <span>{{child2Data}}</span>
    </div>
    </template>
    
    <script>
    export default {
        name: 'Child2',
        props: {
            child2Data: String
        }
    }
    </script>
    
    <style>
    
    </style>
    

    结果图

    1、

    2、

    3、


    官方文档:

    解释:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。

    如下例子: 父组件的click事件包含了其父亲组件(即爷组件)的作用域

    爷组件

    <template>
      <div class="home">
        <img alt="Vue logo" src="../assets/logo.png">
        <father @click="handleBtnClick"/>     // 注意此处为click事件
      </div>
    </template>
    
    <script>
    import Father from '../components/Father'
    
    export default {
      name: 'home',
      components: {
        Father
      },
      data() {
        return {
          child2Data: '我是爷爷组件数据'
        }
      },
      methods: {
        handleBtnClick() {
                alert(this.child2Data)
            }
      }
    }
    </script>
    

    父组件

    <template>
      <div>
          *********************father********************
          <button v-on="$listeners">父组件</button>
      </div>
    </template>
    
    <script>
    import Child2 from '../components/Child2';
    export default {
        name: 'Father',
        components: {
            Child2
        }
    }
    </script>
    
    <style>
    
    </style>
    

    解释:它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

    如下例子:

    爷组件

    <template>
      <div class="home">
        <img alt="Vue logo" src="../assets/logo.png">
        <br>
        <father :child2Data="`${child2Data}`" @handle="handleBtnClick"/>    // 自定义一个handle点击指令
      </div>
    </template>
    
    <script>
    import Father from '../components/Father'
    
    export default {
      name: 'home',
      components: {
        Father
      },
      data() {
        return {
          child2Data: '我是爷爷组件数据'
        }
      },
      methods: {
        handleBtnClick() {
                alert(this.child2Data)
            }
      }
    }
    </script>
    

    父组件

    <template>
      <div>
          *********************father********************
          <child2 v-bind="$attrs" v-on="$listeners" />   //父组件通过v-on="$listeners"中转点击事件传给子组件
      </div>
    </template>
    
    <script>
    import Child2 from '../components/Child2';
    export default {
        name: 'Father',
        components: {
            Child2
        }
    }
    </script>
    
    <style>
    
    </style>
    

    子组件

    <template>
    <div>
        ====================Child2==================
        <br>
        <span>{{child2Data}}</span>
        <br>
        <button @click="handleBtnClick">点击</button>
    </div>
    </template>
    
    <script>
    export default {
         inheritAttrs:false,
        name: 'Child2',
        props: {
            child2Data: String
        },
        methods: {
            handleBtnClick() {
                this.$emit('handle')   // 子组件即可访问爷组件的作用域
            }
        }
    }
    </script>
    
    <style>
    
    </style>
    

    结果图:

    inheritAttrs

    其他用法学习博客:https://www.jianshu.com/p/4649d317adfe
    参考博客:https://blog.csdn.net/m0_37115637/article/details/88779799

    今天你学习了吗!!!
  • 相关阅读:
    无题
    赌对了
    赌:
    这次是真的再见了,oi退役回忆录
    线段树(lazy标记)
    《挑战》2.1 POJ POJ 1979 Red and Black (简单的DFS)
    《挑战》2.1 POJ 2386 Lake Counting (简单的dfs)
    TC安装全系列教程
    ProblemC 剪花布条(KMP基础)
    多校+CF简单题
  • 原文地址:https://www.cnblogs.com/nayek/p/12052796.html
Copyright © 2020-2023  润新知