@Secretmm
2021-02-18T02:54:59.000000Z
字数 5706
阅读 514
梳理
命名规范:通过大家讨论之后形成文档,新项目和重构的项目必须遵守新命名规范
变量:小驼峰命名
文件夹:小驼峰命名
.ts文件:小驼峰命名
.vue文件:大驼峰命名【遵循自动生成规则】
图片: 小写字母,下划线连接
css类名:小写字母,短横杠连接
路由path:小写字母,短横杠连接
iconfont Font Family:iconfont_${项目名}
iconfont icon前缀:icon_${项目名}
iconfont icon:小写字母,短横杠连接
统一缩进、统一分号、统一空格的位置、统一对象尾部属性后的逗号等等
需要与后端确定,确定之后,形成文档;
flag
问题:需要保证:仅使用code
码一定不会出错
null
,{}
;例如:时间只传秒级时间戳
Example.vue
<template>
<div>
this is Example page
</div>
</template>
<style scoped>
</style>
<script lang='ts'>
import {
Component,
Emit,
Inject,
Model,
Prop,
Provide,
Vue,
Watch
} from 'vue-property-decorator';
import { State, Getter, Action, Mutation, namespace } from 'vuex-class';
/* component组件 */
@Component({
components: {}
})
export default class Example extends Vue {
/* @Inject/@Prop */
/* data数据 /@Provide */
/* method/@Emit/@Action/@Mutation */
/* computed/@State/@Getter */
/* Watch监听 */
/* @Watch('xxx') */
/* @Watch('xxx', { deep: true }) */
/* lifecycle 生命周期 */
mounted() {}
}
</script>
Example.tsx
: hook
import React, { useState, useEffect, Props } from 'react';
import './Example.css';
type ExampleProps = {
}
Example.defaultProps = {}
function Example(props: ExampleProps & Props<any>) {
//const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
//useEffect(() => {
//dom更新后的操作
//卸载组件的操作
//return () => {}
//},[count]);
return (
<div>this is Example</div>
)
}
export default Example;
Example.tsx
: class
import React, { Props } from 'react';
import './Example.css';
import {Route, Switch, RouteChildrenProps } from 'react-router-dom';
//import {} from '@/util/apiMethod';
type ExampleProps = {
}
type ExampleState = {
}
class Example extends React.Component<ExampleProps & Props<any>, ExampleState> {
constructor(props: ExampleProps & Props<any>) {
super(props);
this.state = {
//count: 0
};
}
static defaultProps:ExampleProps = {
}
render() {
return (
<div>this is Example</div>
);
}
}
export default Example;
脚手架名:
vue+ts
:daddylab-cli-vue
react+ts
:daddylab-cli-react
命令头:
daddylab-vue
:daddylab-vue create app
daddylab-react
:daddylab-react create app
vue-cli
/ creat react app
可以生成的基本框架】vue.config.js
的基本配置tsconfig.json
的基本配置:别名第一部分:
main.ts
:router.ts
:App.vue
:- 基本类型声明【
.d.ts
】:图片
第二部分:
views
文件夹:仅用于路由界面,层级参考路由层级,可自动生成components
文件夹:store
文件夹:
第三部分:
interface
文件夹:用于接口声明【index.ts
用于公共接口声明】util
文件夹:index.ts
用于公用方法声明;apiMethod.ts
:自动生成的api
方法引用mixins
文件夹:分发vue
组件中的可复用功能api
文件夹:自动生成。存放后端接口相关;【详细见最后】
第四部分:
theme
文件夹:【只放样式类】reset.css
用于清除浏览器默认样式;index.css
作为css
访问入口assets
文件夹:只放图片importImage
文件夹: 图片引用
src
结构选配,也可以通过脚手架相关命令在开发过程中添加;
可通过
npm
包的形式
工具名:
daddylab-cli-tool
命令头:
daddylab-tool
:daddylab-tool create xxx
见第六部分
效果:输入命名行例如
daddylab-tool create imgFile
,根据assets
目录中图片文件夹生成同名ts
文件,ts
文件中有对应的文件夹中图片的引用
ts
文件示例
import light1 from '../assets/activity/light1.png';
import light2 from '../assets/activity/light2.png';
import light3 from '../assets/activity/light3.png';
import light4 from '../assets/activity/light4.png';
import light5 from '../assets/activity/light5.png';
import light6 from '../assets/activity/light6.png';
export {
light1,light2,light3,light4,light5,light6
}
以
vue
文件举例,生成路由文件效果:输入命令如:daddylab-tool create --route Login
,则在views
目录中自动生成Login.vue
,在route.ts
中在对应层级加入基本的相关路由配置,例如:
{
path: '/login'
}
考虑到路由配置的复杂度,这个命令行的主要功能还是为了使
views
文件夹和route.ts
的目录结构变清晰,route.ts
的其它配置暂时不考虑自动化
生成组件效果:要生成一个在路由页面
Main
里使用的组件MainLayOut
,输入命令例如daddylab-tool create --components /Main MainLayOut vue|react
,则在components
目录里自动就生成Main
目录,里面有一个MainLayOut.vue|.tsx
,并自动根据snippets
生成好初始化代码
daddy-lib
:一些常用方法,例如时间转换,localstorage
,接口声明方法,等等等等,等待讨论daddy-css
:一些常用样式可以放入,用于组件库的样式统一
- 将工具尽可能的集成到脚手架中,升级脚手架
以:/api/class-studyreport/fictitious-way
为例:
1.@/util/apiMethod
:接口引用
import {
metaProvider as fictitiousWayProvider,
Params as FictitiousWayParams,
Response as FictitiousWayResponse
} from '@/api/class-studyreport/fictitious-way';
getFictitiousWay(params: FictitiousWayParams): Promise<FictitiousWayResponse> {
return new Promise((resolve, reject) => {
fetchApi(fictitiousWayProvider, params)
.then(data => {
resolve(data);
})
.catch(e => {
reject();
});
});
},
2.@/api/class-studyreport/fictitious-way
: 接口声明
import { ApiMetaProvider } from '@/api';
const method = 'GET';
const url = '/api/class-studyreport/fictitious-way';
interface Params {
id: number;
startTime: number;
studentUserId: string;
teacherUserId: string;
subject: string;
category: number;
title: string;
}
interface Response {
id: number;
subject: string;
student_user_id: string;
teacher_user_id: string;
title: string;
category: number;
start_time: number;
}
const metaProvider: ApiMetaProvider<Params, Response> = function() {
return {
url: url,
method: method
};
};
export { metaProvider, Params, Response };
3.@/util/apiFetcher
:fetchApi
:接口统一处理
import axios from 'axios';
import qs from 'qs';
import { ApiMetaProvider } from '@/api';
import { transCamel } from 'xxxxx';
import { Message } from 'xxxx';
import Vue from 'vue';
export const fetchProgress = Vue.observable({ percent: 0 });
function onProgress(event: ProgressEvent) {
fetchProgress.percent = Math.round((event.loaded * 100) / event.total);
}
export default async function fetchApi<P, R>(
apiMetaProvider: ApiMetaProvider<P, R>,
params?: P
): Promise<R> {
try {
const meta = apiMetaProvider();
const { data } = await axios({
url: meta.url,
method: meta.method,
headers: { 'X-Requested-With': 'XMLHttpRequest', 'Cache-Control': 'no-cache' },
[meta.method === 'GET' ? 'params' : 'data']:
meta.method === 'GET'
? transCamel(params || {})
: qs.stringify(transCamel(params || {})),
onDownloadProgress: onProgress
});
if (data.code === 200 || data.code === 0) {
return data.data;
} else {
data.code !== 505 && Message.error(data.message);
throw { code: data.code, message: data.message };
}
} finally {
fetchProgress.percent = 0;
}
}
export interface Api {
fetch<P, R>(apiMetaProvider: ApiMetaProvider<P, R>, params: P): Promise<R>;
}
export interface FetchApi<P, R> {
(apiMetaProvider: ApiMetaProvider<P, R>, params: P): Promise<R>;
}
4.@/api
:ApiMetaProvider
interface ApiMeta {
method: 'GET' | 'POST';
url: string;
}
export interface ApiMetaProvider<P, R> {
(): ApiMeta;
}