温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

vue3 $attrs和inheritAttrs怎么用

发布时间:2022-04-29 09:09:11 来源:亿速云 阅读:770 作者:iii 栏目:开发技术

今天小编给大家分享一下vue3 $attrs和inheritAttrs怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

    $attrs和inheritAttrs用法

    • $attrs属性解释:包含了父作用域中不作为组件 props 或自定义事件的 attribute 绑定和事件。当一个组件没有声明任何prop 时,这里会包含所有父作用域的绑定,并且可以通过 v-bind="$attrs" 传入内部组件——这在创建高阶的组件时会非常有用。

    • inheritAttrs属性解释:如果你不希望组件的根元素继承特性,你可以在组件的选项中设置 inheritAttrs: false

    可能不是很好理解,我们可以举个例子来验证一下。

    在父组件app.vue中

    <template>
      <div>
        <MyInput type="text" placeholder="输入用户名" v-model="state.text" />
        <MyInput type="password" placeholder="输入密码"  v-model="state.pass"  />
      </div>
    </template>
    <script setup>
    import MyInput from "@/components/myInput.vue";
    import { reactive } from "vue";
    const state = reactive({
      text: "",
      pass: "",
    });
    </script>

    子组件 myInput.vue 设置 inheritAttrs: true(默认)

    <template>
      <div class="input">
        <input v-bind="$attrs" v-model="modelValue" />
      </div>
    </template>
    <script>
    export default {
      props: {
        modelValue: [String, Number],
      },
    };
    </script>

    vue3 $attrs和inheritAttrs怎么用

    子组件 myInput.vue 设置 inheritAttrs: false

    <template>
      <div class="input">
        <input v-bind="$attrs" v-model="modelValue"/>
      </div>
    </template>
    <script>
    export default {
      inheritAttrs: false,
      props: {
        modelValue: [String, Number],
      },
    };
    </script>

    vue3 $attrs和inheritAttrs怎么用

    小结:

    由上述例子可以看出,子组件的props中未注册父组件传递过来的属性。

    • 当设置inheritAttrs:true时,子组件的顶层标签元素中会渲染出父组件传递过来的属性(例如:type="text"等)

    • 当设置inheritAttrs: false时,子组件的顶层标签元素中不会渲染出父组件传递过来的属性

    • 不管inheritAttrs为true或者false,子组件中都能通过$attrs属性获取到父组件中传递过来的属性。

    $attrs和inheritAttrs实例

    官网的文档简短而又不清晰,实在是看不懂,只好自己找代码验证来看看是什么意思:

    <!DOCTYPE html>
    <html lang="en">
     
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.1.5/vue.global.js"></script>
    </head>
     
    <body>
        <div id="app">
            <father :v1="'value1'" :v2="'value2'" :v3="'value3'"></father>
        </div>
    </body>
     
    </html>
    <script>
    const app = Vue.createApp({
        data() {
            return {}
        },
    })
    app.component('father', {
     // inheritAttrs: false,
        props: ['v1'],
        template: ` <div><p>v1 is {{v1}}</p>
    		  <son v-bind='$attrs' :some="1"></son>
    	       </div>`,
        created() {
            console.log('father:', this.$attrs)
        }
    })
    app.component('son', {
        // inheritAttrs: false,
        props: ['v2'],
        template: `<div><p>v2 is {{v2}}</p>
                         <grandSon v-bind='$attrs'></grandSon>
                  </div>`,
        created() {
            console.log('son:', this.$attrs)
        }
    })
    app.component('grandSon', {
        props: ['v3'],
        template: `<p>v3 is {{v3}}</p>`,
        created() {
            console.log('grandSon:', this.$attrs)
        }
    })
    app.mount('#app')
    </script>

    页面显示的结果:

    v1 is value1 

    v2 is value2 

    v3 is value3

    页面源代码:

    <div id="app" data-v-app="">
       <div v2="value2" v3="value3"> <!-- 这是father -->
          <p>v1 is value1</p>
          <div v3="value3" some="1">  <!-- 这是 son-->
              <p>v2 is value2</p>
               <p some="1">v3 is value3</p>  <!-- 这是 grandSon -->
          </div>
       </div>
    </div>

    控制台打印是当前组件的$attrs:

    father: Proxy {v2: "value2", v3: "value3", __vInternal: 1}

    son: Proxy {v3: "value3", some: 1, __vInternal: 1}

    grandSon: Proxy {some: 1, __vInternal: 1}

    首选,father组件被传入了3个值,但是实际使用props接收的只有v1,v2和v3作为attributes在DOM里面渲染了。

    vue3 $attrs和inheritAttrs怎么用

    上图的devtool 也可以说明,另外就是控制台也同时证明了。

    同样son组件只是接收v2作为prop:

    vue3 $attrs和inheritAttrs怎么用

    grandSon组件只是接收v3作为prop

    vue3 $attrs和inheritAttrs怎么用

    father prop:v1,attributes: v2,v3

    son prop:v2 ,attributes:v3,some

    grandSon prop:v3,,attributes: some

    发现无论是father传入的3个值v1,v2,v3还是son又传入的值':some=1',

    只要不被prop传入下一层组件,那么一定是在下一层组件的$attrs,也就是说不被作为prop的值会传入下一个组件作为attrs的一员。一个组件的attrs由父组件传递以及自己自带的组合而成。

    上面说的是$attrs,那么inheritAttrs则说的是attrs继承,这里的继承是控制DOM渲染,不继承也就是不渲染了,但是实际还是存在这个attrs的。

    `inheritAttrs`属性默认是true,所以能看到上面的结论,attrs会往下传,当设置为false的时候就不会在DOM渲染从上一层继承来的attrs。

    修改一下代码:

    app.component('father', {
       inheritAttrs: false,    // 不继承
        props: ['v1'],
        template: ` <div><p>v1 is {{v1}}</p>
    		  <son v-bind='$attrs' :some="1"></son>
    	       </div>`,
        created() {
            console.log('father:', this.$attrs)
        }
    })

    father组件这不继承attrs,控制台的打印没变:

    father: Proxy {v2: "value2", v3: "value3", __vInternal: 1}

    son: Proxy {v3: "value3", some: 1, __vInternal: 1}

    grandSon: Proxy {some: 1, __vInternal: 1}

    devtool这里依然可以看到attrs

    vue3 $attrs和inheritAttrs怎么用

    但是看源代码:

    <div id="app" data-v-app="">
      <div>                          <!-- 这里是 father --> <!-- 看这行 -->
        <p>v1 is value1</p>
        <div v3="value3" some="1">     <!-- 这里是 son-->
          <p>v2 is value2</p>
          <p some="1">v3 is value3</p>   <!-- 这里是 grandSon-->
          </div>
        </div>
    </div>

    DOM渲染里面的v2,v3 attrs都不存在了。

    以上就是“vue3 $attrs和inheritAttrs怎么用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注亿速云行业资讯频道。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI