Skip to content

Fallthrough Attributes

Kế thừa Thuộc tính

"Một thuộc tính chuyển tiếp" là một thuộc tính hoặc trình nghe sự kiện v-on được chuyển đến một thành phần, nhưng không được khai báo rõ ràng trong props hoặc emits của thành phần nhận. Ví dụ phổ biến bao gồm các thuộc tính như class, styleid.

Khi một thành phần render một phần tử gốc duy nhất, các thuộc tính chuyển tiếp sẽ tự động được thêm vào các thuộc tính của phần tử gốc. Ví dụ, với thành phần <MyButton> có mẫu sau:

template
<!-- Mẫu của <MyButton> -->
<button>click me</button>

Và một thành phần cha sử dụng thành phần này với:

template
<MyButton class="large" />

DOM cuối cùng được hiển thị sẽ là:

html
<button class="large">click me</button>

Ở đây, <MyButton> không khai báo class như một prop được chấp nhận. Do đó, class được xem xét như là một thuộc tính chuyển tiếp và tự động được thêm vào phần tử gốc của <MyButton>.

Gộp classstyle

Nếu phần tử gốc của thành phần con đã có các thuộc tính class hoặc style, chúng sẽ được gộp với các giá trị classstyle được kế thừa từ phần cha. Giả sử chúng ta thay đổi mẫu của <MyButton> trong ví dụ trước thành:

template
<!-- Mẫu của <MyButton> -->
<button class="btn">click me</button>

Kết quả DOM cuối cùng sẽ trở thành:

html
<button class="btn large">click me</button>

Kế thừa Trình nghe Sự kiện v-on

Quy tắc tương tự áp dụng cho trình nghe sự kiện v-on:

template
<MyButton @click="onClick" />

Trình nghe click sẽ được thêm vào phần tử gốc của <MyButton>, tức là phần tử <button> nguyên thủy. Khi phần tử <button> nguyên thủy được nhấp, nó sẽ kích hoạt phương thức onClick của thành phần cha. Nếu phần tử <button> nguyên thủy đã có một trình nghe click được kết nối với v-on, cả hai trình nghe sẽ đều được kích hoạt.

Kế thừa Từ Thành phần Lồng nhau

Nếu một thành phần render một thành phần khác làm nút gốc của nó, ví dụ, chúng ta tối ưu lại <MyButton> để hiển thị một <BaseButton> làm nút gốc:

template
<!-- Mẫu của <MyButton/> chỉ đơn giản là hiển thị một thành phần khác -->
<BaseButton />

Sau đó, các thuộc tính chuyển tiếp được nhận bởi <MyButton> sẽ tự động được chuyển tiếp cho <BaseButton>.

Lưu ý rằng:

  1. Các thuộc tính được chuyển tiếp không bao gồm bất kỳ thuộc tính nào được khai báo làm props, hoặc trình nghe v-on của các sự kiện được khai báo bởi <MyButton> - nói cách khác, các props và trình nghe đã được "tiêu thụ" bởi <MyButton>.

  2. Các thuộc tính được chuyển tiếp có thể được chấp nhận làm props bởi <BaseButton>, nếu nó được khai báo.

Tắt Kế thừa Thuộc tính

Nếu bạn không muốn một thành phần tự động kế thừa các thuộc tính, bạn có thể đặt inheritAttrs: false trong các tùy chọn của thành phần.

Từ phiên bản 3.3, bạn cũng có thể sử dụng defineOptions trực tiếp trong <script setup>:

vue
<script setup>
defineOptions({
  inheritAttrs: false
})
// ...logic setup
</script>

Tình huống phổ biến để tắt kế thừa thuộc

tính là khi các thuộc tính cần được áp dụng cho các phần tử khác ngoài nút gốc. Bằng cách đặt tùy chọn inheritAttrs thành false, bạn có thể kiểm soát hoàn toàn nơi các thuộc tính chuyển tiếp nên được áp dụng.

Các thuộc tính chuyển tiếp này có thể được truy cập trực tiếp trong biểu thức mẫu dưới dạng $attrs:

template
<span>Thuộc tính chuyển tiếp: {{ $attrs }}</span>

Đối tượng $attrs bao gồm tất cả các thuộc tính không được khai báo trong props hoặc emits của thành phần (ví dụ, class, style, trình nghe v-on, vv.).

Một số lưu ý:

  • Khác với props, các thuộc tính chuyển tiếp giữ nguyên chữ in của chúng trong JavaScript, nên một thuộc tính như foo-bar cần phải được truy cập như $attrs['foo-bar'].

  • Một trình nghe sự kiện v-on như @click sẽ được hiển thị trên đối tượng dưới dạng một hàm trong $attrs.onClick.

Sử dụng ví dụ của chúng ta với thành phần <MyButton> từ phần trước - đôi khi chúng ta có thể cần bọc phần tử <button> thực sự bằng một <div> phụ trợ cho mục đích trang trí:

template
<div class="btn-wrapper">
  <button class="btn">click me</button>
</div>

Chúng ta muốn tất cả các thuộc tính chuyển tiếp như class và trình nghe v-on được áp dụng cho phần tử <button> bên trong, không phải là phần tử <div> bên ngoài. Chúng ta có thể đạt được điều này với inheritAttrs: falsev-bind="$attrs":

template
<div class="btn-wrapper">
  <button class="btn" v-bind="$attrs">click me</button>
</div>

Hãy nhớ rằng v-bind mà không có đối số sẽ ràng buộc tất cả các thuộc tính của một đối tượng làm thuộc tính của phần tử đích.

Fallthrough Attributes has loaded