Blame view

README.md 6.31 KB
weiqingting authored
1 2 3 4 5 6 7
# 平台化框架
> 基于express 上面封装的一层框架,主要以配置贯穿项目,比较灵活,强化了MVC了思想,尤其Model层级上面
#### 项目特点
* 1 Model(接口层) 以配置为主
* 2 项目中最好禁止使用require(./XXXX)自定义模块,为了支持服务器打包,变换目录
## 文件目录
weiqingting authored
8
#举个栗子 实现一个用户注册的功能
weiqingting authored
9 10 11 12 13 14 15 16 17
## Model
###### 新建一个interface.js
		module.exports={
		    namespace:"User",								//命名空间
		    apis:{
				register:{
		            title:'用户注册',						//标题 用于日志统计
		            url:'/user/register',		
		            params:{
weiqingting authored
18
		                firstName:{type:String,require:true,default:'wei'},
weiqingting authored
19 20
		                LastName:{type:String,require:true},
		                fullName:{type:String,require:true},
weiqingting authored
21 22
						yaoQingCode:{type:String,require:true},
		                regTimeguid:{type:String,coerce:function(value){
weiqingting authored
23 24 25 26 27
									return Date.now().toString()+"-"+this.fullName+"-"+value;
								}}
		            }
		        },
				checkUserName:{
weiqingting authored
28
		            title:'检查用户名称是否重复',
weiqingting authored
29 30
		            url:'/user/checkUserName',
		            params:{
weiqingting authored
31
		                fullName:{type:String}
weiqingting authored
32 33
		            }
		        },
weiqingting authored
34 35 36 37 38 39 40 41 42
				checkYaoQingMa:{
					title:'检查邀请码',
					url:'/user/checkYaoQingMa',
		            params:{
		                yaoQingCode:{type:String,required:true}
		            }
				},
				//接口的定义可以为JSON对象,也可以为function,作为function的时候,参数req,callback,req你懂的,callback是接口返回的数据入口.
				//如果你要调用其他模块接口,你就在后面继续加参数,比如User,Role,单词一定不要写错了。所以从某种角度来说,你可以不用require 了
weiqingting authored
43
				fuzha:function(req,callback,User,Role){
weiqingting authored
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
					var firstName=req.param("firstName"),lastName=req.param("lastName")...;
					//如果需求简单的话
					User.register({firstName:firstName,lastName:lastName,...}).done(function(res){
						//callback接收两个参数,第一个为错误,第二个为成功的结果
						return callback(null,res)
					},function(err){
						return callback(err,null);
					})
					//如果需求复杂的话,比如在注册的使用,需要验证用户名称和邀请码
					//用户名验证和邀请码可以同时请求,类似promise.all一样
					User.checkUserName({xxx:xxx}).checkYaoQingMa({xxx:xxx}).done(function(res1,res2){
						//todo
						User.register({xxxx}).done(function(res){
							//当然业务还可以在复杂一点,你需要调角色模块的,一个方法
							Role.xxxxx().done(...)
							return callback(null,res);
						})
					},..)
				},
				userInfo:{
					title:'用户信息',
					url:'user/userInfo',
					param:{
						userid:{type:Numebr}
					}
				}
weiqingting authored
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
				...
			}
		}
###### apis 接口属性介绍
<table>
    <tr>
        <td>属性</td><td>类型</td><td>说明</td>
	</tr>
	<tr>
		<td>title</td><td>String</td><td>主要用于代替注释,而且在日志中会备用,最好必选</td>
	</tr>
	<tr>
		<td>url</td><td>String</td><td>接口请求地址,必选</td>
    </tr>
	<tr>
		<td>domain</td><td>接口请求的域</td><td>可选,这个值一般在node启动的js中进行全局配置</td>
    </tr>
	<tr>
		<td>methord</td><td>请求方式,默认post</td><td>请求方式</td>
	</tr>
weiqingting authored
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
	<tr>
		<td>params</td><td>参数</td><td>参考下面</td>
	</tr>
</table>
###### params 属性介绍
<table>
	<tr>
        <td>属性</td><td>类型</td><td>说明</td>
	</tr>
<tr>
        <td>type</td><td>类型</td><td>数据类型,会帮你转换,比如你前台传了“1”,type设置为Number,那接口接收就是1</td>
	</tr>
<tr>
        <td>require</td><td>默认fasle</td><td>表示字段必选</td>
	</tr>
<tr>
        <td>default</td><td>在没有传递的情况下,字段默认值</td><td>可以为字符串</td>
	</tr>
<tr>
        <td>coerce</td><td>function 类型</td><td>用于处理接收值,在Function内部使用this,可以获取其他字段值</td>
	</tr>
weiqingting authored
111 112
</table>
## Controler
weiqingting authored
113 114
### 正常情况下打开一个页面
	module.exports={
weiqingting authored
115 116
		// "common.login" 为虚拟路径,注意以点隔开
		//"User_userInfo" 接口规则命名空间+“_”+"接口名",名字这么起,也是无奈的选择
weiqingting authored
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
		app.get("/login","common.login");
		//打开一个页面,并且调一个接口,进行页面渲染,function 这个参数可以省略
		app.get("/index/:userid","common.index","User_userInfo",function(user,req,res){
			//user 为 User_userInfo 的接口返回的结果
			//req 为就是express 的req,res 同理
			//比如在某种情况下,你需要调用res里面的方法,比如json ,end等等,应该这么写res.myJson(..);
			//规律 res.my+首字母大写+后面的部分。如果你直接用res.json 原声的,他可能会爆一个错,不过这个错不会影响结果,建议不用
		});
		//当然我们也猥琐了一下,如果这么使用,页面就使用vue模式进行加载渲染,这是黑科技
		app.vue("/login","common.login")
		
		//直接返回结果
		app.post("/login","User_login");
		
		//如果需要对接口结果进行处理,加Function
		//比如
		app.post("/login","User_login",function(data,req,res){
			return data.message
		})
		
		//当然你请求可能需要调用两个接口
		app.post("/xxxxx",["User_A","User_B"]);这么写会直接返回{User_A:XXX,User_B:XXXX}
		//当然你请求接口,可能需要小小的修改,相信你已经想到了,加一个function
		app.post("/xxxx",["User_A","User_B"],function(a,b,req,res){
			a.child=b;
			return a;
		});
		
		//也许你请求一个接口可能比较复杂,可能有相互的依赖关系
		app.post("/reqgist","User_fuzha")
	}
weiqingting authored
148
## View
weiqingting authored
149
模板使用arttemplate,不过方式使用的<%%>,没有使用推荐的{{}},这么做是打算干另外一件事,只是没机会干了。
weiqingting authored
150 151

## 后记
weiqingting authored
152
#### 以上介绍就是随便说说,有很多也没说,说的也没讲到位,我个人觉得框架本身就是一个思想支撑的。所以并不一定会完美的应用于任何一个场景,意思希望大家能够理解,配置本身就是不灵活,这个框架就在灵活和配置找一个点来贯彻项目。因为项目中没有require,所以我们可以为所欲为的“服务端打包”,运行npm run build,server文件夹就是服务端打包的结果,看起来是不是工整许多呢。