初次接触前后端分离项目,记录下。
vue-element-admin该项目的定位是后台集成方案,不太适合当基础模板来二次开发。因为该项目继承了很多你可能用不到的功能,会造成不少的代码冗余。如果你的项目不关注这方面的问题,也可以直接基于它进行二次开发。
我不关注代码冗余,只关注实现功能,所以直接基于它进行二次开发。
前端框架介绍: vue-element-admin.
github源码:vue-element-admin.
路由和侧边栏是组织起一个后台应用的关键骨架,建议直接参考官方文档更改,官方文档
vue-element-admin路由和侧边栏.
轮到我们自己新建页面了,我们在/src文件夹下新建一个module文件夹,用来放我们自己编写的vue组件,注意要跟路由里的配置匹配,我们用element-ui来写一个简单的页面,大家可以随意添加,这里不再过多介绍, vue官方文档.
当我们写了不同层次的页面,访问最后一层需要一层一层的点进去,这对用户不太友好。
我们需要做一个树形控件来实现导航的作用,当然你也可以使用侧边栏,不过如果层级或者数据量过多的话,侧边栏也会不太合适。对我的这个项目而言,树形控件应该是最佳方案了。我用的是element-ui的树形控件,我们需要这样结构的数据来填充树形结构。
比如我们有四层页面,
1.a
2.a\b
3.a\b\c
4.a\b\c\d
而树形控件的data结构是
data: [{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
}]
}
],
我们可以在data中增加一个id字段来对应相对的页面,改为
data: [{
label: '一级 1',
id: 1,
children: [{
label: '二级 1-1',
id: 2,
children: [{
label: '三级 1-1-1',
id: 3,
}]
}]
}
],
然后我们还需要一个a、b、c、d页面和id的对应关系,
我们可以这样定义一个map结构,treeId[a️c:d] = id,将id和页面对应起来
如果点击a层页面,key值就为a::: 如果点击b层页面,key值就为a:b:: 如果点击c层页面,key值就为a:b:c: 如果点击d层页面,key值就为a:b:c:d,
我们根据a,b,c,d的值跳转到不同的页面及不同的数据请求
a、b、c、d的值需要定义为每一层中唯一的数据,以防跳转错误。
vuex主要作用在两个地方,
1.多个页面可以共享同一份数据,跳转页面后不重新请求数据
2.可以监听共享的数据,实现自动更新
#1.共享数据
import store from '../../store'
#获取数据
this.data = this.$store.state.forensic.case_info
#存数据到vuex
this.$store.commit('forensic/getTreeCaseInfo',data)
#vuex
const state = {
case_info: ''
}
const mutations = {
getTreeCaseInfo: (state, data) => {
state.case_info = data
console.log('vuex get case info')
}
}
#2.自动更新(方法一)
import { mapGetters } from 'vuex'
computed: {
...mapGetters({ caseInfo:'caseInfo'),
},
const getters = {
caseInfo:state => {
console.log('taskList Getter refresh')
for (let index in state.forensic.case_info) {
if (state.forensic.case_info[index].case_id == state.forensic.case_id) {
console.log(state.forensic.case_info[index]);
return state.forensic.case_info[index];
}
}
}
}
#2.自动更新(方法二)
import store from '../../store'
watch: {
taskData() {
console.log('casedisplay watch run')
this.init()
}
},
computed: {
taskData() {
console.log('casedisplay computed run')
return this.$store.state.forensic.case_info
},
},
socket传送门, flask_socketio向前端页面发送socket包,vue前端使用vuex接收socket包.
使用蓝图将各个部分模块化
#app.py
app.register_blueprint(forensicDispaly.bp)
#forensicDispaly.py
from flask import Blueprint
bp = Blueprint('forensic', __name__,url_prefix='/forensic')
@bp.route('/case1',methods=['POST'])
def forensic_case():
data = json.loads(request.get_data())
user_id = data['user_id']
result = forensicDispalyModel.queryTreeData(user_id)
return jsonify(result)
#app.py
from flask import Flask, render_template,jsonify,g
app.config["MONGO_URI"] = "mongodb://127.0.0.1:27017/forensicsDb"
mongo = PyMongo(app)
MongoModel.mongo = mongo
#forensicDispalyModel.py
from flask import g
class ForensicDispalyModel:
def __int__(self):
pass
def getMongo(self):
return MongoModel.mongo
def queryTreeData(self,user_id):
print('user_id:', user_id, ' , start query tree data')
result = list(self.getMongo().db.case_task_collection.find(
{
"user_id": user_id,
"enable":
{
"$ne": "false"
},
},
{
"_id": 0
}).sort(
[("create_ts", pymongo.DESCENDING)]))
mongodb传送门, mongodb数据库进行多表联合查询 lookup.
rabbit传送门, python装饰器应用在接收rabbit包后注册回调.
socket传送门, flask_socketio向前端页面发送socket包,vue前端使用vuex接收socket包.
文笔欠佳,多见谅。有疑问可以联系我,大家一起讨论