- Pelajari
-
Ekosistem
Pertolongan
Alat
Pustaka Inti
Berita
Daftar Sumber Daya
- Tim
- Dukung Vue
- Terjemahan
Style Guide
Ini adalah panduan resmi gaya menulis kode yang spesifik untuk Vue . Jika kamu menggunakan Vue pada sebuah proyek, ini adalah referensi yang bagus untuk menghindari error/kesalahan, menghabiskan waktu pada hal remeh, dan pola-pola yang buruk. Meskipun begitu, kami tidak menganggap panduan gaya(style-guide) dalam kode apapun selalu bisa sesuai dengan setiap tim atau proyek, maka penyelewengan yang hati-hati dianjurkan berdasarkan pengalaman, teknologi penunjang lain yang digunakan, dan nilai yang dijunjung.
Secara umum, kami menghindari saran tentang JavaScript atau HTML. Tidak masalah kamu menggunakan ;
atau ,
, apakah petik tunggal: ''
, atau ganda: ""
untuk nilai atribut. Meskipun beberapa pengecualian akan tetap ada, dimana kami dapati pola tertentu lebih membantu dalam konteks Vue.
Segera, kami juga akan menyediakan tips penunjang. Terkadang kamu perlu disiplin, tapi sebisa mungkin, kami tunjukan bagaimana menggunakan ESLint dan proses otomasi lainnya untuk mempermudah.
Terakhir, kami akan membagi aturannya ke 4 kategori:
Kategori Aturan
Prioritas A: Essential(Mendasar)
Aturan-aturan ini membantu mencegah kesalahan, jadi pelajari dan patuhi dengan cara apa pun. Pengecualian mungkin ada, tetapi harus sangat jarang dan hanya dilakukan oleh mereka yang memiliki pengetahuan mendalam tentang JavaScript dan Vue.
Prioritas B: Sangat Dianjurkan
Aturan-aturan ini didapati dapat meningkatkan keterbacaan(readability) dan / atau memudahkan developer di sebagian besar proyek. Kode akan tetap berjalan jika Kamu melanggarnya, tetapi pelanggaran harus jarang dan memiliki alasan yang dibenarkan.
Prioritas C: Disarankan
Dimana terdapat banyak opsi yang sama-sama baik, opsi manapun dapat diterima selama dipastikan konsisten. Dalam aturan ini, kami menjelaskan setiap opsi yang dapat diterima dan menyarankan pilihan default. Itu berarti kamu bebas untuk membuat pilihan yang berbeda dalam basis kode kamu sendiri, selama kamu konsisten dan memiliki alasan yang bagus. Harap punya alasan yang bagus ya! Dengan beradaptasi dengan standar komunitas, kamu akan:
- melatih otak kamu untuk lebih mudah menguraikan sebagian besar kode dari komunitas yang kamu temui
- dapat menyalin dan menempelkan(copy and paste) sebagian besar contoh kode dari komunitas tanpa modifikasi
- sering menemukan karyawan baru sudah terbiasa dengan gaya pengkodean pilihan kamu, setidaknya dalam hal Vue
Prioritas D: Gunakan dengan Hati-hati
Beberapa fitur Vue ada untuk mengakomodasi kasus yang langka atau migrasi yang lebih lancar dari basis kode lawas. Namun ketika digunakan secara berlebihan, mereka dapat membuat kode Kamu lebih sulit untuk dirawat(maintain) atau bahkan menjadi sumber bug. Aturan-aturan ini menerangkan fitur-fitur yang berpotensi berisiko, menjelaskan kapan dan mengapa mereka harus dihindari.
Aturan Prioritas A : Essential (Mencegah Error)
Nama komponen dengan lebih dari satu kata essential
Nama komponen harus selalu multi-kata, kecuali untuk komponen root App
.
Ini mencegah konflik dengan elemen HTML yang ada dan yang akan datang, karena semua elemen HTML adalah satu kata.
Komponen data essential
Komponen data
harus berupa fungsi(function).
Saat menggunakan properti data
pada komponen (contoh. Di mana saja kecuali pada new Vue
), nilai harus berupa fungsi yang mengembalikan objek.
Detailed Explanation
Ketika nilai data
adalah objek, itu dibagi di semua instance komponen. Bayangkan, misalnya, komponen TodoList
dengan data ini:
data: {
listTitle: '',
todos: []
}
Kita mungkin ingin menggunakan lagi komponen ini, untuk memungkinkan pengguna(user) mempertahankan beberapa daftar (contoh. Untuk belanja, daftar harapan(wishlists), tugas harian, dll). Tapi ada masalah. Karena setiap instance komponen merujuk ke objek data yang sama, mengubah judul satu daftar juga akan mengubah judul setiap daftar lainnya. Hal yang sama berlaku untuk menambahkan / mengedit / menghapus todo.
Sebagai gantinya, kita ingin setiap instance komponen hanya mengelola datanya sendiri. Agar itu terjadi, setiap instance harus menghasilkan objek data yang unik. Dalam JavaScript, ini dapat dilakukan dengan suatu fungsi yang mengembalikan(return) objek:
data: function () {
return {
listTitle: '',
todos: []
}
}
Bagus
Vue.component('some-comp', {
data: function () {
return {
foo: 'bar'
}
}
})
// In a .vue file
export default {
data () {
return {
foo: 'bar'
}
}
}
// Tidak masalah menggunakan objek langsung di
// _instance_ root Vue, karena hanya akan ada
// satu _instance_.
new Vue({
data: {
foo: 'bar'
}
})
Definisi prop essential
Definisi prop harus sedetail mungkin.
Dalam kode yang dikomit, definisi prop harus selalu sedetail mungkin, setidaknya menentukan jenis(type).
Detailed Explanation
definisi prop yang detail memiliki dua keuntungan:
- Mereka mendokumentasikan API dari komponen, sehingga mudah untuk melihat bagaimana komponen itu dimaksudkan untuk digunakan.
- Dalam pengembangan(development), Vue akan memperingatkan kamu jika suatu komponen menyediakan prop yang diformat salah, membantu kamu menangkap sumber kesalahan potensial.
Bagus
props: {
status: String
}
// Lebih bagus lagi!
props: {
status: {
type: String,
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
}
v-for
dengan key essential
Selalu gunakan v-for
dengan key
.
v-for
dengan key
selalu digandengkan pada komponen, untuk mempertahankan status internal komponen di bawah subtree. Bahkan untuk elemen, ini adalah praktik yang baik untuk mempertahankan perilaku yang dapat diprediksi, seperti konstanta objek dalam animasi.
Detailed Explanation
Katakanlah kamu memiliki daftar todos:
data: function () {
return {
todos: [
{
id: 1,
text: 'Learn to use v-for'
},
{
id: 2,
text: 'Learn to use key'
}
]
}
}
Kemudian kamu mengurutkannya berdasarkan abjad. Saat memperbarui DOM, Vue akan mengoptimalkan rendering untuk melakukan mutasi DOM se-efisien mungkin. Itu mungkin berarti menghapus elemen todo pertama, lalu menambahkannya lagi di akhir daftar.
Masalahnya adalah, ada kasus di mana penting untuk tidak menghapus elemen yang akan tetap ada di DOM. Misalnya, kamu mungkin ingin menggunakan <transition-group>
untuk animasi penyortiran daftar, atau mempertahankan fokus jika elemen yang diberikan adalah <input>
. Dalam kasus ini, menambahkan kunci unik untuk setiap item (contoh. :key="todo.id"
) akan memberi tahu Vue bagaimana berperilaku lebih dapat diprediksi.
Dalam pengalaman kami, lebih baik untuk selalu menambahkan kunci unik, sehingga kamu dan tim kamu tidak perlu khawatir tentang kasus kecil ini. Kemudian dalam skenario langka, performa-kritis di mana konstansi objek tidak diperlukan, kamu dapat membuat pengecualian secara sadar.
Hindari v-if
dengan v-for
essential
Jangan pernah gunakan v-if
dan v-for
pada satu elemen yang sama.
Ada dua kasus umum di mana ini bisa menggoda:
Untuk memfilter item dalam daftar (contoh.
v-for="user in users" v-if="user.isActive"
). Dalam kasus ini, gantiusers
dengan properti baru yang mengembalikan daftar yang telah difilter (contoh.activeUsers
).Untuk menghindari render daftar jika harus disembunyikan (contoh.
v-for="user in users" v-if="shouldShowUsers"
). Dalam kasus ini, pindahkanv-if
kedalam wadah elemen lain (contoh.ul
,ol
).
Detailed Explanation
Ketika Vue memproses direktif, v-for
memiliki prioritas lebih daripada v-if
, maka templat ini:
<ul>
<li
v-for="user in users"
v-if="user.isActive"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
Akan dievaluasi serupa dengan:
this.users.map(function (user) {
if (user.isActive) {
return user.name
}
})
Jadi, bahkan jika kita hanya membuat elemen untuk sebagian kecil pengguna, kita harus mengiterasi seluruh daftar setiap kali kita merender ulang, apakah set pengguna aktif telah berubah atau tidak.
Alih-alih dengan mengiterasi properti yang telah dikomputasi, seperti ini:
computed: {
activeUsers: function () {
return this.users.filter(function (user) {
return user.isActive
})
}
}
<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
Kita mendapatkan keuntungan berikut:
- Daftar yang difilter akan dievaluasi kembali hanya jika ada perubahan yang relevan pada array
users
, membuat penyaringan/filter jauh lebih efisien. - Menggunakan
v-for="user in activeUsers"
, kita hanya mengiterasi pengguna aktif(activeUsers
) selama render, menjadikan rendering jauh lebih efisien. - Logika sekarang dipisahkan dari lapisan presentasi, membuat pemeliharaan (perubahan / perluasan logika) jauh lebih mudah.
Kita mendapatkan manfaat serupa dari memperbarui:
<ul>
<li
v-for="user in users"
v-if="shouldShowUsers"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
ke:
<ul v-if="shouldShowUsers">
<li
v-for="user in users"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
Dengan memindahkan v-if
ke elemen wadah lain, kita tidak melakukan pengecekan shouldShowUsers
untuk setiap pengguna dalam daftar. Alih-alih, kita mengecek sekali and tidak mengevaluasi v-for
jika shouldShowUsers
bernilai false.
Buruk
<ul>
<li
v-for="user in users"
v-if="user.isActive"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
<ul>
<li
v-for="user in users"
v-if="shouldShowUsers"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
Bagus
<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
<ul v-if="shouldShowUsers">
<li
v-for="user in users"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
Lingkup komponen gaya(style) essential
Untuk aplikasi, gaya dalam komponen tingkat atas App
dan komponen tata letak(layout) mungkin bersifat global, tetapi semua komponen lainnya harus selalu dilingkup(scoped).
Untuk single-file components. tidak harus menggunakan scoped
atribut. membuat lingkupan bisa melalui CSS modules, strategi berbasis kelas seperti BEM, atau pustaka(library/convention) lainnya.
Catatan, Pustaka komponen, harus lebih memilih strategi berbasis kelas daripada menggunakan atribut scoped
.
Ini akan memudahkan untuk mengesampingkan(overriding) gaya internal, dengan nama kelas yang dapat dibaca manusia , tidak terlalu spesifik, tetapi cukup untuk menghindari konflik.
Detailed Explanation
Jika kamu mengembangkan proyek besar, bekerja dengan pengembang lain, atau terkadang menyertakan HTML / CSS pihak ketiga (contoh. Dari Auth0), pelingkupan yang konsisten akan memastikan bahwa gaya kamu hanya berlaku untuk komponen yang dimaksudkan untuknya.
Di luar atribut scoped
, menggunakan nama kelas unik dapat membantu memastikan bahwa CSS pihak ketiga tidak berlaku untuk HTML milikmu. Misalnya, banyak proyek menggunakan nama kelas button
,btn
, atau icon
, jadi walaupun tidak menggunakan strategi seperti BEM, menambahkan awalan unik-aplikasi dan / atau komponen-spesifik (contoh.ButtonClose-icon
) dapat memberikan perlindungan.
Buruk
<template>
<button class="btn btn-close">X</button>
</template>
<style>
.btn-close {
background-color: red;
}
</style>
Bagus
<template>
<button class="button button-close">X</button>
</template>
<!-- menggunakan `scoped` atribut -->
<style scoped>
.button {
border: none;
border-radius: 2px;
}
.button-close {
background-color: red;
}
</style>
<template>
<button :class="[$style.button, $style.buttonClose]">X</button>
</template>
<!-- menggunakan CSS modules -->
<style module>
.button {
border: none;
border-radius: 2px;
}
.buttonClose {
background-color: red;
}
</style>
<template>
<button class="c-Button c-Button--close">X</button>
</template>
<!-- menggunakan konvensi BEM -->
<style>
.c-Button {
border: none;
border-radius: 2px;
}
.c-Button--close {
background-color: red;
}
</style>
Nama properti pribadi essential
Selalu gunakan awalan $_
properti pribadi khusus dalam plugin, mixin, dll. Kemudian untuk menghindari konflik dengan kode oleh penulis lain, sertakan juga lingkup bernama(name scoped) (contoh. $_namaPluginMu
).
Detailed Explanation
Vue menggunakan awalan _
untuk mendefinisikan properti pribadinya sendiri, jadi menggunakan awalan yang sama (contoh._update
) berisiko menimpa properti instance. Bahkan jika kamu memeriksa dan Vue saat ini tidak menggunakan nama properti tertentu, tidak ada jaminan konflik tidak akan muncul di versi yang lebih baru.
Sedangkan untuk awalan $
, tujuannya dalam ekosistem Vue adalah properti instance khusus yang diekspos kepada pengguna, jadi menggunakannya untuk properti pribadi(private) tidak akan sesuai.
Sebagai gantinya, kami menyarankan untuk menggabungkan dua awalan menjadi $_
, sebagai konvensi untuk properti pribadi yang ditentukan pengguna yang menjamin tidak ada konflik dengan Vue.
Buruk
var myGreatMixin = {
// ...
methods: {
update: function () {
// ...
}
}
}
var myGreatMixin = {
// ...
methods: {
_update: function () {
// ...
}
}
}
var myGreatMixin = {
// ...
methods: {
$update: function () {
// ...
}
}
}
var myGreatMixin = {
// ...
methods: {
$_update: function () {
// ...
}
}
}
Aturan Prioritas B: Sangat dianjurkan (Meningkatkan Keterbacaan/Readability)
File komponen sangat dianjurkan
Setiap kali sistem build tersedia untuk menggabungkan file, setiap komponen harus dalam file sendiri.
Ini membantu kamu untuk lebih cepat menemukan komponen ketika kamu perlu mengeditnya atau meninjau cara menggunakannya.
Aturan huruf nama file single-file komponen sangat dianjurkan
Nama file komponen file tunggal harus selalu PascalCase atau kebab-case.
PascalCase bekerja paling baik dengan pelengkapan otomatis dalam editor kode, karena konsisten dengan bagaimana kita mereferensikan komponen dalam JS (X) dan templat. Namun, nama file dengan campuran huruf kapital dan tidak kadang-kadang dapat membuat masalah pada sistem file yang tidak sensitif terhadap huruf kapital, yang mengapa penggunaan kebab-case juga dapat diterima.
Nama komponen dasar sangat dianjurkan
Komponen dasar (contoh. komponen presentasi, bodoh(dumb), atau murni) yang menerapkan gaya dan konvensi khusus aplikasi semua harus dimulai dengan awalan tertentu, seperti Base
,App
, atau V
.
Detailed Explanation
Komponen-komponen ini menjadi dasar untuk gaya dan perilaku yang konsisten dalam aplikasi kamu. Komponen ini hanya mungkin tersusun dari:
- Elemen HTML,
- komponen dasar lainnya, dan
- Komponen UI pihak ketiga.
Tetapi mereka tidak boleh memiliki keadaan(state) global (contoh. Dari toko(store) Vuex).
Nama mereka sering menyertakan nama elemen yang mereka bungkus (contoh. BaseButton
,BaseTable
), kecuali tidak ada elemen untuk tujuan spesifik mereka (contoh. BaseIcon
). Jika kamu membuat komponen serupa untuk konteks yang lebih spesifik, mereka akan hampir selalu mengkonsumsi komponen-komponen ini (contoh. BaseButton
dapat digunakan dalam ButtonSubmit
).
Beberapa keuntungan dari konvensi ini:
Ketika disusun menurut abjad dalam editor, komponen dasar aplikasi kamu semuanya terdaftar bersama, sehingga lebih mudah diidentifikasi.
Karena nama komponen harus selalu multi-kata, konvensi ini mencegah kamu dari keharusan memilih awalan acak untuk pembungkus komponen sederhana (contoh.
MyButton
,VueButton
).Karena komponen ini sangat sering digunakan, kamu mungkin ingin membuatnya menjadi global alih-alih mengimpornya ke mana-mana. Awalan memungkinkan ini dengan memanfaatkan Webpack:
var requireComponent = require.context("./src", true, /^Base[A-Z]/) requireComponent.keys().forEach(function (fileName) { var baseComponentConfig = requireComponent(fileName) baseComponentConfig = baseComponentConfig.default || baseComponentConfig var baseComponentName = baseComponentConfig.name || ( fileName .replace(/^.+\//, '') .replace(/\.\w+$/, '') ) Vue.component(baseComponentName, baseComponentConfig) })
Bagus
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue
components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue
Nama komponen single-instance sangat dianjurkan
Komponen yang seharusnya hanya memiliki satu instance aktif harus dimulai dengan awalan The
, untuk menyatakan bahwa hanya akan ada satu.
Ini tidak berarti komponen hanya digunakan dalam satu halaman, tetapi hanya akan digunakan sekali per halaman. Komponen-komponen ini tidak pernah menerima prop, karena mereka khusus untuk aplikasi kamu, bukan konteksnya dalam aplikasi kamu. Jika kamu merasa perlu menambahkan prop, ini merupakan indikasi yang baik bahwa ini sebenarnya komponen yang dapat digunakan kembali yang hanya digunakan sekali per halaman untuk saat ini.
Nama komponen yang tergabung dengan erat sangat dianjurkan
Komponen anak yang dipasangkan dengan induknya harus menyertakan nama komponen induk sebagai awalan.
Jika komponen hanya menjadi jelas / mungkin dalam konteks komponen induk, hubungan itu harus jelas dalam namanya. Karena editor biasanya mengatur file berdasarkan abjad, ini akan membuat file berkaitan bersebelahan.
Detailed Explanation
Kamu mungkin tergoda untuk memecahkan masalah ini dengan memasukkan komponen anak di direktori yang dinamai dengan induknya. Sebagai contoh:
components/
|- TodoList/
|- Item/
|- index.vue
|- Button.vue
|- index.vue
atau:
components/
|- TodoList/
|- Item/
|- Button.vue
|- Item.vue
|- TodoList.vue
Ini tidak direkomendasikan, karena menghasilkan:
- Banyak file dengan nama yang mirip, membuat pengalihan file dengan cepat dalam editor kode lebih sulit.
- Banyak sub-direktori bersarang, yang meningkatkan waktu yang diperlukan untuk menelusuri komponen di bilah sisi(sidebar) editor.
Buruk
components/
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue
components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue
Bagus
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue
Urutan kata dalam nama komponen sangat dianjurkan
Nama-nama komponen harus dimulai dengan kata-kata level tertinggi (seringkali paling umum) dan diakhiri dengan kata-kata pengubah deskriptif.
Detailed Explanation
Kamu mungkin bertanya-tanya:
“Mengapa kita memaksakan nama komponen untuk menggunakan bahasa yang kurang alami?”
Dalam bahasa Inggris alami, kata sifat dan deskriptor lain biasanya muncul sebelum kata benda, sementara pengecualian membutuhkan kata-kata penghubung. Sebagai contoh:
- Coffee with milk
- Soup of the day
- Visitor to the museum
Kamu pasti dapat memasukkan kata-kata penghubung ini dalam nama komponen jika kamu mau, tetapi urutannya tetap penting.
Juga perhatikan bahwa apa yang dianggap “level tertinggi” akan kontekstual untuk aplikasi kamu.Misalnya, bayangkan aplikasi dengan formulir pencarian. Ini mungkin termasuk komponen seperti ini:
:
components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue
Seperti yang mungkin kamu perhatikan, sangat sulit untuk melihat komponen mana yang spesifik untuk pencarian(search). Sekarang mari kita ganti nama komponen sesuai aturan:
components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputExcludeGlob.vue
|- SearchInputQuery.vue
|- SettingsCheckboxLaunchOnStartup.vue
|- SettingsCheckboxTerms.vue
Karena editor biasanya mengatur file secara alfabet, semua hubungan penting antara komponen sekarang terlihat jelas.
Kamu mungkin tergoda untuk memecahkan masalah ini secara berbeda, mengumpulkan semua komponen pencarian di bawah direktori “search”, lalu semua komponen pengaturan di bawah direktori “settings”. Kami hanya menyarankan mempertimbangkan pendekatan ini di aplikasi yang sangat besar (contoh. 100+ komponen), karena alasan ini:
- Biasanya dibutuhkan lebih banyak waktu untuk menavigasi melalui sub-direktori yang bersarang, daripada menggulir melalui direktori
components
tunggal. - Konflik nama (contoh. Beberapa komponen
ButtonDelete.vue
) membuatnya lebih sulit untuk bernavigasi dengan cepat ke komponen tertentu dalam editor kode. - Refactoring menjadi lebih sulit, karena menemukan dan mengganti seringkali tidak cukup untuk memperbarui referensi relatif ke komponen yang dipindahkan.
Buruk
components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue
Bagus
components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue
Komponen yang dapat ditutup sendiri sangat dianjurkan
Komponen tanpa konten harus ditutup sendiri di komponen file tunggal, templat string, dan JSX - tetapi tidak boleh di templat DOM.
Komponen yang menutup sendiri mengkomunikasin bahwa mereka tidak hanya tidak memiliki konten, tetapi dimaksudkan untuk tidak memiliki konten. Seperti perbedaan antara halaman kosong di buku dan yang berlabel “Halaman ini sengaja dikosongkan.” Kode kamu juga lebih bersih tanpa tag penutup yang tidak perlu.
Sayangnya, HTML tidak mengizinkan elemen khusus untuk ditutup sendiri - hanya elemen resmi kekosongan(“void”). Itulah sebabnya strategi ini hanya mungkin ketika kompiler templat Vue dapat mencapai templat sebelum DOM, kemudian melayani HTML yang memenuhi spesifikasi DOM.
Buruk
<!-- In single-file components, string templates, and JSX -->
<MyComponent></MyComponent>
<!-- In DOM templates -->
<my-component/>
Bagus
<!-- In single-file components, string templates, and JSX -->
<MyComponent/>
<!-- In DOM templates -->
<my-component></my-component>
Aturan huruf nama komponen dalam templat sangat dianjurkan
Dalam kebanyakan proyek, nama komponen harus selalu PascalCase di komponen file tunggal dan templat string - tetapi kebab-case dalam templat DOM.
PascalCase memiliki beberapa keunggulan dibandingkan kebab-case:
- Editor dapat melengkapi nama komponen secara otomatis dalam templat, karena PascalCase juga digunakan dalam JavaScript.
<MyComponent>
lebih berbeda secara visual dari elemen HTML yang satu kata daripada<my-component>
, karena ada dua perbedaan karakter (dua huruf kapital), daripada hanya satu (tanda hubung).- Jika kamu menggunakan elemen khusus non-Vue dalam templat kamu, seperti komponen web, PascalCase memastikan bahwa komponen Vue kamu tetap terlihat jelas.
Sayangnya, karena ketidakpekaan huruf HTML, templat DOM masih harus menggunakan kebab-case.
Juga perhatikan bahwa jika kamu sudah terlanjur banyak menggunakan kebab-case, konsistensi dengan konvensi HTML dan dapat menggunakan aturan huruf(casing) yang sama di semua proyek kamu mungkin lebih penting daripada keuntungan yang tercantum di atas. Dalam kasus tersebut, menggunakan kebab-case di manapun juga dapat diterima.
Buruk
<!-- Di single-file components dan string templates -->
<mycomponent/>
<!-- Di single-file components dan string templates -->
<myComponent/>
<!-- Di DOM templates -->
<MyComponent></MyComponent>
Bagus
<!-- Di single-file components dan string templates -->
<MyComponent/>
<!-- Di DOM templates -->
<my-component></my-component>
ATAU
<!-- Dimanapun -->
<my-component></my-component>
Aturan huruf nama komponen pada JS/JSX sangat dianjurkan
Nama komponen dalam JS / JSX harus selalu PascalCase, meskipun mereka mungkin kebab-case di dalam string untuk aplikasi yang lebih sederhana yang hanya menggunakan registrasi komponen global melalui Vue.component
.
Detailed Explanation
Dalam JavaScript, PascalCase adalah konvensi untuk kelas dan konstruktor prototipe - pada dasarnya, apa pun yang dapat memiliki instance berbeda. Komponen Vue juga memiliki instance, jadi masuk akal juga menggunakan PascalCase. Sebagai manfaat tambahan, menggunakan PascalCase dalam JSX (dan templat) memungkinkan pembaca kode untuk lebih mudah membedakan antara komponen dan elemen HTML.
Namun, untuk aplikasi yang hanya menggunakan definisi komponen global melalui Vue.component
, kami sarankan kebab-case. Alasannya adalah:
- Jarang sekali komponen global direferensikan dalam JavaScript, jadi mengikuti konvensi untuk JavaScript kurang masuk akal.
- Aplikasi ini selalu menyertakan banyak templat di-DOM, yang mana harus menggunakan kebab-case.
Buruk
Vue.component('myComponent', {
// ...
})
import myComponent from './MyComponent.vue'
export default {
name: 'myComponent',
// ...
}
export default {
name: 'my-component',
// ...
}
Bagus
Vue.component('MyComponent', {
// ...
})
Vue.component('my-component', {
// ...
})
import MyComponent from './MyComponent.vue'
export default {
name: 'MyComponent',
// ...
}
Nama komponen dengan kata lengkap sangat dianjurkan
Nama komponen harus lebih mengutamakan kata yang lengkap daripada singkatan.
Pelengkap otomatis(autocompletion) dalam editor membuat ‘biaya’ penulisan nama yang lebih panjang menjadi sangat rendah, sementara kejelasan yang mereka berikan sangat berharga. Singkatan yang tidak biasa, khususnya, harus selalu dihindari.
Aturan huruf nama prop sangat dianjurkan
Nama prop harus selalu menggunakan camelCase ketika deklarasi, tetapi menggunakan kebab-case di templat dan JSX.
Kami hanya mengikuti konvensi masing-masing bahasa. Dalam JavaScript, camelCase lebih alami. Dalam HTML, yang alami adalah kebab-case.
Elemen multi-atribut sangat dianjurkan
Elemen dengan banyak atribut harus menjangkau beberapa baris, dengan satu atribut per baris.
Dalam JavaScript, menulis objek dengan beberapa properti pada beberapa baris secara luas dianggap sebagai konvensi yang bagus, karena jauh lebih mudah dibaca. Templat dan JSX kami pandang layak mendapatkan pertimbangan yang sama.
Buruk
<img src="https://vuejs.org/images/logo.png" alt="Vue Logo">
<MyComponent foo="a" bar="b" baz="c"/>
Bagus
<img
src="https://vuejs.org/images/logo.png"
alt="Vue Logo"
>
<MyComponent
foo="a"
bar="b"
baz="c"
/>
Ekspresi sederhana pada templat sangat dianjurkan
Templat komponen hanya boleh menyertakan ekspresi sederhana, dengan ekspresi yang lebih kompleks di-refactor menjadi properti atau metode yang yang telah dikomputasi.
Ekspresi kompleks dalam templat kamu membuatnya kurang deklaratif. Kita harus berusaha menggambarkan apa yang akan muncul, bukan bagaimana kita menghitung nilai itu. Properti dan metode yang dikomputasi juga memungkinkan kode untuk digunakan kembali.
Buruk
{{
fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}}
Bagus
<!-- In a template -->
{{ normalizedFullName }}
// The complex expression has been moved to a computed property
computed: {
normalizedFullName: function () {
return this.fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}
}
Properti terkomputasi yang sederhana sangat dianjurkan
Properti terkomputasi yang kompleks harus dipecah menjadi properti yang lebih sederhana sebanyak mungkin.
Detailed Explanation
Properti dengan penamaan baik, terkomputasi sederhana adalah yang:
Lebih mudah untuk diuji
Ketika setiap properti yang dikomputasi hanya mengandung ekspresi yang sangat sederhana, dengan sangat sedikit dependensi, akan lebih mudah untuk menulis tes yang mengonfirmasi bahwa itu berfungsi dengan benar.
Lebih mudah dibaca
Menyederhanakan properti yang dihitung memaksa kamu untuk memberikan setiap nilai nama deskriptif, meskipun itu tidak digunakan kembali. Ini membuatnya lebih mudah bagi pengembang lain (dan masa depan kamu) untuk fokus pada kode yang mereka pedulikan dan mencari tahu apa yang terjadi.
Lebih mudah beradaptasi dengan perubahan persyaratan/kebutuhan
Nilai apa pun yang dapat dinamai mungkin berguna untuk tampilan. Misalnya, kami mungkin memutuskan untuk menampilkan pesan yang memberi tahu pengguna berapa banyak uang yang mereka simpan. Kami mungkin juga memutuskan untuk menghitung pajak penjualan, tetapi mungkin menampilkannya secara terpisah, bukan sebagai bagian dari harga akhir.
Properti terkomputasi yang kecil dan terfokus membuat asumsi yang lebih sedikit tentang bagaimana informasi akan digunakan, sehingga memerlukan lebih sedikit refactoring ketika persyaratan/kebutuhan berubah.
Buruk
computed: {
price: function () {
var basePrice = this.manufactureCost / (1 - this.profitMargin)
return (
basePrice -
basePrice * (this.discountPercent || 0)
)
}
}
Bagus
computed: {
basePrice: function () {
return this.manufactureCost / (1 - this.profitMargin)
},
discount: function () {
return this.basePrice * (this.discountPercent || 0)
},
finalPrice: function () {
return this.basePrice - this.discount
}
}
Nilai atribut yang dikutip sangat dianjurkan
Nilai atribut HTML yang tidak kosong harus selalu berada di dalam tanda kutip (tunggal atau ganda, mana saja yang tidak digunakan dalam JS).
Meskipun nilai atribut tanpa spasi tidak perlu memiliki tanda kutip dalam HTML, praktik ini sering membuat nilai atribut lebih susah terbaca.
Menulis cepat direktif sangat dianjurkan
Tulisan ringkas atau lebih dikenal dengan shorthands dari Direktif (:
untuk v-bind:
and @
untuk v-on:
) harus selalu digunakan atau tidak sama sekali.
Buruk
<input
v-bind:value="newTodoText"
:placeholder="newTodoInstructions"
>
<input
v-on:input="onInput"
@focus="onFocus"
>
Bagus
<input
:value="newTodoText"
:placeholder="newTodoInstructions"
>
<input
v-bind:value="newTodoText"
v-bind:placeholder="newTodoInstructions"
>
<input
@input="onInput"
@focus="onFocus"
>
<input
v-on:input="onInput"
v-on:focus="onFocus"
>
Aturan Prioritas C : Dianjurkan (Mengurangi Pilihan Asal dan Kelelahan Kognitif)
Urutan pilihan komponen/instance dianjurkan
Pilihan komponen/instance harus diurutkan secara konsisten.
Ini adalah urutan default yang kami sarankan untuk pilihan komponen. Mereka dibagi menjadi beberapa kategori, jadi kamu akan tahu di mana menambahkan properti baru dari plugin.
Efek Samping (memicu efek di luar komponen)
el
Kesadaran Global (membutuhkan pengetahuan di luar komponen)
name
parent
Tipe Komponen (mengubah jenis komponen)
functional
Pengubah Template (mengubah cara templat dikompilasi)
delimiters
comments
Ketergantungan Templat (aset yang digunakan dalam templat)
components
directives
filters
Komposisi (menggabungkan properti ke dalam pilihan)
extends
mixins
Antarmuka(Interface) (antarmuka ke komponen)
inheritAttrs
model
props
/propsData
State Lokal (properti reaktif lokal)
data
computed
Events (panggilan balik dipicu oleh event reaktif)
watch
- Siklus Hidup Event (dalam urutan yang disebut)
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
Properti Non-Reaktif (properti instance tidak tergantung pada sistem reaktivitas)
methods
Rendering (deskripsi deklaratif dari output komponen)
template
/render
renderError
Urutan atribut elemen dianjurkan
Atribut dari elemen (termasuk komponen) harus diurutkan secara konsisten.
Ini adalah urutan default yang kami sarankan untuk pilihan komponen. Mereka dibagi menjadi beberapa kategori, jadi kamu akan tahu di mana menambahkan atribut dan direktif khusus.
Definisi (memberikan pilihan komponen)
is
Daftar Penyajian (membuat beberapa variasi elemen yang sama)
v-for
Persyaratan (apakah elemen diberikan / ditampilkan)
v-if
v-else-if
v-else
v-show
v-cloak
Render Modifiers (mengubah cara elemen merender)
v-pre
v-once
Kesadaran Global (membutuhkan pengetahuan di luar komponen)
id
Atribut Unik (atribut yang membutuhkan nilai unik)
ref
key
slot
Pengikatan Dua Arah (menggabungkan pengikatan(binding) dan event)
v-model
Atribut Lainnya (semua atribut terikat & terikat tidak ditentukan)
Event (pendengar(listener) event komponen)
v-on
Konten (menimpa konten elemen)
v-html
v-text
Baris kosong pada pilihan komponen/instance dianjurkan
Kamu boleh menambahkan satu baris kosong di antara properti multi-baris, terutama jika pilihan tidak dapat lagi masuk ke layar kamu tanpa menggulir(scroll).
Ketika komponen mulai terasa penuh atau sulit dibaca, menambahkan ruang di antara properti multi-garis dapat membuatnya lebih mudah untuk dibaca sekilas. Di beberapa editor, seperti Vim, opsi pemformatan seperti ini juga dapat membuatnya lebih mudah dinavigasi dengan keyboard.
Bagus
props: {
value: {
type: String,
required: true
},
focused: {
type: Boolean,
default: false
},
label: String,
icon: String
},
computed: {
formattedValue: function () {
// ...
},
inputClasses: function () {
// ...
}
}
// Tanpa spasi pun tak mengapa selama komponen
// masih mudah dibaca dan navigasi.
props: {
value: {
type: String,
required: true
},
focused: {
type: Boolean,
default: false
},
label: String,
icon: String
},
computed: {
formattedValue: function () {
// ...
},
inputClasses: function () {
// ...
}
}
Urutan elemen tingkat atas komponen file tunggal dianjurkan
Komponen file tunggal harus selalu mengurutkan tag <script>
, <template>
, dan <style>
secara konsisten, dengan <style >
terakhir, karena setidaknya satu dari dua lainnya selalu diperlukan.
Buruk
<style>/* ... */</style>
<script>/* ... */</script>
<template>...</template>
<!-- ComponentA.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
Bagus
<!-- ComponentA.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>
<!-- ComponentA.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
Aturan Prioritas D Rules: Digunakan dengan hati-hati (Pola Berpotensi Membahayakan)
v-if
/v-else-if
/v-else
tanpa key
digunakan hati-hati
Biasanya lebih baik menggunakan key
dengan v-if
+ v-else
, jika keduanya adalah tipe elemen yang sama (contoh. Keduanya <div>
elemen).
Secara default, Vue memperbarui DOM seefisien mungkin. Itu berarti ketika beralih di antara elemen-elemen dari tipe yang sama, itu hanya menambal elemen yang ada, daripada menghapusnya dan menambahkan yang baru di tempatnya. Ini dapat memiliki konsekuensi yang tidak diinginkan jika elemen-elemen ini seharusnya tidak dianggap sama.
Bagus
<div
v-if="error"
key="search-status"
>
Error: {{ error }}
</div>
<div
v-else
key="search-results"
>
{{ results }}
</div>
<p v-if="error">
Error: {{ error }}
</p>
<div v-else>
{{ results }}
</div>
Penyeleksi elemen dalam scoped
digunakan hati-hati
Selektor elemen sebaiknya dihindari dalam scoped
.
Utamakan penyeleksi kelas daripada penyeleksi elemen dalam gaya scoped
, karena sejumlah besar penyeleksi elemen lambat.
Detailed Explanation
Untuk gaya lingkupan(scoped), Vue menambahkan atribut unik ke elemen komponen, seperti data-v-f3f3eg9
. Kemudian penyeleksi dimodifikasi sehingga hanya elemen yang cocok dengan atribut ini yang dipilih (contoh. Tombol [data-v-f3f3eg9]
).
Masalahnya adalah sejumlah besar penyeleksi elemen (contoh. tombol [data-v-f3f3eg9]
) akan jauh lebih lambat dari penyeleksi kelas (contoh. .Btn-close [data-v-f3f3eg9]
), sehingga penyeleksi kelas harus lebih diutamakan jika memungkinkan.
Buruk
<template>
<button>X</button>
</template>
<style scoped>
button {
background-color: red;
}
</style>
Bagus
<template>
<button class="btn btn-close">X</button>
</template>
<style scoped>
.btn-close {
background-color: red;
}
</style>
Komunikasi orangtua-anak implisit digunakan hati-hati
Prop dan event harus dipilih untuk komunikasi komponen orangtua-anak, daripada this.$parent
atau prop yang bermutasi.
Aplikasi Vue yang ideal adalah props down, events up
. Berpegang teguh pada konvensi ini membuat komponen kamu lebih mudah dipahami. Namun, ada kasus kecil dimana mutasi prop atau this.$parent
dapat menyederhanakan dua komponen yang sudah sangat terikat.
Masalahnya adalah, ada juga banyak kasus simple di mana pola-pola ini menawarkan kenyamanan. Hati-hati: jangan tergoda untuk ‘menjual’ kemudahan jangka panjang (bisa memahami aliran state kamu) untuk kenyamanan jangka pendek (menulis lebih sedikit kode).
Buruk
Vue.component('TodoItem', {
props: {
todo: {
type: Object,
required: true
}
},
template: '<input v-model="todo.text">'
})
Vue.component('TodoItem', {
props: {
todo: {
type: Object,
required: true
}
},
methods: {
removeTodo () {
var vm = this
vm.$parent.todos = vm.$parent.todos.filter(function (todo) {
return todo.id !== vm.todo.id
})
}
},
template: `
<span>
{{ todo.text }}
<button @click="removeTodo">
X
</button>
</span>
`
})
Bagus
Vue.component('TodoItem', {
props: {
todo: {
type: Object,
required: true
}
},
template: `
<input
:value="todo.text"
@input="$emit('input', $event.target.value)"
>
`
})
Vue.component('TodoItem', {
props: {
todo: {
type: Object,
required: true
}
},
template: `
<span>
{{ todo.text }}
<button @click="$emit('delete')">
X
</button>
</span>
`
})
mengelola non-flux state digunakan hati-hati
Vuex harus lebih diutamakan untuk mengelola state global, daripada this.$root
atau global event bus.
Mengelola state pada this.$root
dan / atau menggunakan global event bus bisa terasa nyaman untuk kasus yang sangat sederhana, tetapi tidak patut untuk sebagian besar aplikasi. Vuex tidak hanya menawarkan tempat sentral untuk mengelola state, tetapi juga alat untuk mengatur, melacak, dan men-debug perubahan state.
Buruk
// main.js
new Vue({
data: {
todos: []
},
created: function () {
this.$on('remove-todo', this.removeTodo)
},
methods: {
removeTodo: function (todo) {
var todoIdToRemove = todo.id
this.todos = this.todos.filter(function (todo) {
return todo.id !== todoIdToRemove
})
}
}
})
Bagus
// store/modules/todos.js
export default {
state: {
list: []
},
mutations: {
REMOVE_TODO (state, todoId) {
state.list = state.list.filter(todo => todo.id !== todoId)
}
},
actions: {
removeTodo ({ commit, state }, todo) {
commit('REMOVE_TODO', todo.id)
}
}
}
<!-- TodoItem.vue -->
<template>
<span>
{{ todo.text }}
<button @click="removeTodo(todo)">
X
</button>
</span>
</template>
<script>
import { mapActions } from 'vuex'
export default {
props: {
todo: {
type: Object,
required: true
}
},
methods: mapActions(['removeTodo'])
}
</script>