良好的代码风格更容易维护代码,虽然没有绝对的标准,但保持自己一贯的代码风格可以提高代码质量。接下来就来介绍我开发 Vue 代码的大致风格吧。
DatePicker.vue ​
<template>
<!-- 组件名字应该大写字母开头,组件最外层节点类名和组件文件名保持一致,PascalCase改成下划线 -->
<div class="date-picker" v-click-outside="clickClose">
<!-- 属性定义应该先定义原生属性,再定义Vue属性 -->
<div
class="date-picker-rel"
ref="reference"
@click="handleClick"
:class="{ 'o-disabled': disabled }"
>
<slot name="picker">
<VueInput
v-model="currentDate"
class="date-picker-input"
:disabled="disabled"
:placeholder="placeholder"
:clearable="clearable"
@on-clear="clearDate"
@on-input="input"
@on-blur="updateDate"
>
<template v-slot:suffix>
<svg-icon
name="date"
class="date-picker-icon"
:class="{ 'o-disabled': disabled, 'o-show': visible }"
/>
</template>
</VueInput>
</slot>
</div>
<transition name="fade">
<div
class="date-picker-popper"
:style="styles"
ref="popper"
v-show="visible && !disabled"
>
<DateTable
:selectedDate="formatedDate"
:isRange="isRange"
:visible="visible"
@select="selectDate"
/>
</div>
</transition>
</div>
</template>
<script lang="ts">
/**
* 模块定义:
* 1. 先第三方后自定义
* 2. 除非是组件内部私有模块,否则全部使用 @ 绝对路径引用
* 3. 按需引用
*/
import { Component, Mixins, Prop, Watch } from 'vue-property-decorator';
// @ts-ignore
import { directive as clickOutside } from 'v-click-outside-x';
import Input from '@/components/input';
import PopperMixin from '@/mixins/popper';
import dateUtils from '@/utils/date';
import DateTable from './DateTable.vue';
import { namespace } from 'vuex-class';
const Info = namespace('information');
@Component({
directives: {
clickOutside
},
components: {
DateTable,
VueInput: Input
},
provide() {
return {
picker: this
};
}
})
// 类名和组件名保持一致,方便调试
export default class DatePicker extends Mixins(PopperMixin) {
/**
* 属性定义区域
*/
@Prop() readonly value!: Date | null | Array<Date | null>;
@Prop({ default: false }) readonly disabled!: boolean;
@Prop({ default: false, type: Boolean }) readonly clearable!: boolean;
@Prop({ default: '' }) readonly placeholder!: string;
/**
* State映射区域,定义顺序是: State Getter Action Mutation
*/
@Info.State notifications!: Array<IAnnouncement>;
/**
* data定义区域
*/
currentDate = '';
updateByInput = false;
/**
* computed区域, 如果同时有 get 和 set 记得配对写一起
*/
get formatedDate(): Array<Date | null> {
if (Array.isArray(this.value)) {
return this.value;
} else {
return [this.value];
}
}
get isRange() {
return Array.isArray(this.value);
}
/**
* watch区域, 函数名 on + 属性名 + Changed
*/
@Watch('value', { immediate: true })
onValueChanged() {
this.currentDate = dateUtils.formatDate(this.value);
}
/**
* 生命周期函数
* beforeCreate -> created -> beforeMount -> mounted -> beforeUpdate ->
* updated -> activated -> deactivated -> beforeDestroy -> destroyed -> errorCaptured
*/
created() {
// noop
}
/**
* methods 区域
*/
clickClose() {
if (this.visible && !this.disabled) {
this.closePopper();
}
}
handleClick() {
if (!this.disabled) {
if (this.visible) {
this.closePopper();
} else {
this.showPopper();
}
}
}
clearDate() {
if (this.isRange) {
this.$emit('input', [null, null]);
} else {
this.$emit('input', null);
}
}
input() {
this.updateByInput = true;
}
updateDate() {
if (this.updateByInput) {
if (this.isRange) {
const dates = this.currentDate.split(' - ');
if (dates.length > 1) {
const [start, end] = dates;
const startDate = dateUtils.parseDate(start);
const endDate = dateUtils.parseDate(end);
if (
!Number.isNaN(startDate.getTime()) &&
!Number.isNaN(endDate.getTime())
) {
this.$emit(
'input',
[startDate, endDate].sort((s, e) => {
return s.getTime() - e.getTime();
})
);
} else {
this.$emit('input', this.value);
this.currentDate = dateUtils.formatDate(this.value);
}
}
} else {
const startDate = new Date(this.currentDate);
if (!Number.isNaN(startDate.getTime())) {
this.$emit('input', startDate);
} else {
this.$emit('input', this.value);
this.currentDate = dateUtils.formatDate(this.value);
}
}
this.updateByInput = false;
}
}
selectDate(date: Date | Array<Date>) {
this.currentDate = dateUtils.formatDate(date);
this.$emit('input', date);
this.clickClose();
}
}
</script>
<style lang="scss">
.date-picker {
display: block;
/**
* CSS书写顺序
* 以 Formatting Model (布局方式,位置) -> Box Model (尺寸) -> Typographic (文本相关) -> Visual (视觉效果)
* 的顺序书写,可以提高代码的可读性。
* Formatting Model 相关属性包括: position, top, right, bottom, left, float, display, overflow 等
* Box Model 相关属性包括: border, margin, padding, width, height 等
* Typographic 相关属性包括: font, line-height, text-align, word-wrap 等
* Visual 相关属性包括: background, color, transition, list-style 等
* 如果有 content 属性, 应该放在最前面。
*/
&-popper {
width: 272px;
}
}
</style>
总结 ​
良好的代码风格可以提高代码的可读性,建议大家都保持一致的风格,方便团队合作。
