vue3 基础-non-props 特性

本篇探讨当父组件通过属性给子组件传数据时, 子组件如果不通过 props 属性进行接收, 那数据会挂载到哪里, 以及子组件如何能使用这些数据.

正常的父子组件传值

<!DOCTYPE html>
<html lang="en">

<head>
  <title>正常-父子组件传值</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      // 1. 父组件通过 msg 属性给子组件传递一个 "hello, youge" 的数据
      template: `
      <div>
        <Son msg="hello, youge" />
      </div>
      `
    })

    app.component('Son', {
      // 2. 正常逻辑就是子组件通过 props 进行接收
      props: ['msg'],
      template: `<div>son</div>`
    })
    
    const vm = app.mount('#root')

  </script>
</body>

</html>

现在, 如果子组件 Son 不写 props 属性的话, 则这个数据会自动挂载的子组件 Son 的最外层 dom 上如下:

<div msg="hello, youge">son</div>

当然, 子组件也可选择就不接收父组件数据, 则在子组件中设置 inheritAttrs: false 即可.

 app.component('Son', {
      inheritAttrs: false,
      template: `<div>son</div>`
    })

non-props 应用

当父组件要给子组件传递一个样式的时候, 就可直接自动应用到子组件最外层 dom 啦.

<!DOCTYPE html>
<html lang="en">

<head>
  <title>nop-props 传样式过去</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      template: `
      <div>
        <Son style="color: orange;" />
      </div>
      `
    })

    app.component('Son', {
      template: `<div>son</div>`
    })
    
    const vm = app.mount('#root')

  </script>
</body>

</html>

则可看到父组件传递的样式在子组件上就直接生效了, 这还是有使用场景的. 但当我们的子组件最外层有多个 dom 节点时, 则可通过 v-bind="$attrs" 的来指定作用于谁.

app.component('Son', {
      template: `
      <div>son</div>
      <div v-bind="$attrs">son</div>
      <div>son</div>
      `
    })

这就表明样式的这个 nop-props 就作用于上图第二个节点了.

$attrs 就是用来存储父子局传过来的所有属性, 则就可以按需使用了.

<!DOCTYPE html>
<html lang="en">

<head>
  <title>传多值 $attrs</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      template: `
      <div>
        <Son style="color: orange;" />
      </div>
      `
    })

    app.component('Son', {
      template: `
      <div>son</div>
      <div v-bind="$attrs">son</div>
      <div>son</div>
      `
    })
    
    const vm = app.mount('#root')

  </script>
</body>

</html>

当然更多的应用配置是, 我能自己去通过 $attrs 对父组件传过来的多数据进行自己随意应用.

<!DOCTYPE html>
<html lang="en">

<head>
  <title>传多值 $attrs</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      template: `
      <div>
        <Son msg="hello" msg1="youge" />
      </div>
      `
    })

    app.component('Son', {
      template: `
      <div :msg="$attrs.msg">{{$attrs.msg}}</div>
      <div>啥都不接收</div>
      <div :cj="$attrs.msg1">{{$attrs.msg1}}</div>
      `
    })
    
    const vm = app.mount('#root')

  </script>
</body>

</html>

对于这些 nop-props 的属性数据, 则子组件可通过 v-bind="$ attrs.xxx" 进行应用即可. 同时它也是可以直接在其他地方用的, 比如生命周期函数:

<script>
    const app = Vue.createApp({
      template: `
      <div>
        <Son msg="hello" msg1="youge" />
      </div>
      `
    })

    app.component('Son', {
      mounted () {
        console.log(this.$attrs.msg)
      },
      template: '<div>son</div>'

    })
</script>

小结

  • 父子组件传值常规操作是父组件通过属性传数据给子组件, 子组件通过 props 进行接收
  • non-props 即当子组件不通过 props 接收父组件传的数据时, 其都会存在 $attrs 这个属性中
  • 子组件可通过 v-bind=$attrs.xxx 的方式对 non-props 的数据进行应用
  • 在很多地方如生命周期函数都是可以直接访问 $attrs 的数据, 即 this.s.attrs.xxx
posted @ 2022-09-06 23:33  致于数据科学家的小陈  阅读(108)  评论(0编辑  收藏  举报