Câu hỏi tràn ngăn xếp này là kết quả số 1 cho truy vấn Google "chỉ thị vue so với thành phần". Câu trả lời của Saurshaz hiện đang được chấp nhận và nó rất sai trong Vue 2.0. Tôi tưởng tượng điều này đang dẫn đầu rất nhiều người lạc lối vì vậy tôi sẽ cân nhắc ở đây.
Câu trả lời cho “Tôi nên sử dụng chỉ thị hoặc thành phần trong Vue” gần như luôn là một thành phần.
Bạn có muốn sử dụng lại HTML không? I E. vật dụng tái sử dụng? Sau đó sử dụng một thành phần. Bạn có muốn hai trong số các tiện ích này có dữ liệu rời rạc không? Sau đó sử dụng một thành phần. Dữ liệu của một người sẽ KHÔNG ghi đè dữ liệu của người khác. Có lẽ đó là sự thật trong Vue 1.0, tôi không biết. Nhưng nó hoàn toàn không đúng trong Vue 2.0. Trong Vue 2.0, các thành phần của bạn có hàm data
trả về một tập dữ liệu duy nhất. Xem xét việc này thực tế cuộc sống của một dropdown Vue có một đoạn mã HTML tương tự như menu thả xuống UI Bootstrap:
<template>
<span class="dropdown sm-dropdown" @click="toggle" :class="{'open': isOpen}">
<a class="dropdown-toggle">
<span class="special-field">{{ label }}</span>
</a>
<ul class="dropdown-menu">
<li v-for="choice in choices">
<a @click.prevent="click(choice)">{{ choice.label }}</a>
</li>
</ul>
</span>
</template>
<script>
export default {
name: 'Dropdown',
props: ['label', 'options', 'onChange'],
data() {
return {
choices: this.options,
isOpen: false
}
},
methods: {
click(option) {
this.onChange(option);
},
toggle() {
this.isOpen = !this.isOpen;
}
}
}
</script>
Bây giờ trong một thành phần phụ huynh, tôi có thể làm một cái gì đó như thế này:
<template>
<div class="container">
<dropdown
:label="-- Select --"
:options="ratingChoices"
:onChange="toggleChoice"
>
</dropdown>
<dropdown
:label="-- Select --"
:options="ratingChoices"
:onChange="toggleChoice"
>
</dropdown>
</div>
</template>
<script>
import Dropdown from '../dropdown/dropdown.component.vue';
export default {
name: 'main-directive',
components: { Dropdown },
methods: {
toggleChoice(newChoice) {
// Save this state to a store, e.g. Vuex
}
},
computed: {
ratingChoices() {
return [{
value: true,
label: 'Yes'
}, {
value: false,
label: 'No'
}]
}
}
}
</script>
Có một số lượng mã phong nha ở đây. Điều đang xảy ra là chúng tôi đang thiết lập một thành phần cha và bên trong thành phần cha mẹ đó, chúng tôi có hai trình đơn thả xuống. Nói cách khác, thành phần thả xuống được gọi hai lần. Điểm tôi đang cố gắng thực hiện trong việc hiển thị mã này là: khi bạn nhấp vào menu thả xuống, isOpen
cho rằng dropdown
thay đổi cho chỉ thị đó và chỉ thị đó. Nhấp vào một trong các menu thả xuống không ảnh hưởng đến menu thả xuống khác theo bất kỳ cách nào.
Không chọn giữa các thành phần hoặc chỉ thị dựa trên việc bạn có muốn dữ liệu rời rạc hay không. Các thành phần cho phép dữ liệu rời rạc.
Vì vậy, khi nào bạn muốn chọn một chỉ thị trong Vue?
Dưới đây là một số nguyên tắc hy vọng sẽ giúp bạn suy nghĩ đúng hướng.
- Bạn muốn chọn chỉ thị khi muốn mở rộng chức năng của các thành phần HTML và bạn nghi ngờ rằng kết quả là. Để hiểu ý tôi là gì, hãy xem các chỉ thị mà Vue đưa ra khỏi hộp. Lấy ví dụ
v-for
của nó. Nó cho phép bạn lặp qua một bộ sưu tập. Điều đó rất hữu ích và bạn cần có khả năng làm điều đó trong bất kỳ thành phần nào bạn muốn, và bạn không muốn DOM có được sâu hơn. Đó là một ví dụ điển hình khi một chỉ thị là lựa chọn tốt hơn. [1]
- Bạn muốn chọn chỉ thị khi bạn muốn một thẻ HTML duy nhất có chức năng nhiều. Ví dụ, một phần tử vừa kích hoạt một yêu cầu Ajax và có một chú giải công cụ tùy chỉnh. Giả sử bạn muốn chú giải công cụ trên các phần tử không phải là các yếu tố kích hoạt Ajax, bạn nên chia chúng ra thành hai thứ khác nhau. Trong ví dụ này, tôi sẽ làm cho chú giải công cụ một chỉ thị và tính năng Ajax được thúc đẩy bởi một thành phần để tôi có thể tận dụng chỉ thị tích hợp trong
@click
có sẵn trong các thành phần.
Một chú thích cho tò mò hơn. Trong lý thuyết v-for
có thể được tạo thành thành phần, nhưng làm như vậy sẽ yêu cầu DOM sâu sắc hơn mức cần thiết mỗi khi bạn muốn sử dụng v-for
cũng như cú pháp khó xử hơn. Nếu Vue đã chọn để thực hiện một phần ra khỏi nó, thay vì điều này:
<a v-for="link in links" :href="link.href">link.anchor</a>
Cú pháp sẽ phải đã này:
<v-for items="link in links">
<a :href="link.href">link.anchor</a>
</v-for>
Không chỉ là vụng về này, nhưng kể từ khi thành phần mã sẽ cần thiết để thực hiện cú pháp <slot></slot>
để nhận được innerHTML và vì các vị trí không thể là con ngay lập tức của khai báo <template>
(vì không có đảm bảo rằng đánh dấu vị trí có một nút mục nhập ở cấp cao nhất), điều này có nghĩa là sẽ phải là một yếu tố cấp cao nhất xung quanh trong định nghĩa thành phần cho v-for
. Do đó DOM sẽ nhận được sâu hơn cần thiết. Chỉ thị rõ ràng là sự lựa chọn đúng ở đây.