Chào mừng độc giả đến với Cafedev, nơi chúng tôi không chỉ chia sẻ kiến thức mà còn là nơi để cùng nhau khám phá các công nghệ mới. Trong bài viết này, chúng ta sẽ đào sâu vào chủ đề Vuejs với Thuộc Tính Fallthrough. Điều này không chỉ là một khía cạnh thú vị của Vuejs mà còn là một điểm mạnh để hiểu rõ hơn về cách các thành phần Vuejs tương tác với các thuộc tính truyền vào. Hãy cùng nhau khám phá và tận hưởng sự tiện ích của Vuejs với Thuộc Tính Fallthrough trên Cafedev!

Trang này giả định rằng bạn đã đọc qua Cơ Bản về Các Thành Phần. Hãy đọc trước nếu bạn mới bắt đầu với các thành phần.

1. Kế Thừa Thuộc Tính

Một “thuộc tính fallthrough” là một thuộc tính hoặc lắng nghe sự kiện v-on được truyền vào một thành phần, nhưng không được khai báo một cách rõ ràng trong props hoặc emits của thành phần nhận. Các ví dụ phổ biến bao gồm các thuộc tính class, style, và id.
Khi một thành phần render một phần tử gốc duy nhất, các thuộc tính fallthrough 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 một thành phần có mẫu như sau:

<!-- template of <MyButton> -->
<button>click me</button>

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

<MyButton class="large" />

DOM được render cuối cùng sẽ là:

<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 như là một thuộc tính fallthrough và tự động được thêm vào phần tử gốc của <MyButton>.

1.1 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 hiện có, nó sẽ được gộp với các giá trị classstyle được kế thừa từ phần tử cha. Giả sử chúng ta thay đổi mẫu của <MyButton> trong ví dụ trước thành:

<!-- template of <MyButton> -->
<button class="btn">click me</button>

Khi đó, DOM được render cuối cùng sẽ trở thành:

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

1.2 Kế Thừa Lắng Nghe v-on

Cùng một quy tắc cũng áp dụng cho các lắng nghe sự kiện v-on:

<MyButton @click="onClick" />

Bộ lắng nghe click sẽ được thêm vào phần tử gốc của <MyButton>, tức là phần tử nguyên thủy <button>. Khi phần tử nguyên thủy <button> đượ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ử nguyên thủy <button> đã có một bộ lắng nghe click được ràng buộc với v-on, thì cả hai bộ lắng nghe đều sẽ được kích hoạt.

1.3 Kế Thừa Thành Phần Lồng Ghép

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 cấu trúc <MyButton> để render một <BaseButton> làm gốc:

<!-- template of <MyButton/> that simply renders another component -->
<BaseButton />

Sau đó, các thuộc tính fallthrough nhận được bởi <MyButton> sẽ tự động được chuyển tiếp đến <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 v-on lắng nghe sự kiện của các sự kiện được khai báo bởi <MyButton> – nói cách khác, các props và lắng nghe sự kiện đã đượ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 được khai báo bởi nó.

2. Vô Hiệu Hóa 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.

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

Kịch bản phổ biến để vô hiệu hóa 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 đầy đủ vị trí mà các thuộc tính fallthrough nên được áp dụng.
Các thuộc tính fallthrough này có thể được truy cập trực tiếp trong biểu thức mẫu như $attrs:

<span>Fallthrough attributes: {{ $attrs }}</span>

Đối tượng $attrs bao gồm tất cả các thuộc tính không được khai báo bởi các tùy chọn props hoặc emits của thành phần (ví dụ: class, style, lắng nghe v-on, v.v.).
Một số lưu ý:

  • Khác với props, các thuộc tính fallthrough giữ nguyên kiểu chữ cái gốc của chúng trong JavaScript, vì vậy một thuộc tính như foo-bar cần được truy cập như $attrs['foo-bar'].
  • Một lắng nghe sự kiện v-on như @click sẽ được tiết lộ trên đối tượng như một hàm dưới $attrs.onClick.

Sử dụng ví dụ về thành phần <MyButton> từ phần trước – đôi khi chúng ta có thể cần bọc phần tử thực sự <button> bằng một <div> bổ sung cho mục đích làm đẹp:

<div class="btn-wrapper">
  <button class="btn">Click Me</button>
</div>

Chúng tôi muốn tất cả các thuộc tính fallthrough như lớp và bộ lắng 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: false và v-bind=”$attrs”:

<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 như các thuộc tính của phần tử mục tiêu.

3. Kế Thừa Thuộc Tính trên Nhiều Nút Gốc

Không giống như các thành phần với một nút gốc, các thành phần có nhiều nút gốc không có hành vi kế thừa thuộc tính tự động. Nếu $attrs không được ràng buộc một cách rõ ràng, một cảnh báo thời gian chạy sẽ được phát ra.

<CustomLayout id="custom-layout" @click="changeValue" />

Nếu <CustomLayout> có mẫu đa-nút gốc sau đây, sẽ có một cảnh báo vì Vue không thể chắc chắn nơi áp dụng các thuộc tính fallthrough:

<header>...</header>
<main>...</main>
<footer>...</footer>

Cảnh báo sẽ được làm im lặng nếu $attrs được ràng buộc một cách rõ ràng:


<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>

4. Truy Cập Thuộc Tính Fallthrough trong JavaScript

Nếu cần, bạn có thể truy cập các thuộc tính fallthrough của một thành phần trong <script setup> bằng cách sử dụng API useAttrs().

<script setup>
import { useAttrs } from 'vue'

const attrs = useAttrs()
</script>

Nếu không sử dụng <script setup>, attrs sẽ được tiết lộ như một thuộc tính của ngữ cảnh setup().

export default {
  setup(props, ctx) {
    // fallthrough attributes are exposed as ctx.attrs
    console.log(ctx.attrs)
  }
}

Lưu ý rằng mặc dù đối tượng attrs ở đây luôn phản ánh các thuộc tính fallthrough mới nhất, nhưng nó không phản ứng (vì lý do hiệu suất). Bạn không thể sử dụng watchers để quan sát các thay đổi của nó. Nếu cần tính phản ứng, hãy sử dụng một prop. Hoặc, bạn có thể sử dụng onUpdated() để thực hiện các hiệu ứng phụ với attrs mới nhất trên mỗi cập nhật.
Nếu cần, bạn có thể truy cập các thuộc tính fallthrough của một thành phần thông qua thuộc tính instance $attrs:

Chúng tôi hy vọng rằng bạn đã tìm thấy bài viết về Vuejs với Thuộc Tính Fallthrough trên Cafedev hữu ích và thú vị. Vuejs không ngừng mang lại những tính năng mạnh mẽ và linh hoạt cho việc phát triển ứng dụng web, và việc hiểu rõ về thuộc tính fallthrough sẽ giúp bạn tận dụng tối đa sức mạnh của nó. Hãy tiếp tục theo dõi Cafedev để cập nhật thông tin và kiến thức mới nhất về Vuejs và các công nghệ khác. Cảm ơn bạn đã đồng hành cùng Cafedev!

Các nguồn kiến thức MIỄN PHÍ VÔ GIÁ từ cafedev tại đây

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của CafeDev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!