1. 程式人生 > 其它 >vue $attrs的使用(元件父傳孫的方法)

vue $attrs的使用(元件父傳孫的方法)

$attrs的使用 vue

  • $attrs是在vue的2.40版本以上新增的。
  • 專案中有多層元件傳參可以使用$attrs,可以使程式碼更加美觀,更加簡潔,維護程式碼的時候更方便。如果使用普通的父子元件傳參prop和$emit,$on會很繁瑣;如果使用vuex會大材小用,只是在這幾個元件中使用,沒必要使用vuex;使用事件匯流排eventBus,使用不恰當的話,有可能會出現事件多次執行。

  • 如果給元件傳遞的資料,元件不使用props接收,那麼這些資料將作為元件的HTML元素的特性,這些特性繫結在元件的HTML根元素上
  • inheritAttrs: false的含義是不希望本元件的根元素繼承父元件的attribute,同時父元件傳過來的屬性(沒有被子元件的props接收的屬性),也不會顯示在子元件的dom元素上,但是在元件裡可以通過其$attrs可以獲取到沒有使用的註冊屬性, ``inheritAttrs: false`是不會影響 style 和 class 的繫結
  • 以下是$attrs的使用示例(父元件的列表行資料傳遞給孫子元件展示)
  1. 父元件(Father.vue),給子元件關聯資料,子元件如果不用props接收,那麼這些資料就作為普通的HTML特性應用在子元件的根元素上
<template>
  <div>
    <el-table :data='list'>
      <el-table-column
        prop="name"
        label="姓名"
      ></el-table-column>
      <el-table-column
        prop="study"
        label="學習科目"
      ></el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button @click='transmitClick(scope.row)'>傳遞</el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <!-- 兒子元件 -->
    <ChildView
      :is-show="isOpen"
      :row="row"
    >
    </ChildView>
  </div>
</template>

<script>
import ChildView from './Child.vue'
export default {
  components: { ChildView },
  data() {
    return {
      isOpen: false,
      row: {},
      list: [
        { name: '王麗', study: 'Java' },
        { name: '李克', study: 'Python' }
      ]
    }
  },
  methods: {
    // 傳遞事件
    transmitClick(row) {
      this.isOpen = true;
      this.row = row
    }
  }
}
</script>
  1. 兒子元件(Child.vue),中間層,作為父元件和孫子元件的傳遞中介,在兒子元件中給孫子元件新增v-bind="$attrs",這樣孫子元件才能接收到資料
<template>
  <div class='child-view'>
    <p>兒子元件</p>
    <GrandChild v-bind="$attrs"></GrandChild>
  </div>
</template>

<script>
import GrandChild from './GrandChild.vue'
export default {
  // 繼承所有父元件的內容
  inheritAttrs: true,
  components: { GrandChild },
  data() {
    return {
    }
  }
}
</script>

<style lang="stylus">
.child-view {
  margin: 20px
  border: 2px solid red
  padding: 20px
}
</style>
  1. 孫子元件(GrandChild.vue),在孫子元件中一定要使用props接收從父元件傳遞過來的資料
<template>
  <div class='grand-child-view'>
    <p>孫子元件</p>
    <p>傳給孫子元件的資料:{{row.name}} {{row.name !== undefined? '學習' : ''}} {{row.study}}</p>
  </div>
</template>

<script>
export default {
  // 不想繼承所有父元件的內容,同時也不在元件根元素dom上顯示屬性
  inheritAttrs: false,
  // 在本元件中需要接收從父元件傳遞過來的資料,注意props裡的引數名稱不能改變,必須和父元件傳遞過來的是一樣的
  props: {
    isShow: {
      type: Boolean,
      dedault: false
    },
    row: {
      type: Object,
      dedault: () => { }
    }
  }
}
</script>

<style lang="stylus">
.grand-child-view {
  border: 2px solid green
  padding: 20px
  margin: 20px
}
</style>

結果:

在上面提過,如果給子元件傳遞的資料,子元件不使用props接收,那麼這些資料將作為子元件的特性,這些特性繫結在元件的HTML根元素上,在vue2.40版本之後,可以通過inheritAttrs = false 來控制這些特性是否顯示在dom元素上 如:案例中父元件給子元件傳遞的row和isShow,子元件沒有使用props接收,這個2個數據直接作為HTML的特殊屬性。子元件使用inheritAttrs = true,那麼特性顯示在dom上,如果設定為false,那麼特性不顯示在dom上