@Secretmm
2021-02-18T02:54:59.000000Z
字数 5706
阅读 590
梳理
命名规范:通过大家讨论之后形成文档,新项目和重构的项目必须遵守新命名规范
变量:小驼峰命名
文件夹:小驼峰命名
.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;}