善用 computed 屬性去描述一些條件式或可讀性不高的程式碼
<template>
<div v-if="isLoggedInAndDataLoaded">
Logging !
</div>
</template>
<script>
export default {
name: 'Home',
computed: {
menu() {
return this.$store.state.app.menu;
},
isLoggedInAndDataLoaded() {
return this.$store.state.auth.isLoggedIn && this.menu;
},
},
}
</script>
文件式組件 (*.vue) 使用 PascalCase 命名方式.
components/
|- MyComponent.vue
基礎組件 (無邏輯或無條件的組件) 命名方式, 以前綴 Base、App 或 V 命名.
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue
components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue
單例組件 (單個實例組件) 以前綴 The 命名表示唯一性.
components/
|- TheHeading.vue
|- TheSidebar.vue
緊密耦合的組件應以父組件名為前綴命名.
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
組件應以一般描述的單詞為開頭, 描述性的修飾詞結尾
Bad:
components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue
Good:
components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue
el
name
parent
functional
delimiters
comments
components
directives
filters
extends
mixins
inheritAttrs
model
props / propsData
data
computed
watch
Lifecycle Events
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
methods
template / render
renderError
使用有意義且可拼音的命名變數
const currentDate = moment().format('YYYY/MM/DD')
給變量賦予意義提高代碼可讀性及可搜尋性
// Declare them as capitalized named constants.
const MILLISECONDS_IN_A_DAY = 86400000
setTimeout(blastOff, MILLISECONDS_IN_A_DAY)
給變量賦予意義提高代碼可讀性及可搜尋性
// Declare them as capitalized named constants.
const MILLISECONDS_IN_A_DAY = 86400000
setTimeout(blastOff, MILLISECONDS_IN_A_DAY)
說明變數名稱提高代碼可讀性
Bad:
const address = 'One Infinite Loop, Cupertino 95014'
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2])
Good:
const address = 'One Infinite Loop, Cupertino 95014'
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/
const [, city, zipCode] = address.match(cityZipCodeRegex) || []
saveCityZipCode(city, zipCode)
函式變數數量不要超過2個,當超過2個表示這個函式正在做複雜的事
- 一個函式不要做太多事情,拆分功能提高復用性及可測試性
- 函數名稱明確告訴我們它正在做什麼事
- 利用函式減少重複的代碼,提高維護性
Bad:
function emailClients(clients) {
clients.forEach((client) => {
const clientRecord = database.lookup(client)
if (clientRecord.isActive()) {
email(client)
}
});
}
Good:
function emailActiveClients(clients) {
clients
.filter(isActiveClient)
.forEach(email)
}
function isActiveClient(client) {
const clientRecord = database.lookup(client)
return clientRecord.isActive()
}
函式做了"接受一個值並返回一個結果"以外的事,可能會產生副作用,像是對原本的值進行操作。比如說寫入文件、更動全域變數或影響到其他部分。
Bad:
let name = 'Ryan McDermott'
function splitInfoFirstAndLastName() {
name = name.split(' ')
}
splitInfoFirstAndLastName()
console.log(name) // ['Ryan', 'McDermott']
Good:
function splitInfoFirstAndLastName(name) {
return name.split(' ')
}
const name = 'Ryan McDermott'
const newName = splitInfoFirstAndLastName(name)
console.log(name) // 'Ryan McDermott'
console.log(newName) // ['Ryan', 'McDermott']
In JavaScript, primitives are passed by value and objects/arrays are passed by reference.
Bad:
const addItemToCart = (cart, item) => {
cart.push({item, date: Date.now()})
}
Good:
const addItemToCart = (cart, item) => {
return [...cart, {item, date: Date.now()}]
}
複製巨大物件是一件成本很重的事情,好在有一些很棒的工具,像是 Immutable.js,降低記憶體的消耗,有效配制記憶體。
JavaScript isn't a functional language in the way that Haskell is, but it has a functional flavor to it. Functional languages can be cleaner and easier to test. Favor this style of programming when you can.
Bad:
const programmerOutput = [
{
name: 'Uncle Bobby',
linesOfCode: 500
}, {
name: 'Suzie Q',
linesOfCode: 1500
}, {
name: 'Jimmy Gosling',
linesOfCode: 150
}, {
name: 'Gracie Hopper',
linesOfCode: 1000
}
]
let totalOutput = 0
for (let i = 0; i < programmerOutput.length; i++) {
totalOutput += programmerOutput[i].linesOfCode
}
Good:
const programmerOutput = [
{
name: 'Uncle Bobby',
linesOfCode: 500
}, {
name: 'Suzie Q',
linesOfCode: 1500
}, {
name: 'Jimmy Gosling',
linesOfCode: 150
}, {
name: 'Gracie Hopper',
linesOfCode: 1000
}
];
const totalOutput = programmerOutput
.map(output => output.linesOfCode)
.reduce((totalLines, lines) => totalLines + lines)
- 封裝條件語句
- 避免否定條件語句
- 避免使用條件判斷
function 在繼承及建構方面可讀性較差,當需要使用繼承時優先選擇 classes,但建立的對象過於複雜時,效能考量最好選擇更小的 fumction 而非 classes