美文网首页vuejs与angularjs
inheritAttrs、vm.$listeners 、vm.$

inheritAttrs、vm.$listeners 、vm.$

作者: 简单tao的简单 | 来源:发表于2019-07-28 12:27 被阅读0次

    inheritAttrs

    组件的根元素是否继承不被认作 props的特性,默认true

    //父组件
    <template>
       <div>
         <child-dom
          :foo="foo"
          :coo="coo"
         >
         </child-dom>
       </div>
    </template>
    <script>
       import childDom from "../components/Father2-Child";
       export default {
         data() {
            return {
              foo:"Hello, world",
              coo:"Hello,rui"
            }
         },
         components:{childDom},
       }
    </script>
    
    //子组件
    <template>
       <div>
          <p>foo:{{foo}}</p>
       </div>
    </template>
    <script>
    export default {
     name:'child-dom',
     props:["foo"],
    }
    </script>
    

    查看DOM结构,结构如下


    因为子组件中没有prop为coo这个属性,所以继承了父组件的特性,如果在子组件的props里接收coo则DOM中就不会有这个属性

    在2.4中新增选项inheritAttrs inheritAttrs的默认值为true, 将inheritAttrs的值设为false, 这些默认的行为会禁止掉。

    //子组件
    <template>
       <div>
          <p>foo:{{foo}}</p>
       </div>
    </template>
    <script>
    export default {
     name:'child-dom',
     props:["foo"],
     inheritAttrs:false,
    }
    </script>
    
    子组件加了inheritAttrs:false,就不会继承父组件的特性了

    但是通过实例属性vm.$attrs ,可以将这些特性生效,且可以通过v-bind 绑定到子组件的非根元素上。

    vm.$attrs

    //父组件
    <template>
       <div>
         <child-dom
          :foo="foo"
          :coo="coo"
         >
         </child-dom>
       </div>
    </template>
    <script>
       import childDom from "../components/Father2-Child";
       export default {
         data() {
            return {
              foo:"Hello, world",
              coo:"Hello,rui"
            }
         },
         components:{childDom},
       }
    </script>
    
    //子组件
    <template>
       <div>
          <p>foo:{{foo}}</p>
          <p>attrs:{{$attrs}}</p>
          <childDomChild v-bind="$attrs"></childDomChild>
       </div>
    </template>
    <script>
    import childDomChild from '../components/Father2-Child-Child';
    export default {
     name:'child-dom',
     props:["foo"],
     inheritAttrs:false,
     components:{childDomChild}
    }
    </script>
    
    //孙子组件
    <template>
      <div>
       <p>coo:{{coo}}</p>
      </div>
    </template>
    <script>
      export default {
        name:'childDomChild',
        props:["coo"],
        inheritAttrs:false
      }
    </script>
    
    输出结果:子组件和孙子组件通过$attrs获取到父组件的特性

    综上所述:可以通过$attrs属性将父组件的数据传递给子组件、孙子组件

    注意:
    $attrs仅包含了父作用域中不作为 prop 被识别的特性 (class 和 style 除外)

    那么问题来了,孙子组件的信息怎么同步给父组件呢?下面我们就来解决这个问题

    vm.$listeners

    vue2.4版本新增了$listeners属性,它是一个对象,里面包含了作用在这个组件上的所有监听器,有了这个$listeners属性,你就可以配合 v-on="$listeners"将所有的事件监听器指向这个组件的某个特定的子元素。

    我们在子组件上 绑定v-on=”$listeners”, 就可以在父组件中监听孙子组件触发的事件,就能把孙子组件发出的数据,传递给父组件。

    //父组件
    <template>
     <div>
        {{coo}}
       <child-dom
        :foo="foo"
        :coo="coo"
         @upRocket="reciveRocket">
       </child-dom>
     </div>
    </template>
    <script>
     import childDom from "../components/Father2-Child";
     export default {
       name:'demoNo',
       data() {
            return {
                foo:"Hello, world",
                coo:"Hello,rui"
            }
        },
        components:{childDom},
        methods:{
            reciveRocket(ev){
                this.coo = ev;//改变数据
                console.log(this.coo)
            }
        }
    }
    </script>
    
    //子组件
    <template>
        <div>
            <p>foo:{{foo}}</p>
            <p>attrs:{{$attrs}}</p>
            <childDomChild v-bind="$attrs" v-on="$listeners"></childDomChild>
        </div>
    </template>
    <script>
    import childDomChild from '../components/Father2-Child-Child';
    export default {
        name:'child-dom',
        props:["foo"],
        inheritAttrs:false,
        components:{childDomChild}
    }
    </script>
    
    //孙子组件
    <template> 
        <div>
        <p>coo:{{coo}}</p>
        <button @click="startUpRocket">我要发射火箭</button>
        </div>
    </template>
    <script>
     export default {
        name:'childDomChild',
        props:['coo'],
        methods:{
            startUpRocket(){
                this.$emit("upRocket",'简单我的简单');
            }      
        }
     }
    </script>
    
    输出结果
    点击“我要发射火箭”后的结果

    至此,孙子组件向父组件传递数据的问题也解决了

    综上所述:vm.$attrsvm.$listeners 可以解决“父组件”和“子组件”、“孙子组件”、“曾孙子组件”等后代组件的通讯问题

    • inheritAttrs

    默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrs 为 false,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例属性 $attrs 可以让这些特性生效,且可以通过 v-bind 显性的绑定到非根元素上。

    注意:这个选项不影响 class 和 style 绑定。

    • vm.$attrs

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

    • vm.$listeners

    包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners"传入内部组件——在创建更高层次的组件时非常有用。

    相关文章

      网友评论

        本文标题:inheritAttrs、vm.$listeners 、vm.$

        本文链接:https://www.haomeiwen.com/subject/paqyrctx.html